Timber - Version 1.21.0

Version Description

  • Updated minimum required PHP version to 7.2 to make the included Twig version support PHP 8.0 and 8.1, by @gchtr in #2640.
  • Updated minimum Twig version to 1.44.0 to support PHP 8.0 and 8.1, by @gchtr in #2640.
  • Fixed support for PHP 8.0 and PHP 8.1, by @nlemoine and @gchtr in #2638, #2640.
Download this release

Release Info

Developer jarednova
Plugin Icon 128x128 Timber
Version 1.21.0
Comparing to
See all releases

Code changes from version 1.20.0 to 1.21.0

Files changed (466) hide show
  1. lib/Image.php +2 -2
  2. lib/Image/Operation/Letterbox.php +4 -4
  3. lib/Image/Operation/Resize.php +13 -7
  4. lib/Image/Operation/Retina.php +2 -2
  5. lib/Loader.php +3 -2
  6. lib/PostsIterator.php +3 -2
  7. lib/QueryIterator.php +6 -2
  8. readme.txt +8 -2
  9. timber.php +2 -1
  10. vendor/autoload.php +1 -1
  11. vendor/composer/InstalledVersions.php +26 -22
  12. vendor/composer/autoload_classmap.php +10 -35
  13. vendor/composer/autoload_files.php +2 -0
  14. vendor/composer/autoload_psr4.php +2 -0
  15. vendor/composer/autoload_real.php +7 -7
  16. vendor/composer/autoload_static.php +28 -41
  17. vendor/composer/installed.json +215 -41
  18. vendor/composer/installed.php +26 -22
  19. vendor/composer/installers/.github/workflows/continuous-integration.yml +2 -16
  20. vendor/composer/installers/.github/workflows/lint.yml +2 -2
  21. vendor/composer/installers/.github/workflows/phpstan.yml +2 -4
  22. vendor/composer/installers/composer.json +8 -14
  23. vendor/composer/installers/phpstan.neon.dist +3 -1
  24. vendor/composer/installers/src/Composer/Installers/AglInstaller.php +10 -2
  25. vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php +0 -9
  26. vendor/composer/installers/src/Composer/Installers/AkauntingInstaller.php +23 -0
  27. vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php +2 -0
  28. vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php +15 -6
  29. vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php +2 -0
  30. vendor/composer/installers/src/Composer/Installers/BaseInstaller.php +28 -28
  31. vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php +10 -13
  32. vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php +2 -0
  33. vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php +9 -8
  34. vendor/composer/installers/src/Composer/Installers/ChefInstaller.php +2 -1
  35. vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php +2 -0
  36. vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php +7 -5
  37. vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php +9 -5
  38. vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php +2 -0
  39. vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php +2 -0
  40. vendor/composer/installers/src/Composer/Installers/CraftInstaller.php +0 -35
  41. vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php +3 -1
  42. vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php +2 -0
  43. vendor/composer/installers/src/Composer/Installers/DframeInstaller.php +1 -0
  44. vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php +19 -12
  45. vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php +2 -0
  46. vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php +2 -0
  47. vendor/composer/installers/src/Composer/Installers/ElggInstaller.php +2 -0
  48. vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php +2 -0
  49. vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php +10 -8
  50. vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php +2 -0
  51. vendor/composer/installers/src/Composer/Installers/FuelInstaller.php +2 -0
  52. vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php +2 -0
  53. vendor/composer/installers/src/Composer/Installers/GravInstaller.php +5 -6
  54. vendor/composer/installers/src/Composer/Installers/HuradInstaller.php +4 -2
  55. vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php +2 -0
  56. vendor/composer/installers/src/Composer/Installers/Installer.php +33 -51
  57. vendor/composer/installers/src/Composer/Installers/ItopInstaller.php +2 -0
  58. vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php +0 -15
  59. vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php +2 -0
  60. vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php +0 -11
  61. vendor/composer/installers/src/Composer/Installers/KnownInstaller.php +2 -0
  62. vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php +3 -1
  63. vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php +2 -0
  64. vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php +3 -3
  65. vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php +2 -0
  66. vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php +2 -0
  67. vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php +2 -0
  68. vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php +2 -0
  69. vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php +2 -0
  70. vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php +2 -0
  71. vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php +15 -6
  72. vendor/composer/installers/src/Composer/Installers/MakoInstaller.php +2 -0
  73. vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php +4 -2
  74. vendor/composer/installers/src/Composer/Installers/{PimcoreInstaller.php → MatomoInstaller.php} +10 -3
  75. vendor/composer/installers/src/Composer/Installers/MauticInstaller.php +5 -10
  76. vendor/composer/installers/src/Composer/Installers/MayaInstaller.php +9 -4
  77. vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php +15 -8
  78. vendor/composer/installers/src/Composer/Installers/MiaoxingInstaller.php +1 -0
  79. vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php +56 -30
  80. vendor/composer/installers/src/Composer/Installers/ModxInstaller.php +2 -0
  81. vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php +8 -0
  82. vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php +17 -8
  83. vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php +6 -4
  84. vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php +3 -3
  85. vendor/composer/installers/src/Composer/Installers/OxidInstaller.php +34 -44
  86. vendor/composer/installers/src/Composer/Installers/PPIInstaller.php +2 -0
  87. vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php +2 -0
  88. vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php +2 -0
  89. vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php +4 -8
  90. vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php +8 -9
  91. vendor/composer/installers/src/Composer/Installers/Plugin.php +4 -3
  92. vendor/composer/installers/src/Composer/Installers/PortoInstaller.php +2 -0
  93. vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php +2 -0
  94. vendor/composer/installers/src/Composer/Installers/ProcessWireInstaller.php +3 -2
  95. vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php +1 -0
  96. vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php +11 -12
  97. vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php +4 -2
  98. vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php +2 -0
  99. vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php +2 -0
  100. vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php +2 -0
  101. vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php +3 -4
  102. vendor/composer/installers/src/Composer/Installers/SMFInstaller.php +2 -0
  103. vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php +16 -10
  104. vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php +3 -5
  105. vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php +11 -2
  106. vendor/composer/installers/src/Composer/Installers/StarbugInstaller.php +2 -0
  107. vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php +15 -7
  108. vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php +2 -0
  109. vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php +0 -26
  110. vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php +0 -16
  111. vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php +0 -38
  112. vendor/composer/installers/src/Composer/Installers/TaoInstaller.php +3 -1
  113. vendor/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php +60 -7
  114. vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php +2 -0
  115. vendor/composer/installers/src/Composer/Installers/TuskInstaller.php +16 -13
  116. vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php +2 -0
  117. vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php +2 -0
  118. vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php +15 -5
  119. vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php +1 -0
  120. vendor/composer/installers/src/Composer/Installers/WinterInstaller.php +22 -9
  121. vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php +2 -0
  122. vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php +2 -0
  123. vendor/composer/installers/src/Composer/Installers/YawikInstaller.php +4 -13
  124. vendor/composer/installers/src/Composer/Installers/ZendInstaller.php +2 -0
  125. vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php +2 -0
  126. vendor/composer/installers/src/bootstrap.php +6 -1
  127. vendor/composer/platform_check.php +2 -2
  128. vendor/symfony/polyfill-ctype/Ctype.php +29 -24
  129. vendor/symfony/polyfill-ctype/README.md +1 -1
  130. vendor/symfony/polyfill-ctype/bootstrap.php +15 -11
  131. vendor/symfony/polyfill-ctype/bootstrap80.php +46 -0
  132. vendor/symfony/polyfill-ctype/composer.json +5 -2
  133. vendor/symfony/polyfill-mbstring/LICENSE +19 -0
  134. vendor/symfony/polyfill-mbstring/Mbstring.php +873 -0
  135. vendor/symfony/polyfill-mbstring/README.md +13 -0
  136. vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php +1397 -0
  137. vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php +5 -0
  138. vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php +1489 -0
  139. vendor/symfony/polyfill-mbstring/bootstrap.php +147 -0
  140. vendor/symfony/polyfill-mbstring/bootstrap80.php +143 -0
  141. vendor/symfony/polyfill-mbstring/composer.json +41 -0
  142. vendor/symfony/polyfill-php72/LICENSE +19 -0
  143. vendor/symfony/polyfill-php72/Php72.php +217 -0
  144. vendor/symfony/polyfill-php72/README.md +35 -0
  145. vendor/symfony/polyfill-php72/bootstrap.php +57 -0
  146. vendor/symfony/polyfill-php72/composer.json +35 -0
  147. vendor/twig/twig/.gitattributes +3 -1
  148. vendor/twig/twig/.github/workflows/ci.yml +146 -0
  149. vendor/twig/twig/.github/workflows/documentation.yml +64 -0
  150. vendor/twig/twig/.gitignore +2 -2
  151. vendor/twig/twig/{.php_cs.dist → .php-cs-fixer.dist.php} +2 -2
  152. vendor/twig/twig/.travis.yml +0 -46
  153. vendor/twig/twig/CHANGELOG +246 -979
  154. vendor/twig/twig/LICENSE +20 -22
  155. vendor/twig/twig/README.rst +1 -2
  156. vendor/twig/twig/composer.json +8 -5
  157. vendor/twig/twig/doc/advanced.rst +0 -957
  158. vendor/twig/twig/doc/advanced_legacy.rst +0 -877
  159. vendor/twig/twig/doc/api.rst +0 -593
  160. vendor/twig/twig/doc/coding_standards.rst +0 -101
  161. vendor/twig/twig/doc/deprecated.rst +0 -224
  162. vendor/twig/twig/doc/filters/abs.rst +0 -18
  163. vendor/twig/twig/doc/filters/batch.rst +0 -52
  164. vendor/twig/twig/doc/filters/capitalize.rst +0 -11
  165. vendor/twig/twig/doc/filters/convert_encoding.rst +0 -28
  166. vendor/twig/twig/doc/filters/date.rst +0 -100
  167. vendor/twig/twig/doc/filters/date_modify.rst +0 -23
  168. vendor/twig/twig/doc/filters/default.rst +0 -33
  169. vendor/twig/twig/doc/filters/escape.rst +0 -129
  170. vendor/twig/twig/doc/filters/filter.rst +0 -58
  171. vendor/twig/twig/doc/filters/first.rst +0 -25
  172. vendor/twig/twig/doc/filters/format.rst +0 -16
  173. vendor/twig/twig/doc/filters/index.rst +0 -41
  174. vendor/twig/twig/doc/filters/join.rst +0 -35
  175. vendor/twig/twig/doc/filters/json_encode.rst +0 -23
  176. vendor/twig/twig/doc/filters/keys.rst +0 -11
  177. vendor/twig/twig/doc/filters/last.rst +0 -25
  178. vendor/twig/twig/doc/filters/length.rst +0 -23
  179. vendor/twig/twig/doc/filters/lower.rst +0 -10
  180. vendor/twig/twig/doc/filters/map.rst +0 -37
  181. vendor/twig/twig/doc/filters/merge.rst +0 -48
  182. vendor/twig/twig/doc/filters/nl2br.rst +0 -22
  183. vendor/twig/twig/doc/filters/number_format.rst +0 -56
  184. vendor/twig/twig/doc/filters/raw.rst +0 -38
  185. vendor/twig/twig/doc/filters/reduce.rst +0 -32
  186. vendor/twig/twig/doc/filters/replace.rst +0 -25
  187. vendor/twig/twig/doc/filters/reverse.rst +0 -47
  188. vendor/twig/twig/doc/filters/round.rst +0 -37
  189. vendor/twig/twig/doc/filters/slice.rst +0 -71
  190. vendor/twig/twig/doc/filters/sort.rst +0 -18
  191. vendor/twig/twig/doc/filters/spaceless.rst +0 -65
  192. vendor/twig/twig/doc/filters/split.rst +0 -53
  193. vendor/twig/twig/doc/filters/striptags.rst +0 -29
  194. vendor/twig/twig/doc/filters/title.rst +0 -11
  195. vendor/twig/twig/doc/filters/trim.rst +0 -45
  196. vendor/twig/twig/doc/filters/upper.rst +0 -10
  197. vendor/twig/twig/doc/filters/url_encode.rst +0 -34
  198. vendor/twig/twig/doc/functions/attribute.rst +0 -26
  199. vendor/twig/twig/doc/functions/block.rst +0 -41
  200. vendor/twig/twig/doc/functions/constant.rst +0 -29
  201. vendor/twig/twig/doc/functions/cycle.rst +0 -28
  202. vendor/twig/twig/doc/functions/date.rst +0 -55
  203. vendor/twig/twig/doc/functions/dump.rst +0 -69
  204. vendor/twig/twig/doc/functions/include.rst +0 -84
  205. vendor/twig/twig/doc/functions/index.rst +0 -20
  206. vendor/twig/twig/doc/functions/max.rst +0 -20
  207. vendor/twig/twig/doc/functions/min.rst +0 -20
  208. vendor/twig/twig/doc/functions/parent.rst +0 -20
  209. vendor/twig/twig/doc/functions/random.rst +0 -36
  210. vendor/twig/twig/doc/functions/range.rst +0 -58
  211. vendor/twig/twig/doc/functions/source.rst +0 -32
  212. vendor/twig/twig/doc/functions/template_from_string.rst +0 -43
  213. vendor/twig/twig/doc/index.rst +0 -19
  214. vendor/twig/twig/doc/installation.rst +0 -73
  215. vendor/twig/twig/doc/internals.rst +0 -144
  216. vendor/twig/twig/doc/intro.rst +0 -76
  217. vendor/twig/twig/doc/recipes.rst +0 -568
  218. vendor/twig/twig/doc/tags/apply.rst +0 -23
  219. vendor/twig/twig/doc/tags/autoescape.rst +0 -81
  220. vendor/twig/twig/doc/tags/block.rst +0 -11
  221. vendor/twig/twig/doc/tags/deprecated.rst +0 -30
  222. vendor/twig/twig/doc/tags/do.rst +0 -12
  223. vendor/twig/twig/doc/tags/embed.rst +0 -178
  224. vendor/twig/twig/doc/tags/extends.rst +0 -270
  225. vendor/twig/twig/doc/tags/filter.rst +0 -26
  226. vendor/twig/twig/doc/tags/flush.rst +0 -17
  227. vendor/twig/twig/doc/tags/for.rst +0 -179
  228. vendor/twig/twig/doc/tags/from.rst +0 -6
  229. vendor/twig/twig/doc/tags/if.rst +0 -79
  230. vendor/twig/twig/doc/tags/import.rst +0 -6
  231. vendor/twig/twig/doc/tags/include.rst +0 -114
  232. vendor/twig/twig/doc/tags/index.rst +0 -27
  233. vendor/twig/twig/doc/tags/macro.rst +0 -139
  234. vendor/twig/twig/doc/tags/sandbox.rst +0 -30
  235. vendor/twig/twig/doc/tags/set.rst +0 -78
  236. vendor/twig/twig/doc/tags/spaceless.rst +0 -41
  237. vendor/twig/twig/doc/tags/use.rst +0 -124
  238. vendor/twig/twig/doc/tags/verbatim.rst +0 -24
  239. vendor/twig/twig/doc/tags/with.rst +0 -44
  240. vendor/twig/twig/doc/templates.rst +0 -884
  241. vendor/twig/twig/doc/tests/constant.rst +0 -22
  242. vendor/twig/twig/doc/tests/defined.rst +0 -30
  243. vendor/twig/twig/doc/tests/divisibleby.rst +0 -14
  244. vendor/twig/twig/doc/tests/empty.rst +0 -22
  245. vendor/twig/twig/doc/tests/even.rst +0 -10
  246. vendor/twig/twig/doc/tests/index.rst +0 -15
  247. vendor/twig/twig/doc/tests/iterable.rst +0 -19
  248. vendor/twig/twig/doc/tests/null.rst +0 -12
  249. vendor/twig/twig/doc/tests/odd.rst +0 -10
  250. vendor/twig/twig/doc/tests/sameas.rst +0 -14
  251. vendor/twig/twig/drupal_test.sh +0 -50
  252. vendor/twig/twig/ext/twig/.gitignore +0 -30
  253. vendor/twig/twig/ext/twig/config.m4 +0 -8
  254. vendor/twig/twig/ext/twig/config.w32 +0 -8
  255. vendor/twig/twig/ext/twig/php_twig.h +0 -35
  256. vendor/twig/twig/ext/twig/twig.c +0 -1217
  257. vendor/twig/twig/lib/Twig/Autoloader.php +0 -52
  258. vendor/twig/twig/lib/Twig/BaseNodeVisitor.php +4 -1
  259. vendor/twig/twig/lib/Twig/Cache/Filesystem.php +4 -1
  260. vendor/twig/twig/lib/Twig/Cache/Null.php +4 -1
  261. vendor/twig/twig/lib/Twig/CacheInterface.php +4 -1
  262. vendor/twig/twig/lib/Twig/Compiler.php +4 -1
  263. vendor/twig/twig/lib/Twig/CompilerInterface.php +0 -34
  264. vendor/twig/twig/lib/Twig/ContainerRuntimeLoader.php +4 -1
  265. vendor/twig/twig/lib/Twig/Environment.php +4 -1
  266. vendor/twig/twig/lib/Twig/Error.php +4 -1
  267. vendor/twig/twig/lib/Twig/Error/Loader.php +4 -1
  268. vendor/twig/twig/lib/Twig/Error/Runtime.php +4 -1
  269. vendor/twig/twig/lib/Twig/Error/Syntax.php +4 -1
  270. vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php +4 -1
  271. vendor/twig/twig/lib/Twig/ExpressionParser.php +4 -1
  272. vendor/twig/twig/lib/Twig/Extension.php +4 -1
  273. vendor/twig/twig/lib/Twig/Extension/Core.php +4 -1
  274. vendor/twig/twig/lib/Twig/Extension/Debug.php +4 -1
  275. vendor/twig/twig/lib/Twig/Extension/Escaper.php +4 -1
  276. vendor/twig/twig/lib/Twig/Extension/GlobalsInterface.php +4 -1
  277. vendor/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php +4 -1
  278. vendor/twig/twig/lib/Twig/Extension/Optimizer.php +4 -1
  279. vendor/twig/twig/lib/Twig/Extension/Profiler.php +4 -1
  280. vendor/twig/twig/lib/Twig/Extension/Sandbox.php +4 -1
  281. vendor/twig/twig/lib/Twig/Extension/Staging.php +4 -1
  282. vendor/twig/twig/lib/Twig/Extension/StringLoader.php +4 -1
  283. vendor/twig/twig/lib/Twig/ExtensionInterface.php +4 -1
  284. vendor/twig/twig/lib/Twig/ExtensionSet.php +14 -0
  285. vendor/twig/twig/lib/Twig/FactoryRuntimeLoader.php +4 -1
  286. vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php +4 -1
  287. vendor/twig/twig/lib/Twig/Filter.php +6 -78
  288. vendor/twig/twig/lib/Twig/Filter/Function.php +0 -40
  289. vendor/twig/twig/lib/Twig/Filter/Method.php +0 -44
  290. vendor/twig/twig/lib/Twig/Filter/Node.php +0 -42
  291. vendor/twig/twig/lib/Twig/FilterCallableInterface.php +0 -24
  292. vendor/twig/twig/lib/Twig/FilterInterface.php +0 -45
  293. vendor/twig/twig/lib/Twig/Function.php +6 -68
  294. vendor/twig/twig/lib/Twig/Function/Function.php +0 -41
  295. vendor/twig/twig/lib/Twig/Function/Method.php +0 -45
  296. vendor/twig/twig/lib/Twig/Function/Node.php +0 -42
  297. vendor/twig/twig/lib/Twig/FunctionCallableInterface.php +0 -24
  298. vendor/twig/twig/lib/Twig/FunctionInterface.php +0 -42
  299. vendor/twig/twig/lib/Twig/Lexer.php +4 -1
  300. vendor/twig/twig/lib/Twig/LexerInterface.php +0 -36
  301. vendor/twig/twig/lib/Twig/Loader/Array.php +4 -1
  302. vendor/twig/twig/lib/Twig/Loader/Chain.php +4 -1
  303. vendor/twig/twig/lib/Twig/Loader/Filesystem.php +4 -1
  304. vendor/twig/twig/lib/Twig/Loader/String.php +0 -63
  305. vendor/twig/twig/lib/Twig/LoaderInterface.php +4 -1
  306. vendor/twig/twig/lib/Twig/Markup.php +4 -1
  307. vendor/twig/twig/lib/Twig/Node.php +4 -1
  308. vendor/twig/twig/lib/Twig/Node/AutoEscape.php +4 -1
  309. vendor/twig/twig/lib/Twig/Node/Block.php +4 -1
  310. vendor/twig/twig/lib/Twig/Node/BlockReference.php +4 -1
  311. vendor/twig/twig/lib/Twig/Node/Body.php +4 -1
  312. vendor/twig/twig/lib/Twig/Node/CheckSecurity.php +4 -1
  313. vendor/twig/twig/lib/Twig/Node/Deprecated.php +4 -1
  314. vendor/twig/twig/lib/Twig/Node/Do.php +4 -1
  315. vendor/twig/twig/lib/Twig/Node/Embed.php +4 -1
  316. vendor/twig/twig/lib/Twig/Node/Expression.php +4 -1
  317. vendor/twig/twig/lib/Twig/Node/Expression/Array.php +4 -1
  318. vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php +4 -1
  319. vendor/twig/twig/lib/Twig/Node/Expression/Binary.php +4 -1
  320. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php +4 -1
  321. vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php +4 -1
  322. vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php +4 -1
  323. vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php +4 -1
  324. vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php +4 -1
  325. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php +4 -1
  326. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php +4 -1
  327. vendor/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php +4 -1
  328. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php +4 -1
  329. vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php +4 -1
  330. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php +4 -1
  331. vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php +4 -1
  332. vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php +4 -1
  333. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php +4 -1
  334. vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php +4 -1
  335. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php +4 -1
  336. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php +4 -1
  337. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php +4 -1
  338. vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php +4 -1
  339. vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php +4 -1
  340. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php +4 -1
  341. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php +4 -1
  342. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php +4 -1
  343. vendor/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php +4 -1
  344. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php +4 -1
  345. vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php +4 -1
  346. vendor/twig/twig/lib/Twig/Node/Expression/Call.php +4 -1
  347. vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php +4 -1
  348. vendor/twig/twig/lib/Twig/Node/Expression/Constant.php +4 -1
  349. vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php +0 -35
  350. vendor/twig/twig/lib/Twig/Node/Expression/Filter.php +4 -1
  351. vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php +4 -1
  352. vendor/twig/twig/lib/Twig/Node/Expression/Function.php +4 -1
  353. vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php +4 -1
  354. vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php +4 -1
  355. vendor/twig/twig/lib/Twig/Node/Expression/Name.php +4 -1
  356. vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php +4 -1
  357. vendor/twig/twig/lib/Twig/Node/Expression/Parent.php +4 -1
  358. vendor/twig/twig/lib/Twig/Node/Expression/TempName.php +4 -1
  359. vendor/twig/twig/lib/Twig/Node/Expression/Test.php +4 -1
  360. vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php +4 -1
  361. vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php +4 -1
  362. vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php +4 -1
  363. vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php +4 -1
  364. vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php +4 -1
  365. vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php +4 -1
  366. vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php +4 -1
  367. vendor/twig/twig/lib/Twig/Node/Expression/Unary.php +4 -1
  368. vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php +4 -1
  369. vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php +4 -1
  370. vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php +4 -1
  371. vendor/twig/twig/lib/Twig/Node/Flush.php +4 -1
  372. vendor/twig/twig/lib/Twig/Node/For.php +4 -1
  373. vendor/twig/twig/lib/Twig/Node/ForLoop.php +4 -1
  374. vendor/twig/twig/lib/Twig/Node/If.php +4 -1
  375. vendor/twig/twig/lib/Twig/Node/Import.php +4 -1
  376. vendor/twig/twig/lib/Twig/Node/Include.php +4 -1
  377. vendor/twig/twig/lib/Twig/Node/Macro.php +4 -1
  378. vendor/twig/twig/lib/Twig/Node/Module.php +4 -1
  379. vendor/twig/twig/lib/Twig/Node/Print.php +4 -1
  380. vendor/twig/twig/lib/Twig/Node/Sandbox.php +4 -1
  381. vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php +4 -1
  382. vendor/twig/twig/lib/Twig/Node/Set.php +4 -1
  383. vendor/twig/twig/lib/Twig/Node/SetTemp.php +0 -11
  384. vendor/twig/twig/lib/Twig/Node/Spaceless.php +4 -1
  385. vendor/twig/twig/lib/Twig/Node/Text.php +4 -1
  386. vendor/twig/twig/lib/Twig/Node/With.php +4 -1
  387. vendor/twig/twig/lib/Twig/NodeCaptureInterface.php +4 -1
  388. vendor/twig/twig/lib/Twig/NodeInterface.php +0 -34
  389. vendor/twig/twig/lib/Twig/NodeOutputInterface.php +4 -1
  390. vendor/twig/twig/lib/Twig/NodeTraverser.php +4 -1
  391. vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php +4 -1
  392. vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php +4 -1
  393. vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php +4 -1
  394. vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php +4 -1
  395. vendor/twig/twig/lib/Twig/NodeVisitorInterface.php +4 -1
  396. vendor/twig/twig/lib/Twig/Parser.php +4 -1
  397. vendor/twig/twig/lib/Twig/ParserInterface.php +0 -33
  398. vendor/twig/twig/lib/Twig/Profiler/Dumper/Base.php +4 -1
  399. vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php +4 -1
  400. vendor/twig/twig/lib/Twig/Profiler/Dumper/Html.php +4 -1
  401. vendor/twig/twig/lib/Twig/Profiler/Dumper/Text.php +4 -1
  402. vendor/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php +4 -1
  403. vendor/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php +4 -1
  404. vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php +4 -1
  405. vendor/twig/twig/lib/Twig/Profiler/Profile.php +4 -1
  406. vendor/twig/twig/lib/Twig/RuntimeLoaderInterface.php +4 -1
  407. vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php +4 -1
  408. vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php +4 -1
  409. vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php +4 -1
  410. vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php +4 -1
  411. vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php +4 -1
  412. vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php +4 -1
  413. vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php +4 -1
  414. vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php +4 -1
  415. vendor/twig/twig/lib/Twig/SimpleFilter.php +18 -3
  416. vendor/twig/twig/lib/Twig/SimpleFunction.php +18 -3
  417. vendor/twig/twig/lib/Twig/SimpleTest.php +18 -3
  418. vendor/twig/twig/lib/Twig/Source.php +4 -1
  419. vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php +4 -1
  420. vendor/twig/twig/lib/Twig/Template.php +4 -1
  421. vendor/twig/twig/lib/Twig/TemplateInterface.php +0 -50
  422. vendor/twig/twig/lib/Twig/TemplateWrapper.php +4 -1
  423. vendor/twig/twig/lib/Twig/Test.php +6 -29
  424. vendor/twig/twig/lib/Twig/Test/Function.php +0 -38
  425. vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php +4 -1
  426. vendor/twig/twig/lib/Twig/Test/Method.php +0 -42
  427. vendor/twig/twig/lib/Twig/Test/Node.php +0 -40
  428. vendor/twig/twig/lib/Twig/Test/NodeTestCase.php +4 -1
  429. vendor/twig/twig/lib/Twig/TestCallableInterface.php +0 -22
  430. vendor/twig/twig/lib/Twig/TestInterface.php +0 -27
  431. vendor/twig/twig/lib/Twig/Token.php +4 -1
  432. vendor/twig/twig/lib/Twig/TokenParser.php +4 -1
  433. vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php +4 -1
  434. vendor/twig/twig/lib/Twig/TokenParser/Block.php +4 -1
  435. vendor/twig/twig/lib/Twig/TokenParser/Deprecated.php +4 -1
  436. vendor/twig/twig/lib/Twig/TokenParser/Do.php +4 -1
  437. vendor/twig/twig/lib/Twig/TokenParser/Embed.php +4 -1
  438. vendor/twig/twig/lib/Twig/TokenParser/Extends.php +4 -1
  439. vendor/twig/twig/lib/Twig/TokenParser/Filter.php +4 -1
  440. vendor/twig/twig/lib/Twig/TokenParser/Flush.php +4 -1
  441. vendor/twig/twig/lib/Twig/TokenParser/For.php +4 -1
  442. vendor/twig/twig/lib/Twig/TokenParser/From.php +4 -1
  443. vendor/twig/twig/lib/Twig/TokenParser/If.php +4 -1
  444. vendor/twig/twig/lib/Twig/TokenParser/Import.php +4 -1
  445. vendor/twig/twig/lib/Twig/TokenParser/Include.php +4 -1
  446. vendor/twig/twig/lib/Twig/TokenParser/Macro.php +4 -1
  447. vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php +4 -1
  448. vendor/twig/twig/lib/Twig/TokenParser/Set.php +4 -1
  449. vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php +4 -1
  450. vendor/twig/twig/lib/Twig/TokenParser/Use.php +4 -1
  451. vendor/twig/twig/lib/Twig/TokenParser/With.php +4 -1
  452. vendor/twig/twig/lib/Twig/TokenParserBroker.php +0 -122
  453. vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php +0 -46
  454. vendor/twig/twig/lib/Twig/TokenParserInterface.php +4 -1
  455. vendor/twig/twig/lib/Twig/TokenStream.php +4 -1
  456. vendor/twig/twig/lib/Twig/Util/DeprecationCollector.php +4 -1
  457. vendor/twig/twig/lib/Twig/Util/TemplateDirIterator.php +4 -1
  458. vendor/twig/twig/src/Cache/FilesystemCache.php +3 -3
  459. vendor/twig/twig/src/Cache/NullCache.php +1 -3
  460. vendor/twig/twig/src/Compiler.php +20 -63
  461. vendor/twig/twig/src/Environment.php +137 -781
  462. vendor/twig/twig/src/Error/Error.php +25 -93
  463. vendor/twig/twig/src/Error/SyntaxError.php +6 -15
  464. vendor/twig/twig/src/ExpressionParser.php +131 -135
  465. vendor/twig/twig/src/Extension/AbstractExtension.php +0 -25
  466. vendor/twig/twig/src/Extension/CoreExtension.php +271 -512
lib/Image.php CHANGED
@@ -437,7 +437,7 @@ class Image extends Post implements CoreInterface {
437
  * ```
438
  */
439
  public function link() {
440
- if ( strlen($this->abs_url) ) {
441
  return $this->abs_url;
442
  }
443
  return get_permalink($this->ID);
@@ -483,7 +483,7 @@ class Image extends Post implements CoreInterface {
483
  * @return bool|string
484
  */
485
  public function src( $size = 'full' ) {
486
- if ( isset($this->abs_url) ) {
487
  return $this->_maybe_secure_url($this->abs_url);
488
  }
489
 
437
  * ```
438
  */
439
  public function link() {
440
+ if (!empty($this->abs_url)) {
441
  return $this->abs_url;
442
  }
443
  return get_permalink($this->ID);
483
  * @return bool|string
484
  */
485
  public function src( $size = 'full' ) {
486
+ if (!empty($this->abs_url)) {
487
  return $this->_maybe_secure_url($this->abs_url);
488
  }
489
 
lib/Image/Operation/Letterbox.php CHANGED
@@ -63,7 +63,7 @@ class Letterbox extends ImageOperation {
63
  if ( ImageHelper::is_svg($load_filename) ) {
64
  return false;
65
  }
66
-
67
  $w = $this->w;
68
  $h = $this->h;
69
 
@@ -92,14 +92,14 @@ class Letterbox extends ImageOperation {
92
  $y = 0;
93
  $x = $w / 2 - $owt / 2;
94
  $oht = $h;
95
- $image->crop(0, 0, $ow, $oh, $owt, $oht);
96
  } else {
97
  $w_scale = $w / $ow;
98
  $oht = $oh * $w_scale;
99
  $x = 0;
100
  $y = $h / 2 - $oht / 2;
101
  $owt = $w;
102
- $image->crop(0, 0, $ow, $oh, $owt, $oht);
103
  }
104
  $result = $image->save($save_filename);
105
  $func = 'imagecreatefromjpeg';
@@ -120,7 +120,7 @@ class Letterbox extends ImageOperation {
120
  $save_func = 'imagewebp';
121
  }
122
  $image = $func($save_filename);
123
- imagecopy($bg, $image, $x, $y, 0, 0, $owt, $oht);
124
  if ( $save_func === 'imagegif' ) {
125
  return $save_func($bg, $save_filename);
126
  }
63
  if ( ImageHelper::is_svg($load_filename) ) {
64
  return false;
65
  }
66
+
67
  $w = $this->w;
68
  $h = $this->h;
69
 
92
  $y = 0;
93
  $x = $w / 2 - $owt / 2;
94
  $oht = $h;
95
+ $image->crop(0, 0, round($ow), round($oh), round($owt), round($oht));
96
  } else {
97
  $w_scale = $w / $ow;
98
  $oht = $oh * $w_scale;
99
  $x = 0;
100
  $y = $h / 2 - $oht / 2;
101
  $owt = $w;
102
+ $image->crop(0, 0, round($ow), round($oh), round($owt), round($oht));
103
  }
104
  $result = $image->save($save_filename);
105
  $func = 'imagecreatefromjpeg';
120
  $save_func = 'imagewebp';
121
  }
122
  $image = $func($save_filename);
123
+ imagecopy($bg, $image, round($x), round($y), 0, 0, round($owt), round($oht));
124
  if ( $save_func === 'imagegif' ) {
125
  return $save_func($bg, $save_filename);
126
  }
lib/Image/Operation/Resize.php CHANGED
@@ -75,7 +75,12 @@ class Resize extends ImageOperation {
75
  $image = $image->coalesceImages();
76
  $crop = self::get_target_sizes($editor);
77
  foreach ( $image as $frame ) {
78
- $frame->cropImage($crop['src_w'], $crop['src_h'], $crop['x'], $crop['y']);
 
 
 
 
 
79
  $frame->thumbnailImage($w, $h);
80
  $frame->setImagePage($w, $h, 0, 0);
81
  }
@@ -188,12 +193,13 @@ class Resize extends ImageOperation {
188
  }
189
 
190
  $crop = self::get_target_sizes($image);
191
- $image->crop( $crop['x'],
192
- $crop['y'],
193
- $crop['src_w'],
194
- $crop['src_h'],
195
- $crop['target_w'],
196
- $crop['target_h']
 
197
  );
198
  $quality = apply_filters( 'wp_editor_set_quality', 82, 'image/jpeg');
199
  $image->set_quality($quality);
75
  $image = $image->coalesceImages();
76
  $crop = self::get_target_sizes($editor);
77
  foreach ( $image as $frame ) {
78
+ $frame->cropImage(
79
+ round($crop['src_w']),
80
+ round($crop['src_h']),
81
+ round($crop['x']),
82
+ round($crop['y'])
83
+ );
84
  $frame->thumbnailImage($w, $h);
85
  $frame->setImagePage($w, $h, 0, 0);
86
  }
193
  }
194
 
195
  $crop = self::get_target_sizes($image);
196
+ $image->crop(
197
+ round( $crop['x'] ),
198
+ round( $crop['y'] ),
199
+ round( $crop['src_w'] ),
200
+ round( $crop['src_h'] ),
201
+ round( $crop['target_w'] ),
202
+ round( $crop['target_h'] )
203
  );
204
  $quality = apply_filters( 'wp_editor_set_quality', 82, 'image/jpeg');
205
  $image->set_quality($quality);
lib/Image/Operation/Retina.php CHANGED
@@ -62,8 +62,8 @@ class Retina extends ImageOperation {
62
  $src_w = $current_size['width'];
63
  $src_h = $current_size['height'];
64
  // Get ratios
65
- $w = $src_w * $this->factor;
66
- $h = $src_h * $this->factor;
67
  $image->crop(0, 0, $src_w, $src_h, $w, $h);
68
  $result = $image->save($save_filename);
69
  if ( is_wp_error($result) ) {
62
  $src_w = $current_size['width'];
63
  $src_h = $current_size['height'];
64
  // Get ratios
65
+ $w = round( $src_w * $this->factor );
66
+ $h = round( $src_h * $this->factor );
67
  $image->crop(0, 0, $src_w, $src_h, $w, $h);
68
  $result = $image->save($save_filename);
69
  if ( is_wp_error($result) ) {
lib/Loader.php CHANGED
@@ -205,9 +205,10 @@ class Loader {
205
  }
206
  $cache_mode = $this->_get_cache_mode($cache_mode);
207
  if ( self::CACHE_TRANSIENT === $cache_mode || self::CACHE_SITE_TRANSIENT === $cache_mode ) {
208
- return self::clear_cache_timber_database();
 
209
  } else if ( self::CACHE_OBJECT === $cache_mode && $object_cache ) {
210
- return self::clear_cache_timber_object();
211
  }
212
  return false;
213
  }
205
  }
206
  $cache_mode = $this->_get_cache_mode($cache_mode);
207
  if ( self::CACHE_TRANSIENT === $cache_mode || self::CACHE_SITE_TRANSIENT === $cache_mode ) {
208
+ // $wpdb->query() might return 0 affected rows, but that means it’s still successful.
209
+ return false !== self::clear_cache_timber_database();
210
  } else if ( self::CACHE_OBJECT === $cache_mode && $object_cache ) {
211
+ return false !== self::clear_cache_timber_object();
212
  }
213
  return false;
214
  }
lib/PostsIterator.php CHANGED
@@ -8,11 +8,12 @@ namespace Timber;
8
  * @package Timber
9
  */
10
  class PostsIterator extends \ArrayIterator {
11
-
 
12
  public function current() {
13
  global $post;
14
  $post = parent::current();
15
  return $post;
16
  }
17
-
18
  }
8
  * @package Timber
9
  */
10
  class PostsIterator extends \ArrayIterator {
11
+
12
+ #[\ReturnTypeWillChange]
13
  public function current() {
14
  global $post;
15
  $post = parent::current();
16
  return $post;
17
  }
18
+
19
  }
lib/QueryIterator.php CHANGED
@@ -130,10 +130,11 @@ class QueryIterator implements \Iterator, \Countable {
130
  // Iterator Interface
131
  //
132
 
133
- public function valid() {
134
  return $this->_query->have_posts();
135
  }
136
 
 
137
  public function current() {
138
  global $post;
139
 
@@ -147,12 +148,15 @@ class QueryIterator implements \Iterator, \Countable {
147
  /**
148
  * Don't implement next, because current already advances the loop
149
  */
 
150
  final public function next() {}
151
 
 
152
  public function rewind() {
153
  $this->_query->rewind_posts();
154
  }
155
 
 
156
  public function key() {
157
  $this->_query->current_post;
158
  }
@@ -199,7 +203,7 @@ class QueryIterator implements \Iterator, \Countable {
199
  * @return int The custom count as an integer.
200
  * The return value is cast to an integer.
201
  */
202
- public function count() {
203
  return $this->post_count();
204
  }
205
  }
130
  // Iterator Interface
131
  //
132
 
133
+ public function valid(): bool {
134
  return $this->_query->have_posts();
135
  }
136
 
137
+ #[\ReturnTypeWillChange]
138
  public function current() {
139
  global $post;
140
 
148
  /**
149
  * Don't implement next, because current already advances the loop
150
  */
151
+ #[\ReturnTypeWillChange]
152
  final public function next() {}
153
 
154
+ #[\ReturnTypeWillChange]
155
  public function rewind() {
156
  $this->_query->rewind_posts();
157
  }
158
 
159
+ #[\ReturnTypeWillChange]
160
  public function key() {
161
  $this->_query->current_post;
162
  }
203
  * @return int The custom count as an integer.
204
  * The return value is cast to an integer.
205
  */
206
+ public function count(): int {
207
  return $this->post_count();
208
  }
209
  }
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: jarednova
3
  Tags: template engine, templates, twig
4
  Requires at least: 4.9.8
5
  Tested up to: 6.0.0
6
- Stable tag: 1.20.0
7
- Requires PHP: 5.6
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -38,6 +38,12 @@ _Twig is the template language powering Timber; if you need a little background
38
 
39
  **Fixes and improvements**
40
 
 
 
 
 
 
 
41
  = 1.20.0 =
42
 
43
  * Use newest version of Upstatement/routes for WordPress 6.0 by @jarednova in #2595
3
  Tags: template engine, templates, twig
4
  Requires at least: 4.9.8
5
  Tested up to: 6.0.0
6
+ Stable tag: 1.21.0
7
+ Requires PHP: 7.2.5
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
38
 
39
  **Fixes and improvements**
40
 
41
+ = 1.21.0 =
42
+
43
+ * Updated minimum required PHP version to 7.2 to make the included Twig version support PHP 8.0 and 8.1, by @gchtr in #2640.
44
+ * Updated minimum Twig version to 1.44.0 to support PHP 8.0 and 8.1, by @gchtr in #2640.
45
+ * Fixed support for PHP 8.0 and PHP 8.1, by @nlemoine and @gchtr in #2638, #2640.
46
+
47
  = 1.20.0 =
48
 
49
  * Use newest version of Upstatement/routes for WordPress 6.0 by @jarednova in #2595
timber.php CHANGED
@@ -4,8 +4,9 @@ Plugin Name: Timber
4
  Description: The WordPress Timber Library allows you to write themes using the power of Twig templates.
5
  Plugin URI: https://upstatement.com/timber
6
  Author: Jared Novack + Upstatement
7
- Version: 1.20.0
8
  Author URI: http://upstatement.com/
 
9
  */
10
  // we look for Composer files first in the plugins dir.
11
  // then in the wp-content dir (site install).
4
  Description: The WordPress Timber Library allows you to write themes using the power of Twig templates.
5
  Plugin URI: https://upstatement.com/timber
6
  Author: Jared Novack + Upstatement
7
+ Version: 1.21.0
8
  Author URI: http://upstatement.com/
9
+ Requires PHP: 7.2.5
10
  */
11
  // we look for Composer files first in the plugins dir.
12
  // then in the wp-content dir (site install).
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit1fb235bc74e35292d2b088681fade654::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit989702ef2dea046e4eae802005e7b013::getLoader();
vendor/composer/InstalledVersions.php CHANGED
@@ -25,12 +25,12 @@ class InstalledVersions
25
  private static $installed = array (
26
  'root' =>
27
  array (
28
- 'pretty_version' => '1.20.0.x-dev',
29
- 'version' => '1.20.0.9999999-dev',
30
  'aliases' =>
31
  array (
32
  ),
33
- 'reference' => '3ac8c7629656009b9e0d6d9e4ccda202aad3b8e0',
34
  'name' => 'timber/timber',
35
  ),
36
  'versions' =>
@@ -46,44 +46,48 @@ private static $installed = array (
46
  ),
47
  'composer/installers' =>
48
  array (
49
- 'pretty_version' => 'v1.12.0',
50
- 'version' => '1.12.0.0',
51
  'aliases' =>
52
  array (
53
  ),
54
- 'reference' => 'd20a64ed3c94748397ff5973488761b22f6d3f19',
55
  ),
56
- 'roundcube/plugin-installer' =>
57
  array (
58
- 'replaced' =>
 
 
59
  array (
60
- 0 => '*',
61
  ),
 
62
  ),
63
- 'shama/baton' =>
64
  array (
65
- 'replaced' =>
 
 
66
  array (
67
- 0 => '*',
68
  ),
 
69
  ),
70
- 'symfony/polyfill-ctype' =>
71
  array (
72
- 'pretty_version' => 'v1.19.0',
73
- 'version' => '1.19.0.0',
74
  'aliases' =>
75
  array (
76
  ),
77
- 'reference' => 'aed596913b70fae57be53d86faa2e9ef85a2297b',
78
  ),
79
  'timber/timber' =>
80
  array (
81
- 'pretty_version' => '1.20.0.x-dev',
82
- 'version' => '1.20.0.9999999-dev',
83
  'aliases' =>
84
  array (
85
  ),
86
- 'reference' => '3ac8c7629656009b9e0d6d9e4ccda202aad3b8e0',
87
  ),
88
  'twig/cache-extension' =>
89
  array (
@@ -96,12 +100,12 @@ private static $installed = array (
96
  ),
97
  'twig/twig' =>
98
  array (
99
- 'pretty_version' => 'v1.42.5',
100
- 'version' => '1.42.5.0',
101
  'aliases' =>
102
  array (
103
  ),
104
- 'reference' => '87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e',
105
  ),
106
  'upstatement/routes' =>
107
  array (
25
  private static $installed = array (
26
  'root' =>
27
  array (
28
+ 'pretty_version' => '1.21.0.x-dev',
29
+ 'version' => '1.21.0.9999999-dev',
30
  'aliases' =>
31
  array (
32
  ),
33
+ 'reference' => '342007fffa62b89c7d0c345914ac61482e4fe939',
34
  'name' => 'timber/timber',
35
  ),
36
  'versions' =>
46
  ),
47
  'composer/installers' =>
48
  array (
49
+ 'pretty_version' => 'v2.2.0',
50
+ 'version' => '2.2.0.0',
51
  'aliases' =>
52
  array (
53
  ),
54
+ 'reference' => 'c29dc4b93137acb82734f672c37e029dfbd95b35',
55
  ),
56
+ 'symfony/polyfill-ctype' =>
57
  array (
58
+ 'pretty_version' => 'v1.26.0',
59
+ 'version' => '1.26.0.0',
60
+ 'aliases' =>
61
  array (
 
62
  ),
63
+ 'reference' => '6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4',
64
  ),
65
+ 'symfony/polyfill-mbstring' =>
66
  array (
67
+ 'pretty_version' => 'v1.26.0',
68
+ 'version' => '1.26.0.0',
69
+ 'aliases' =>
70
  array (
 
71
  ),
72
+ 'reference' => '9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e',
73
  ),
74
+ 'symfony/polyfill-php72' =>
75
  array (
76
+ 'pretty_version' => 'v1.26.0',
77
+ 'version' => '1.26.0.0',
78
  'aliases' =>
79
  array (
80
  ),
81
+ 'reference' => 'bf44a9fd41feaac72b074de600314a93e2ae78e2',
82
  ),
83
  'timber/timber' =>
84
  array (
85
+ 'pretty_version' => '1.21.0.x-dev',
86
+ 'version' => '1.21.0.9999999-dev',
87
  'aliases' =>
88
  array (
89
  ),
90
+ 'reference' => '342007fffa62b89c7d0c345914ac61482e4fe939',
91
  ),
92
  'twig/cache-extension' =>
93
  array (
100
  ),
101
  'twig/twig' =>
102
  array (
103
+ 'pretty_version' => 'v2.15.3',
104
+ 'version' => '2.15.3.0',
105
  'aliases' =>
106
  array (
107
  ),
108
+ 'reference' => 'ab402673db8746cb3a4c46f3869d6253699f614a',
109
  ),
110
  'upstatement/routes' =>
111
  array (
vendor/composer/autoload_classmap.php CHANGED
@@ -9,7 +9,7 @@ return array(
9
  'AltoRouter' => $vendorDir . '/altorouter/altorouter/AltoRouter.php',
10
  'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
11
  'Composer\\Installers\\AglInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AglInstaller.php',
12
- 'Composer\\Installers\\AimeosInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AimeosInstaller.php',
13
  'Composer\\Installers\\AnnotateCmsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php',
14
  'Composer\\Installers\\AsgardInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AsgardInstaller.php',
15
  'Composer\\Installers\\AttogramInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AttogramInstaller.php',
@@ -23,7 +23,6 @@ return array(
23
  'Composer\\Installers\\CockpitInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CockpitInstaller.php',
24
  'Composer\\Installers\\CodeIgniterInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php',
25
  'Composer\\Installers\\Concrete5Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Concrete5Installer.php',
26
- 'Composer\\Installers\\CraftInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CraftInstaller.php',
27
  'Composer\\Installers\\CroogoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CroogoInstaller.php',
28
  'Composer\\Installers\\DecibelInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DecibelInstaller.php',
29
  'Composer\\Installers\\DframeInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DframeInstaller.php',
@@ -41,9 +40,7 @@ return array(
41
  'Composer\\Installers\\ImageCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ImageCMSInstaller.php',
42
  'Composer\\Installers\\Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Installer.php',
43
  'Composer\\Installers\\ItopInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ItopInstaller.php',
44
- 'Composer\\Installers\\JoomlaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/JoomlaInstaller.php',
45
  'Composer\\Installers\\KanboardInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KanboardInstaller.php',
46
- 'Composer\\Installers\\KirbyInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KirbyInstaller.php',
47
  'Composer\\Installers\\KnownInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KnownInstaller.php',
48
  'Composer\\Installers\\KodiCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KodiCMSInstaller.php',
49
  'Composer\\Installers\\KohanaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KohanaInstaller.php',
@@ -57,6 +54,7 @@ return array(
57
  'Composer\\Installers\\MajimaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MajimaInstaller.php',
58
  'Composer\\Installers\\MakoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MakoInstaller.php',
59
  'Composer\\Installers\\MantisBTInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MantisBTInstaller.php',
 
60
  'Composer\\Installers\\MauticInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MauticInstaller.php',
61
  'Composer\\Installers\\MayaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MayaInstaller.php',
62
  'Composer\\Installers\\MediaWikiInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MediaWikiInstaller.php',
@@ -72,7 +70,6 @@ return array(
72
  'Composer\\Installers\\PantheonInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PantheonInstaller.php',
73
  'Composer\\Installers\\PhiftyInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PhiftyInstaller.php',
74
  'Composer\\Installers\\PhpBBInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PhpBBInstaller.php',
75
- 'Composer\\Installers\\PimcoreInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PimcoreInstaller.php',
76
  'Composer\\Installers\\PiwikInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PiwikInstaller.php',
77
  'Composer\\Installers\\PlentymarketsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php',
78
  'Composer\\Installers\\Plugin' => $vendorDir . '/composer/installers/src/Composer/Installers/Plugin.php',
@@ -93,9 +90,6 @@ return array(
93
  'Composer\\Installers\\StarbugInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/StarbugInstaller.php',
94
  'Composer\\Installers\\SyDESInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SyDESInstaller.php',
95
  'Composer\\Installers\\SyliusInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SyliusInstaller.php',
96
- 'Composer\\Installers\\Symfony1Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Symfony1Installer.php',
97
- 'Composer\\Installers\\TYPO3CmsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php',
98
- 'Composer\\Installers\\TYPO3FlowInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php',
99
  'Composer\\Installers\\TaoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TaoInstaller.php',
100
  'Composer\\Installers\\TastyIgniterInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php',
101
  'Composer\\Installers\\TheliaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TheliaInstaller.php',
@@ -112,6 +106,8 @@ return array(
112
  'Composer\\Installers\\ZikulaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ZikulaInstaller.php',
113
  'Routes' => $vendorDir . '/upstatement/routes/Routes.php',
114
  'Symfony\\Polyfill\\Ctype\\Ctype' => $vendorDir . '/symfony/polyfill-ctype/Ctype.php',
 
 
115
  'Timber\\Admin' => $baseDir . '/lib/Admin.php',
116
  'Timber\\Archives' => $baseDir . '/lib/Archives.php',
117
  'Timber\\Cache\\Cleaner' => $baseDir . '/lib/Cache/Cleaner.php',
@@ -192,6 +188,7 @@ return array(
192
  'Twig\\Error\\RuntimeError' => $vendorDir . '/twig/twig/src/Error/RuntimeError.php',
193
  'Twig\\Error\\SyntaxError' => $vendorDir . '/twig/twig/src/Error/SyntaxError.php',
194
  'Twig\\ExpressionParser' => $vendorDir . '/twig/twig/src/ExpressionParser.php',
 
195
  'Twig\\Extension\\AbstractExtension' => $vendorDir . '/twig/twig/src/Extension/AbstractExtension.php',
196
  'Twig\\Extension\\CoreExtension' => $vendorDir . '/twig/twig/src/Extension/CoreExtension.php',
197
  'Twig\\Extension\\DebugExtension' => $vendorDir . '/twig/twig/src/Extension/DebugExtension.php',
@@ -217,6 +214,7 @@ return array(
217
  'Twig\\NodeTraverser' => $vendorDir . '/twig/twig/src/NodeTraverser.php',
218
  'Twig\\NodeVisitor\\AbstractNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/AbstractNodeVisitor.php',
219
  'Twig\\NodeVisitor\\EscaperNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/EscaperNodeVisitor.php',
 
220
  'Twig\\NodeVisitor\\NodeVisitorInterface' => $vendorDir . '/twig/twig/src/NodeVisitor/NodeVisitorInterface.php',
221
  'Twig\\NodeVisitor\\OptimizerNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/OptimizerNodeVisitor.php',
222
  'Twig\\NodeVisitor\\SafeAnalysisNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php',
@@ -225,6 +223,7 @@ return array(
225
  'Twig\\Node\\BlockNode' => $vendorDir . '/twig/twig/src/Node/BlockNode.php',
226
  'Twig\\Node\\BlockReferenceNode' => $vendorDir . '/twig/twig/src/Node/BlockReferenceNode.php',
227
  'Twig\\Node\\BodyNode' => $vendorDir . '/twig/twig/src/Node/BodyNode.php',
 
228
  'Twig\\Node\\CheckSecurityNode' => $vendorDir . '/twig/twig/src/Node/CheckSecurityNode.php',
229
  'Twig\\Node\\CheckToStringNode' => $vendorDir . '/twig/twig/src/Node/CheckToStringNode.php',
230
  'Twig\\Node\\DeprecatedNode' => $vendorDir . '/twig/twig/src/Node/DeprecatedNode.php',
@@ -258,6 +257,7 @@ return array(
258
  'Twig\\Node\\Expression\\Binary\\OrBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/OrBinary.php',
259
  'Twig\\Node\\Expression\\Binary\\PowerBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/PowerBinary.php',
260
  'Twig\\Node\\Expression\\Binary\\RangeBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/RangeBinary.php',
 
261
  'Twig\\Node\\Expression\\Binary\\StartsWithBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php',
262
  'Twig\\Node\\Expression\\Binary\\SubBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/SubBinary.php',
263
  'Twig\\Node\\Expression\\BlockReferenceExpression' => $vendorDir . '/twig/twig/src/Node/Expression/BlockReferenceExpression.php',
@@ -286,6 +286,7 @@ return array(
286
  'Twig\\Node\\Expression\\Unary\\NegUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/NegUnary.php',
287
  'Twig\\Node\\Expression\\Unary\\NotUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/NotUnary.php',
288
  'Twig\\Node\\Expression\\Unary\\PosUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/PosUnary.php',
 
289
  'Twig\\Node\\FlushNode' => $vendorDir . '/twig/twig/src/Node/FlushNode.php',
290
  'Twig\\Node\\ForLoopNode' => $vendorDir . '/twig/twig/src/Node/ForLoopNode.php',
291
  'Twig\\Node\\ForNode' => $vendorDir . '/twig/twig/src/Node/ForNode.php',
@@ -301,7 +302,6 @@ return array(
301
  'Twig\\Node\\SandboxNode' => $vendorDir . '/twig/twig/src/Node/SandboxNode.php',
302
  'Twig\\Node\\SandboxedPrintNode' => $vendorDir . '/twig/twig/src/Node/SandboxedPrintNode.php',
303
  'Twig\\Node\\SetNode' => $vendorDir . '/twig/twig/src/Node/SetNode.php',
304
- 'Twig\\Node\\SetTempNode' => $vendorDir . '/twig/twig/src/Node/SetTempNode.php',
305
  'Twig\\Node\\SpacelessNode' => $vendorDir . '/twig/twig/src/Node/SpacelessNode.php',
306
  'Twig\\Node\\TextNode' => $vendorDir . '/twig/twig/src/Node/TextNode.php',
307
  'Twig\\Node\\WithNode' => $vendorDir . '/twig/twig/src/Node/WithNode.php',
@@ -359,13 +359,11 @@ return array(
359
  'Twig\\TwigTest' => $vendorDir . '/twig/twig/src/TwigTest.php',
360
  'Twig\\Util\\DeprecationCollector' => $vendorDir . '/twig/twig/src/Util/DeprecationCollector.php',
361
  'Twig\\Util\\TemplateDirIterator' => $vendorDir . '/twig/twig/src/Util/TemplateDirIterator.php',
362
- 'Twig_Autoloader' => $vendorDir . '/twig/twig/lib/Twig/Autoloader.php',
363
  'Twig_BaseNodeVisitor' => $vendorDir . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
364
  'Twig_CacheInterface' => $vendorDir . '/twig/twig/lib/Twig/CacheInterface.php',
365
  'Twig_Cache_Filesystem' => $vendorDir . '/twig/twig/lib/Twig/Cache/Filesystem.php',
366
  'Twig_Cache_Null' => $vendorDir . '/twig/twig/lib/Twig/Cache/Null.php',
367
  'Twig_Compiler' => $vendorDir . '/twig/twig/lib/Twig/Compiler.php',
368
- 'Twig_CompilerInterface' => $vendorDir . '/twig/twig/lib/Twig/CompilerInterface.php',
369
  'Twig_ContainerRuntimeLoader' => $vendorDir . '/twig/twig/lib/Twig/ContainerRuntimeLoader.php',
370
  'Twig_Environment' => $vendorDir . '/twig/twig/lib/Twig/Environment.php',
371
  'Twig_Error' => $vendorDir . '/twig/twig/lib/Twig/Error.php',
@@ -376,6 +374,7 @@ return array(
376
  'Twig_ExpressionParser' => $vendorDir . '/twig/twig/lib/Twig/ExpressionParser.php',
377
  'Twig_Extension' => $vendorDir . '/twig/twig/lib/Twig/Extension.php',
378
  'Twig_ExtensionInterface' => $vendorDir . '/twig/twig/lib/Twig/ExtensionInterface.php',
 
379
  'Twig_Extension_Core' => $vendorDir . '/twig/twig/lib/Twig/Extension/Core.php',
380
  'Twig_Extension_Debug' => $vendorDir . '/twig/twig/lib/Twig/Extension/Debug.php',
381
  'Twig_Extension_Escaper' => $vendorDir . '/twig/twig/lib/Twig/Extension/Escaper.php',
@@ -389,28 +388,15 @@ return array(
389
  'Twig_FactoryRuntimeLoader' => $vendorDir . '/twig/twig/lib/Twig/FactoryRuntimeLoader.php',
390
  'Twig_FileExtensionEscapingStrategy' => $vendorDir . '/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php',
391
  'Twig_Filter' => $vendorDir . '/twig/twig/lib/Twig/Filter.php',
392
- 'Twig_FilterCallableInterface' => $vendorDir . '/twig/twig/lib/Twig/FilterCallableInterface.php',
393
- 'Twig_FilterInterface' => $vendorDir . '/twig/twig/lib/Twig/FilterInterface.php',
394
- 'Twig_Filter_Function' => $vendorDir . '/twig/twig/lib/Twig/Filter/Function.php',
395
- 'Twig_Filter_Method' => $vendorDir . '/twig/twig/lib/Twig/Filter/Method.php',
396
- 'Twig_Filter_Node' => $vendorDir . '/twig/twig/lib/Twig/Filter/Node.php',
397
  'Twig_Function' => $vendorDir . '/twig/twig/lib/Twig/Function.php',
398
- 'Twig_FunctionCallableInterface' => $vendorDir . '/twig/twig/lib/Twig/FunctionCallableInterface.php',
399
- 'Twig_FunctionInterface' => $vendorDir . '/twig/twig/lib/Twig/FunctionInterface.php',
400
- 'Twig_Function_Function' => $vendorDir . '/twig/twig/lib/Twig/Function/Function.php',
401
- 'Twig_Function_Method' => $vendorDir . '/twig/twig/lib/Twig/Function/Method.php',
402
- 'Twig_Function_Node' => $vendorDir . '/twig/twig/lib/Twig/Function/Node.php',
403
  'Twig_Lexer' => $vendorDir . '/twig/twig/lib/Twig/Lexer.php',
404
- 'Twig_LexerInterface' => $vendorDir . '/twig/twig/lib/Twig/LexerInterface.php',
405
  'Twig_LoaderInterface' => $vendorDir . '/twig/twig/lib/Twig/LoaderInterface.php',
406
  'Twig_Loader_Array' => $vendorDir . '/twig/twig/lib/Twig/Loader/Array.php',
407
  'Twig_Loader_Chain' => $vendorDir . '/twig/twig/lib/Twig/Loader/Chain.php',
408
  'Twig_Loader_Filesystem' => $vendorDir . '/twig/twig/lib/Twig/Loader/Filesystem.php',
409
- 'Twig_Loader_String' => $vendorDir . '/twig/twig/lib/Twig/Loader/String.php',
410
  'Twig_Markup' => $vendorDir . '/twig/twig/lib/Twig/Markup.php',
411
  'Twig_Node' => $vendorDir . '/twig/twig/lib/Twig/Node.php',
412
  'Twig_NodeCaptureInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeCaptureInterface.php',
413
- 'Twig_NodeInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeInterface.php',
414
  'Twig_NodeOutputInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeOutputInterface.php',
415
  'Twig_NodeTraverser' => $vendorDir . '/twig/twig/lib/Twig/NodeTraverser.php',
416
  'Twig_NodeVisitorInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeVisitorInterface.php',
@@ -459,7 +445,6 @@ return array(
459
  'Twig_Node_Expression_Call' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Call.php',
460
  'Twig_Node_Expression_Conditional' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Conditional.php',
461
  'Twig_Node_Expression_Constant' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Constant.php',
462
- 'Twig_Node_Expression_ExtensionReference' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php',
463
  'Twig_Node_Expression_Filter' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Filter.php',
464
  'Twig_Node_Expression_Filter_Default' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Filter/Default.php',
465
  'Twig_Node_Expression_Function' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Function.php',
@@ -493,12 +478,10 @@ return array(
493
  'Twig_Node_Sandbox' => $vendorDir . '/twig/twig/lib/Twig/Node/Sandbox.php',
494
  'Twig_Node_SandboxedPrint' => $vendorDir . '/twig/twig/lib/Twig/Node/SandboxedPrint.php',
495
  'Twig_Node_Set' => $vendorDir . '/twig/twig/lib/Twig/Node/Set.php',
496
- 'Twig_Node_SetTemp' => $vendorDir . '/twig/twig/lib/Twig/Node/SetTemp.php',
497
  'Twig_Node_Spaceless' => $vendorDir . '/twig/twig/lib/Twig/Node/Spaceless.php',
498
  'Twig_Node_Text' => $vendorDir . '/twig/twig/lib/Twig/Node/Text.php',
499
  'Twig_Node_With' => $vendorDir . '/twig/twig/lib/Twig/Node/With.php',
500
  'Twig_Parser' => $vendorDir . '/twig/twig/lib/Twig/Parser.php',
501
- 'Twig_ParserInterface' => $vendorDir . '/twig/twig/lib/Twig/ParserInterface.php',
502
  'Twig_Profiler_Dumper_Base' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Base.php',
503
  'Twig_Profiler_Dumper_Blackfire' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php',
504
  'Twig_Profiler_Dumper_Html' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Html.php',
@@ -522,20 +505,12 @@ return array(
522
  'Twig_Source' => $vendorDir . '/twig/twig/lib/Twig/Source.php',
523
  'Twig_SourceContextLoaderInterface' => $vendorDir . '/twig/twig/lib/Twig/SourceContextLoaderInterface.php',
524
  'Twig_Template' => $vendorDir . '/twig/twig/lib/Twig/Template.php',
525
- 'Twig_TemplateInterface' => $vendorDir . '/twig/twig/lib/Twig/TemplateInterface.php',
526
  'Twig_TemplateWrapper' => $vendorDir . '/twig/twig/lib/Twig/TemplateWrapper.php',
527
  'Twig_Test' => $vendorDir . '/twig/twig/lib/Twig/Test.php',
528
- 'Twig_TestCallableInterface' => $vendorDir . '/twig/twig/lib/Twig/TestCallableInterface.php',
529
- 'Twig_TestInterface' => $vendorDir . '/twig/twig/lib/Twig/TestInterface.php',
530
- 'Twig_Test_Function' => $vendorDir . '/twig/twig/lib/Twig/Test/Function.php',
531
  'Twig_Test_IntegrationTestCase' => $vendorDir . '/twig/twig/lib/Twig/Test/IntegrationTestCase.php',
532
- 'Twig_Test_Method' => $vendorDir . '/twig/twig/lib/Twig/Test/Method.php',
533
- 'Twig_Test_Node' => $vendorDir . '/twig/twig/lib/Twig/Test/Node.php',
534
  'Twig_Test_NodeTestCase' => $vendorDir . '/twig/twig/lib/Twig/Test/NodeTestCase.php',
535
  'Twig_Token' => $vendorDir . '/twig/twig/lib/Twig/Token.php',
536
  'Twig_TokenParser' => $vendorDir . '/twig/twig/lib/Twig/TokenParser.php',
537
- 'Twig_TokenParserBroker' => $vendorDir . '/twig/twig/lib/Twig/TokenParserBroker.php',
538
- 'Twig_TokenParserBrokerInterface' => $vendorDir . '/twig/twig/lib/Twig/TokenParserBrokerInterface.php',
539
  'Twig_TokenParserInterface' => $vendorDir . '/twig/twig/lib/Twig/TokenParserInterface.php',
540
  'Twig_TokenParser_AutoEscape' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/AutoEscape.php',
541
  'Twig_TokenParser_Block' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Block.php',
9
  'AltoRouter' => $vendorDir . '/altorouter/altorouter/AltoRouter.php',
10
  'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
11
  'Composer\\Installers\\AglInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AglInstaller.php',
12
+ 'Composer\\Installers\\AkauntingInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AkauntingInstaller.php',
13
  'Composer\\Installers\\AnnotateCmsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php',
14
  'Composer\\Installers\\AsgardInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AsgardInstaller.php',
15
  'Composer\\Installers\\AttogramInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AttogramInstaller.php',
23
  'Composer\\Installers\\CockpitInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CockpitInstaller.php',
24
  'Composer\\Installers\\CodeIgniterInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php',
25
  'Composer\\Installers\\Concrete5Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Concrete5Installer.php',
 
26
  'Composer\\Installers\\CroogoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CroogoInstaller.php',
27
  'Composer\\Installers\\DecibelInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DecibelInstaller.php',
28
  'Composer\\Installers\\DframeInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DframeInstaller.php',
40
  'Composer\\Installers\\ImageCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ImageCMSInstaller.php',
41
  'Composer\\Installers\\Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Installer.php',
42
  'Composer\\Installers\\ItopInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ItopInstaller.php',
 
43
  'Composer\\Installers\\KanboardInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KanboardInstaller.php',
 
44
  'Composer\\Installers\\KnownInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KnownInstaller.php',
45
  'Composer\\Installers\\KodiCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KodiCMSInstaller.php',
46
  'Composer\\Installers\\KohanaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KohanaInstaller.php',
54
  'Composer\\Installers\\MajimaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MajimaInstaller.php',
55
  'Composer\\Installers\\MakoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MakoInstaller.php',
56
  'Composer\\Installers\\MantisBTInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MantisBTInstaller.php',
57
+ 'Composer\\Installers\\MatomoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MatomoInstaller.php',
58
  'Composer\\Installers\\MauticInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MauticInstaller.php',
59
  'Composer\\Installers\\MayaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MayaInstaller.php',
60
  'Composer\\Installers\\MediaWikiInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MediaWikiInstaller.php',
70
  'Composer\\Installers\\PantheonInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PantheonInstaller.php',
71
  'Composer\\Installers\\PhiftyInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PhiftyInstaller.php',
72
  'Composer\\Installers\\PhpBBInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PhpBBInstaller.php',
 
73
  'Composer\\Installers\\PiwikInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PiwikInstaller.php',
74
  'Composer\\Installers\\PlentymarketsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php',
75
  'Composer\\Installers\\Plugin' => $vendorDir . '/composer/installers/src/Composer/Installers/Plugin.php',
90
  'Composer\\Installers\\StarbugInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/StarbugInstaller.php',
91
  'Composer\\Installers\\SyDESInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SyDESInstaller.php',
92
  'Composer\\Installers\\SyliusInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SyliusInstaller.php',
 
 
 
93
  'Composer\\Installers\\TaoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TaoInstaller.php',
94
  'Composer\\Installers\\TastyIgniterInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php',
95
  'Composer\\Installers\\TheliaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TheliaInstaller.php',
106
  'Composer\\Installers\\ZikulaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ZikulaInstaller.php',
107
  'Routes' => $vendorDir . '/upstatement/routes/Routes.php',
108
  'Symfony\\Polyfill\\Ctype\\Ctype' => $vendorDir . '/symfony/polyfill-ctype/Ctype.php',
109
+ 'Symfony\\Polyfill\\Mbstring\\Mbstring' => $vendorDir . '/symfony/polyfill-mbstring/Mbstring.php',
110
+ 'Symfony\\Polyfill\\Php72\\Php72' => $vendorDir . '/symfony/polyfill-php72/Php72.php',
111
  'Timber\\Admin' => $baseDir . '/lib/Admin.php',
112
  'Timber\\Archives' => $baseDir . '/lib/Archives.php',
113
  'Timber\\Cache\\Cleaner' => $baseDir . '/lib/Cache/Cleaner.php',
188
  'Twig\\Error\\RuntimeError' => $vendorDir . '/twig/twig/src/Error/RuntimeError.php',
189
  'Twig\\Error\\SyntaxError' => $vendorDir . '/twig/twig/src/Error/SyntaxError.php',
190
  'Twig\\ExpressionParser' => $vendorDir . '/twig/twig/src/ExpressionParser.php',
191
+ 'Twig\\ExtensionSet' => $vendorDir . '/twig/twig/src/ExtensionSet.php',
192
  'Twig\\Extension\\AbstractExtension' => $vendorDir . '/twig/twig/src/Extension/AbstractExtension.php',
193
  'Twig\\Extension\\CoreExtension' => $vendorDir . '/twig/twig/src/Extension/CoreExtension.php',
194
  'Twig\\Extension\\DebugExtension' => $vendorDir . '/twig/twig/src/Extension/DebugExtension.php',
214
  'Twig\\NodeTraverser' => $vendorDir . '/twig/twig/src/NodeTraverser.php',
215
  'Twig\\NodeVisitor\\AbstractNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/AbstractNodeVisitor.php',
216
  'Twig\\NodeVisitor\\EscaperNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/EscaperNodeVisitor.php',
217
+ 'Twig\\NodeVisitor\\MacroAutoImportNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/MacroAutoImportNodeVisitor.php',
218
  'Twig\\NodeVisitor\\NodeVisitorInterface' => $vendorDir . '/twig/twig/src/NodeVisitor/NodeVisitorInterface.php',
219
  'Twig\\NodeVisitor\\OptimizerNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/OptimizerNodeVisitor.php',
220
  'Twig\\NodeVisitor\\SafeAnalysisNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php',
223
  'Twig\\Node\\BlockNode' => $vendorDir . '/twig/twig/src/Node/BlockNode.php',
224
  'Twig\\Node\\BlockReferenceNode' => $vendorDir . '/twig/twig/src/Node/BlockReferenceNode.php',
225
  'Twig\\Node\\BodyNode' => $vendorDir . '/twig/twig/src/Node/BodyNode.php',
226
+ 'Twig\\Node\\CheckSecurityCallNode' => $vendorDir . '/twig/twig/src/Node/CheckSecurityCallNode.php',
227
  'Twig\\Node\\CheckSecurityNode' => $vendorDir . '/twig/twig/src/Node/CheckSecurityNode.php',
228
  'Twig\\Node\\CheckToStringNode' => $vendorDir . '/twig/twig/src/Node/CheckToStringNode.php',
229
  'Twig\\Node\\DeprecatedNode' => $vendorDir . '/twig/twig/src/Node/DeprecatedNode.php',
257
  'Twig\\Node\\Expression\\Binary\\OrBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/OrBinary.php',
258
  'Twig\\Node\\Expression\\Binary\\PowerBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/PowerBinary.php',
259
  'Twig\\Node\\Expression\\Binary\\RangeBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/RangeBinary.php',
260
+ 'Twig\\Node\\Expression\\Binary\\SpaceshipBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/SpaceshipBinary.php',
261
  'Twig\\Node\\Expression\\Binary\\StartsWithBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php',
262
  'Twig\\Node\\Expression\\Binary\\SubBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/SubBinary.php',
263
  'Twig\\Node\\Expression\\BlockReferenceExpression' => $vendorDir . '/twig/twig/src/Node/Expression/BlockReferenceExpression.php',
286
  'Twig\\Node\\Expression\\Unary\\NegUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/NegUnary.php',
287
  'Twig\\Node\\Expression\\Unary\\NotUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/NotUnary.php',
288
  'Twig\\Node\\Expression\\Unary\\PosUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/PosUnary.php',
289
+ 'Twig\\Node\\Expression\\VariadicExpression' => $vendorDir . '/twig/twig/src/Node/Expression/VariadicExpression.php',
290
  'Twig\\Node\\FlushNode' => $vendorDir . '/twig/twig/src/Node/FlushNode.php',
291
  'Twig\\Node\\ForLoopNode' => $vendorDir . '/twig/twig/src/Node/ForLoopNode.php',
292
  'Twig\\Node\\ForNode' => $vendorDir . '/twig/twig/src/Node/ForNode.php',
302
  'Twig\\Node\\SandboxNode' => $vendorDir . '/twig/twig/src/Node/SandboxNode.php',
303
  'Twig\\Node\\SandboxedPrintNode' => $vendorDir . '/twig/twig/src/Node/SandboxedPrintNode.php',
304
  'Twig\\Node\\SetNode' => $vendorDir . '/twig/twig/src/Node/SetNode.php',
 
305
  'Twig\\Node\\SpacelessNode' => $vendorDir . '/twig/twig/src/Node/SpacelessNode.php',
306
  'Twig\\Node\\TextNode' => $vendorDir . '/twig/twig/src/Node/TextNode.php',
307
  'Twig\\Node\\WithNode' => $vendorDir . '/twig/twig/src/Node/WithNode.php',
359
  'Twig\\TwigTest' => $vendorDir . '/twig/twig/src/TwigTest.php',
360
  'Twig\\Util\\DeprecationCollector' => $vendorDir . '/twig/twig/src/Util/DeprecationCollector.php',
361
  'Twig\\Util\\TemplateDirIterator' => $vendorDir . '/twig/twig/src/Util/TemplateDirIterator.php',
 
362
  'Twig_BaseNodeVisitor' => $vendorDir . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
363
  'Twig_CacheInterface' => $vendorDir . '/twig/twig/lib/Twig/CacheInterface.php',
364
  'Twig_Cache_Filesystem' => $vendorDir . '/twig/twig/lib/Twig/Cache/Filesystem.php',
365
  'Twig_Cache_Null' => $vendorDir . '/twig/twig/lib/Twig/Cache/Null.php',
366
  'Twig_Compiler' => $vendorDir . '/twig/twig/lib/Twig/Compiler.php',
 
367
  'Twig_ContainerRuntimeLoader' => $vendorDir . '/twig/twig/lib/Twig/ContainerRuntimeLoader.php',
368
  'Twig_Environment' => $vendorDir . '/twig/twig/lib/Twig/Environment.php',
369
  'Twig_Error' => $vendorDir . '/twig/twig/lib/Twig/Error.php',
374
  'Twig_ExpressionParser' => $vendorDir . '/twig/twig/lib/Twig/ExpressionParser.php',
375
  'Twig_Extension' => $vendorDir . '/twig/twig/lib/Twig/Extension.php',
376
  'Twig_ExtensionInterface' => $vendorDir . '/twig/twig/lib/Twig/ExtensionInterface.php',
377
+ 'Twig_ExtensionSet' => $vendorDir . '/twig/twig/lib/Twig/ExtensionSet.php',
378
  'Twig_Extension_Core' => $vendorDir . '/twig/twig/lib/Twig/Extension/Core.php',
379
  'Twig_Extension_Debug' => $vendorDir . '/twig/twig/lib/Twig/Extension/Debug.php',
380
  'Twig_Extension_Escaper' => $vendorDir . '/twig/twig/lib/Twig/Extension/Escaper.php',
388
  'Twig_FactoryRuntimeLoader' => $vendorDir . '/twig/twig/lib/Twig/FactoryRuntimeLoader.php',
389
  'Twig_FileExtensionEscapingStrategy' => $vendorDir . '/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php',
390
  'Twig_Filter' => $vendorDir . '/twig/twig/lib/Twig/Filter.php',
 
 
 
 
 
391
  'Twig_Function' => $vendorDir . '/twig/twig/lib/Twig/Function.php',
 
 
 
 
 
392
  'Twig_Lexer' => $vendorDir . '/twig/twig/lib/Twig/Lexer.php',
 
393
  'Twig_LoaderInterface' => $vendorDir . '/twig/twig/lib/Twig/LoaderInterface.php',
394
  'Twig_Loader_Array' => $vendorDir . '/twig/twig/lib/Twig/Loader/Array.php',
395
  'Twig_Loader_Chain' => $vendorDir . '/twig/twig/lib/Twig/Loader/Chain.php',
396
  'Twig_Loader_Filesystem' => $vendorDir . '/twig/twig/lib/Twig/Loader/Filesystem.php',
 
397
  'Twig_Markup' => $vendorDir . '/twig/twig/lib/Twig/Markup.php',
398
  'Twig_Node' => $vendorDir . '/twig/twig/lib/Twig/Node.php',
399
  'Twig_NodeCaptureInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeCaptureInterface.php',
 
400
  'Twig_NodeOutputInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeOutputInterface.php',
401
  'Twig_NodeTraverser' => $vendorDir . '/twig/twig/lib/Twig/NodeTraverser.php',
402
  'Twig_NodeVisitorInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeVisitorInterface.php',
445
  'Twig_Node_Expression_Call' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Call.php',
446
  'Twig_Node_Expression_Conditional' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Conditional.php',
447
  'Twig_Node_Expression_Constant' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Constant.php',
 
448
  'Twig_Node_Expression_Filter' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Filter.php',
449
  'Twig_Node_Expression_Filter_Default' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Filter/Default.php',
450
  'Twig_Node_Expression_Function' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Function.php',
478
  'Twig_Node_Sandbox' => $vendorDir . '/twig/twig/lib/Twig/Node/Sandbox.php',
479
  'Twig_Node_SandboxedPrint' => $vendorDir . '/twig/twig/lib/Twig/Node/SandboxedPrint.php',
480
  'Twig_Node_Set' => $vendorDir . '/twig/twig/lib/Twig/Node/Set.php',
 
481
  'Twig_Node_Spaceless' => $vendorDir . '/twig/twig/lib/Twig/Node/Spaceless.php',
482
  'Twig_Node_Text' => $vendorDir . '/twig/twig/lib/Twig/Node/Text.php',
483
  'Twig_Node_With' => $vendorDir . '/twig/twig/lib/Twig/Node/With.php',
484
  'Twig_Parser' => $vendorDir . '/twig/twig/lib/Twig/Parser.php',
 
485
  'Twig_Profiler_Dumper_Base' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Base.php',
486
  'Twig_Profiler_Dumper_Blackfire' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php',
487
  'Twig_Profiler_Dumper_Html' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Html.php',
505
  'Twig_Source' => $vendorDir . '/twig/twig/lib/Twig/Source.php',
506
  'Twig_SourceContextLoaderInterface' => $vendorDir . '/twig/twig/lib/Twig/SourceContextLoaderInterface.php',
507
  'Twig_Template' => $vendorDir . '/twig/twig/lib/Twig/Template.php',
 
508
  'Twig_TemplateWrapper' => $vendorDir . '/twig/twig/lib/Twig/TemplateWrapper.php',
509
  'Twig_Test' => $vendorDir . '/twig/twig/lib/Twig/Test.php',
 
 
 
510
  'Twig_Test_IntegrationTestCase' => $vendorDir . '/twig/twig/lib/Twig/Test/IntegrationTestCase.php',
 
 
511
  'Twig_Test_NodeTestCase' => $vendorDir . '/twig/twig/lib/Twig/Test/NodeTestCase.php',
512
  'Twig_Token' => $vendorDir . '/twig/twig/lib/Twig/Token.php',
513
  'Twig_TokenParser' => $vendorDir . '/twig/twig/lib/Twig/TokenParser.php',
 
 
514
  'Twig_TokenParserInterface' => $vendorDir . '/twig/twig/lib/Twig/TokenParserInterface.php',
515
  'Twig_TokenParser_AutoEscape' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/AutoEscape.php',
516
  'Twig_TokenParser_Block' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Block.php',
vendor/composer/autoload_files.php CHANGED
@@ -6,5 +6,7 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
 
9
  '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
10
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
10
+ '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
11
  '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
12
  );
vendor/composer/autoload_psr4.php CHANGED
@@ -8,6 +8,8 @@ $baseDir = dirname($vendorDir);
8
  return array(
9
  'Twig\\' => array($vendorDir . '/twig/twig/src'),
10
  'Timber\\' => array($baseDir . '/lib'),
 
 
11
  'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
12
  'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'),
13
  '' => array($vendorDir . '/twig/cache-extension/lib'),
8
  return array(
9
  'Twig\\' => array($vendorDir . '/twig/twig/src'),
10
  'Timber\\' => array($baseDir . '/lib'),
11
+ 'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'),
12
+ 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
13
  'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
14
  'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'),
15
  '' => array($vendorDir . '/twig/cache-extension/lib'),
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit1fb235bc74e35292d2b088681fade654
6
  {
7
  private static $loader;
8
 
@@ -24,15 +24,15 @@ class ComposerAutoloaderInit1fb235bc74e35292d2b088681fade654
24
 
25
  require __DIR__ . '/platform_check.php';
26
 
27
- spl_autoload_register(array('ComposerAutoloaderInit1fb235bc74e35292d2b088681fade654', 'loadClassLoader'), true, true);
28
  self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
29
- spl_autoload_unregister(array('ComposerAutoloaderInit1fb235bc74e35292d2b088681fade654', 'loadClassLoader'));
30
 
31
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
32
  if ($useStaticLoader) {
33
  require __DIR__ . '/autoload_static.php';
34
 
35
- call_user_func(\Composer\Autoload\ComposerStaticInit1fb235bc74e35292d2b088681fade654::getInitializer($loader));
36
  } else {
37
  $map = require __DIR__ . '/autoload_namespaces.php';
38
  foreach ($map as $namespace => $path) {
@@ -53,19 +53,19 @@ class ComposerAutoloaderInit1fb235bc74e35292d2b088681fade654
53
  $loader->register(true);
54
 
55
  if ($useStaticLoader) {
56
- $includeFiles = Composer\Autoload\ComposerStaticInit1fb235bc74e35292d2b088681fade654::$files;
57
  } else {
58
  $includeFiles = require __DIR__ . '/autoload_files.php';
59
  }
60
  foreach ($includeFiles as $fileIdentifier => $file) {
61
- composerRequire1fb235bc74e35292d2b088681fade654($fileIdentifier, $file);
62
  }
63
 
64
  return $loader;
65
  }
66
  }
67
 
68
- function composerRequire1fb235bc74e35292d2b088681fade654($fileIdentifier, $file)
69
  {
70
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
71
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit989702ef2dea046e4eae802005e7b013
6
  {
7
  private static $loader;
8
 
24
 
25
  require __DIR__ . '/platform_check.php';
26
 
27
+ spl_autoload_register(array('ComposerAutoloaderInit989702ef2dea046e4eae802005e7b013', 'loadClassLoader'), true, true);
28
  self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
29
+ spl_autoload_unregister(array('ComposerAutoloaderInit989702ef2dea046e4eae802005e7b013', 'loadClassLoader'));
30
 
31
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
32
  if ($useStaticLoader) {
33
  require __DIR__ . '/autoload_static.php';
34
 
35
+ call_user_func(\Composer\Autoload\ComposerStaticInit989702ef2dea046e4eae802005e7b013::getInitializer($loader));
36
  } else {
37
  $map = require __DIR__ . '/autoload_namespaces.php';
38
  foreach ($map as $namespace => $path) {
53
  $loader->register(true);
54
 
55
  if ($useStaticLoader) {
56
+ $includeFiles = Composer\Autoload\ComposerStaticInit989702ef2dea046e4eae802005e7b013::$files;
57
  } else {
58
  $includeFiles = require __DIR__ . '/autoload_files.php';
59
  }
60
  foreach ($includeFiles as $fileIdentifier => $file) {
61
+ composerRequire989702ef2dea046e4eae802005e7b013($fileIdentifier, $file);
62
  }
63
 
64
  return $loader;
65
  }
66
  }
67
 
68
+ function composerRequire989702ef2dea046e4eae802005e7b013($fileIdentifier, $file)
69
  {
70
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
71
  require $file;
vendor/composer/autoload_static.php CHANGED
@@ -4,9 +4,11 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit1fb235bc74e35292d2b088681fade654
8
  {
9
  public static $files = array (
 
 
10
  '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
11
  );
12
 
@@ -18,6 +20,8 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
18
  ),
19
  'S' =>
20
  array (
 
 
21
  'Symfony\\Polyfill\\Ctype\\' => 23,
22
  ),
23
  'C' =>
@@ -35,6 +39,14 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
35
  array (
36
  0 => __DIR__ . '/../..' . '/lib',
37
  ),
 
 
 
 
 
 
 
 
38
  'Symfony\\Polyfill\\Ctype\\' =>
39
  array (
40
  0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
@@ -70,7 +82,7 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
70
  'AltoRouter' => __DIR__ . '/..' . '/altorouter/altorouter/AltoRouter.php',
71
  'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
72
  'Composer\\Installers\\AglInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AglInstaller.php',
73
- 'Composer\\Installers\\AimeosInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AimeosInstaller.php',
74
  'Composer\\Installers\\AnnotateCmsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php',
75
  'Composer\\Installers\\AsgardInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AsgardInstaller.php',
76
  'Composer\\Installers\\AttogramInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AttogramInstaller.php',
@@ -84,7 +96,6 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
84
  'Composer\\Installers\\CockpitInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CockpitInstaller.php',
85
  'Composer\\Installers\\CodeIgniterInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php',
86
  'Composer\\Installers\\Concrete5Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Concrete5Installer.php',
87
- 'Composer\\Installers\\CraftInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CraftInstaller.php',
88
  'Composer\\Installers\\CroogoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CroogoInstaller.php',
89
  'Composer\\Installers\\DecibelInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DecibelInstaller.php',
90
  'Composer\\Installers\\DframeInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DframeInstaller.php',
@@ -102,9 +113,7 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
102
  'Composer\\Installers\\ImageCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ImageCMSInstaller.php',
103
  'Composer\\Installers\\Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Installer.php',
104
  'Composer\\Installers\\ItopInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ItopInstaller.php',
105
- 'Composer\\Installers\\JoomlaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/JoomlaInstaller.php',
106
  'Composer\\Installers\\KanboardInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KanboardInstaller.php',
107
- 'Composer\\Installers\\KirbyInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KirbyInstaller.php',
108
  'Composer\\Installers\\KnownInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KnownInstaller.php',
109
  'Composer\\Installers\\KodiCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KodiCMSInstaller.php',
110
  'Composer\\Installers\\KohanaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KohanaInstaller.php',
@@ -118,6 +127,7 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
118
  'Composer\\Installers\\MajimaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MajimaInstaller.php',
119
  'Composer\\Installers\\MakoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MakoInstaller.php',
120
  'Composer\\Installers\\MantisBTInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MantisBTInstaller.php',
 
121
  'Composer\\Installers\\MauticInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MauticInstaller.php',
122
  'Composer\\Installers\\MayaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MayaInstaller.php',
123
  'Composer\\Installers\\MediaWikiInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MediaWikiInstaller.php',
@@ -133,7 +143,6 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
133
  'Composer\\Installers\\PantheonInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PantheonInstaller.php',
134
  'Composer\\Installers\\PhiftyInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PhiftyInstaller.php',
135
  'Composer\\Installers\\PhpBBInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PhpBBInstaller.php',
136
- 'Composer\\Installers\\PimcoreInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PimcoreInstaller.php',
137
  'Composer\\Installers\\PiwikInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PiwikInstaller.php',
138
  'Composer\\Installers\\PlentymarketsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php',
139
  'Composer\\Installers\\Plugin' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Plugin.php',
@@ -154,9 +163,6 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
154
  'Composer\\Installers\\StarbugInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/StarbugInstaller.php',
155
  'Composer\\Installers\\SyDESInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SyDESInstaller.php',
156
  'Composer\\Installers\\SyliusInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SyliusInstaller.php',
157
- 'Composer\\Installers\\Symfony1Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Symfony1Installer.php',
158
- 'Composer\\Installers\\TYPO3CmsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php',
159
- 'Composer\\Installers\\TYPO3FlowInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php',
160
  'Composer\\Installers\\TaoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TaoInstaller.php',
161
  'Composer\\Installers\\TastyIgniterInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php',
162
  'Composer\\Installers\\TheliaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TheliaInstaller.php',
@@ -173,6 +179,8 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
173
  'Composer\\Installers\\ZikulaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ZikulaInstaller.php',
174
  'Routes' => __DIR__ . '/..' . '/upstatement/routes/Routes.php',
175
  'Symfony\\Polyfill\\Ctype\\Ctype' => __DIR__ . '/..' . '/symfony/polyfill-ctype/Ctype.php',
 
 
176
  'Timber\\Admin' => __DIR__ . '/../..' . '/lib/Admin.php',
177
  'Timber\\Archives' => __DIR__ . '/../..' . '/lib/Archives.php',
178
  'Timber\\Cache\\Cleaner' => __DIR__ . '/../..' . '/lib/Cache/Cleaner.php',
@@ -253,6 +261,7 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
253
  'Twig\\Error\\RuntimeError' => __DIR__ . '/..' . '/twig/twig/src/Error/RuntimeError.php',
254
  'Twig\\Error\\SyntaxError' => __DIR__ . '/..' . '/twig/twig/src/Error/SyntaxError.php',
255
  'Twig\\ExpressionParser' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser.php',
 
256
  'Twig\\Extension\\AbstractExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/AbstractExtension.php',
257
  'Twig\\Extension\\CoreExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/CoreExtension.php',
258
  'Twig\\Extension\\DebugExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/DebugExtension.php',
@@ -278,6 +287,7 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
278
  'Twig\\NodeTraverser' => __DIR__ . '/..' . '/twig/twig/src/NodeTraverser.php',
279
  'Twig\\NodeVisitor\\AbstractNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/AbstractNodeVisitor.php',
280
  'Twig\\NodeVisitor\\EscaperNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/EscaperNodeVisitor.php',
 
281
  'Twig\\NodeVisitor\\NodeVisitorInterface' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/NodeVisitorInterface.php',
282
  'Twig\\NodeVisitor\\OptimizerNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/OptimizerNodeVisitor.php',
283
  'Twig\\NodeVisitor\\SafeAnalysisNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php',
@@ -286,6 +296,7 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
286
  'Twig\\Node\\BlockNode' => __DIR__ . '/..' . '/twig/twig/src/Node/BlockNode.php',
287
  'Twig\\Node\\BlockReferenceNode' => __DIR__ . '/..' . '/twig/twig/src/Node/BlockReferenceNode.php',
288
  'Twig\\Node\\BodyNode' => __DIR__ . '/..' . '/twig/twig/src/Node/BodyNode.php',
 
289
  'Twig\\Node\\CheckSecurityNode' => __DIR__ . '/..' . '/twig/twig/src/Node/CheckSecurityNode.php',
290
  'Twig\\Node\\CheckToStringNode' => __DIR__ . '/..' . '/twig/twig/src/Node/CheckToStringNode.php',
291
  'Twig\\Node\\DeprecatedNode' => __DIR__ . '/..' . '/twig/twig/src/Node/DeprecatedNode.php',
@@ -319,6 +330,7 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
319
  'Twig\\Node\\Expression\\Binary\\OrBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/OrBinary.php',
320
  'Twig\\Node\\Expression\\Binary\\PowerBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/PowerBinary.php',
321
  'Twig\\Node\\Expression\\Binary\\RangeBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/RangeBinary.php',
 
322
  'Twig\\Node\\Expression\\Binary\\StartsWithBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php',
323
  'Twig\\Node\\Expression\\Binary\\SubBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/SubBinary.php',
324
  'Twig\\Node\\Expression\\BlockReferenceExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/BlockReferenceExpression.php',
@@ -347,6 +359,7 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
347
  'Twig\\Node\\Expression\\Unary\\NegUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/NegUnary.php',
348
  'Twig\\Node\\Expression\\Unary\\NotUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/NotUnary.php',
349
  'Twig\\Node\\Expression\\Unary\\PosUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/PosUnary.php',
 
350
  'Twig\\Node\\FlushNode' => __DIR__ . '/..' . '/twig/twig/src/Node/FlushNode.php',
351
  'Twig\\Node\\ForLoopNode' => __DIR__ . '/..' . '/twig/twig/src/Node/ForLoopNode.php',
352
  'Twig\\Node\\ForNode' => __DIR__ . '/..' . '/twig/twig/src/Node/ForNode.php',
@@ -362,7 +375,6 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
362
  'Twig\\Node\\SandboxNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SandboxNode.php',
363
  'Twig\\Node\\SandboxedPrintNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SandboxedPrintNode.php',
364
  'Twig\\Node\\SetNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SetNode.php',
365
- 'Twig\\Node\\SetTempNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SetTempNode.php',
366
  'Twig\\Node\\SpacelessNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SpacelessNode.php',
367
  'Twig\\Node\\TextNode' => __DIR__ . '/..' . '/twig/twig/src/Node/TextNode.php',
368
  'Twig\\Node\\WithNode' => __DIR__ . '/..' . '/twig/twig/src/Node/WithNode.php',
@@ -420,13 +432,11 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
420
  'Twig\\TwigTest' => __DIR__ . '/..' . '/twig/twig/src/TwigTest.php',
421
  'Twig\\Util\\DeprecationCollector' => __DIR__ . '/..' . '/twig/twig/src/Util/DeprecationCollector.php',
422
  'Twig\\Util\\TemplateDirIterator' => __DIR__ . '/..' . '/twig/twig/src/Util/TemplateDirIterator.php',
423
- 'Twig_Autoloader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Autoloader.php',
424
  'Twig_BaseNodeVisitor' => __DIR__ . '/..' . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
425
  'Twig_CacheInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/CacheInterface.php',
426
  'Twig_Cache_Filesystem' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Cache/Filesystem.php',
427
  'Twig_Cache_Null' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Cache/Null.php',
428
  'Twig_Compiler' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Compiler.php',
429
- 'Twig_CompilerInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/CompilerInterface.php',
430
  'Twig_ContainerRuntimeLoader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ContainerRuntimeLoader.php',
431
  'Twig_Environment' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Environment.php',
432
  'Twig_Error' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Error.php',
@@ -437,6 +447,7 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
437
  'Twig_ExpressionParser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ExpressionParser.php',
438
  'Twig_Extension' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension.php',
439
  'Twig_ExtensionInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ExtensionInterface.php',
 
440
  'Twig_Extension_Core' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Core.php',
441
  'Twig_Extension_Debug' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Debug.php',
442
  'Twig_Extension_Escaper' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Escaper.php',
@@ -450,28 +461,15 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
450
  'Twig_FactoryRuntimeLoader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FactoryRuntimeLoader.php',
451
  'Twig_FileExtensionEscapingStrategy' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php',
452
  'Twig_Filter' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Filter.php',
453
- 'Twig_FilterCallableInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FilterCallableInterface.php',
454
- 'Twig_FilterInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FilterInterface.php',
455
- 'Twig_Filter_Function' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Filter/Function.php',
456
- 'Twig_Filter_Method' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Filter/Method.php',
457
- 'Twig_Filter_Node' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Filter/Node.php',
458
  'Twig_Function' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Function.php',
459
- 'Twig_FunctionCallableInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FunctionCallableInterface.php',
460
- 'Twig_FunctionInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FunctionInterface.php',
461
- 'Twig_Function_Function' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Function/Function.php',
462
- 'Twig_Function_Method' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Function/Method.php',
463
- 'Twig_Function_Node' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Function/Node.php',
464
  'Twig_Lexer' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Lexer.php',
465
- 'Twig_LexerInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/LexerInterface.php',
466
  'Twig_LoaderInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/LoaderInterface.php',
467
  'Twig_Loader_Array' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Loader/Array.php',
468
  'Twig_Loader_Chain' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Loader/Chain.php',
469
  'Twig_Loader_Filesystem' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Loader/Filesystem.php',
470
- 'Twig_Loader_String' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Loader/String.php',
471
  'Twig_Markup' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Markup.php',
472
  'Twig_Node' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node.php',
473
  'Twig_NodeCaptureInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeCaptureInterface.php',
474
- 'Twig_NodeInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeInterface.php',
475
  'Twig_NodeOutputInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeOutputInterface.php',
476
  'Twig_NodeTraverser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeTraverser.php',
477
  'Twig_NodeVisitorInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeVisitorInterface.php',
@@ -520,7 +518,6 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
520
  'Twig_Node_Expression_Call' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Call.php',
521
  'Twig_Node_Expression_Conditional' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Conditional.php',
522
  'Twig_Node_Expression_Constant' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Constant.php',
523
- 'Twig_Node_Expression_ExtensionReference' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php',
524
  'Twig_Node_Expression_Filter' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Filter.php',
525
  'Twig_Node_Expression_Filter_Default' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Filter/Default.php',
526
  'Twig_Node_Expression_Function' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Function.php',
@@ -554,12 +551,10 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
554
  'Twig_Node_Sandbox' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Sandbox.php',
555
  'Twig_Node_SandboxedPrint' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/SandboxedPrint.php',
556
  'Twig_Node_Set' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Set.php',
557
- 'Twig_Node_SetTemp' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/SetTemp.php',
558
  'Twig_Node_Spaceless' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Spaceless.php',
559
  'Twig_Node_Text' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Text.php',
560
  'Twig_Node_With' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/With.php',
561
  'Twig_Parser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Parser.php',
562
- 'Twig_ParserInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ParserInterface.php',
563
  'Twig_Profiler_Dumper_Base' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Base.php',
564
  'Twig_Profiler_Dumper_Blackfire' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php',
565
  'Twig_Profiler_Dumper_Html' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Html.php',
@@ -583,20 +578,12 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
583
  'Twig_Source' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Source.php',
584
  'Twig_SourceContextLoaderInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/SourceContextLoaderInterface.php',
585
  'Twig_Template' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Template.php',
586
- 'Twig_TemplateInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TemplateInterface.php',
587
  'Twig_TemplateWrapper' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TemplateWrapper.php',
588
  'Twig_Test' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test.php',
589
- 'Twig_TestCallableInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TestCallableInterface.php',
590
- 'Twig_TestInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TestInterface.php',
591
- 'Twig_Test_Function' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test/Function.php',
592
  'Twig_Test_IntegrationTestCase' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test/IntegrationTestCase.php',
593
- 'Twig_Test_Method' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test/Method.php',
594
- 'Twig_Test_Node' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test/Node.php',
595
  'Twig_Test_NodeTestCase' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test/NodeTestCase.php',
596
  'Twig_Token' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Token.php',
597
  'Twig_TokenParser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser.php',
598
- 'Twig_TokenParserBroker' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParserBroker.php',
599
- 'Twig_TokenParserBrokerInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParserBrokerInterface.php',
600
  'Twig_TokenParserInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParserInterface.php',
601
  'Twig_TokenParser_AutoEscape' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/AutoEscape.php',
602
  'Twig_TokenParser_Block' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Block.php',
@@ -625,11 +612,11 @@ class ComposerStaticInit1fb235bc74e35292d2b088681fade654
625
  public static function getInitializer(ClassLoader $loader)
626
  {
627
  return \Closure::bind(function () use ($loader) {
628
- $loader->prefixLengthsPsr4 = ComposerStaticInit1fb235bc74e35292d2b088681fade654::$prefixLengthsPsr4;
629
- $loader->prefixDirsPsr4 = ComposerStaticInit1fb235bc74e35292d2b088681fade654::$prefixDirsPsr4;
630
- $loader->fallbackDirsPsr4 = ComposerStaticInit1fb235bc74e35292d2b088681fade654::$fallbackDirsPsr4;
631
- $loader->prefixesPsr0 = ComposerStaticInit1fb235bc74e35292d2b088681fade654::$prefixesPsr0;
632
- $loader->classMap = ComposerStaticInit1fb235bc74e35292d2b088681fade654::$classMap;
633
 
634
  }, null, ClassLoader::class);
635
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit989702ef2dea046e4eae802005e7b013
8
  {
9
  public static $files = array (
10
+ '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
11
+ '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
12
  '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
13
  );
14
 
20
  ),
21
  'S' =>
22
  array (
23
+ 'Symfony\\Polyfill\\Php72\\' => 23,
24
+ 'Symfony\\Polyfill\\Mbstring\\' => 26,
25
  'Symfony\\Polyfill\\Ctype\\' => 23,
26
  ),
27
  'C' =>
39
  array (
40
  0 => __DIR__ . '/../..' . '/lib',
41
  ),
42
+ 'Symfony\\Polyfill\\Php72\\' =>
43
+ array (
44
+ 0 => __DIR__ . '/..' . '/symfony/polyfill-php72',
45
+ ),
46
+ 'Symfony\\Polyfill\\Mbstring\\' =>
47
+ array (
48
+ 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
49
+ ),
50
  'Symfony\\Polyfill\\Ctype\\' =>
51
  array (
52
  0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
82
  'AltoRouter' => __DIR__ . '/..' . '/altorouter/altorouter/AltoRouter.php',
83
  'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
84
  'Composer\\Installers\\AglInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AglInstaller.php',
85
+ 'Composer\\Installers\\AkauntingInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AkauntingInstaller.php',
86
  'Composer\\Installers\\AnnotateCmsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php',
87
  'Composer\\Installers\\AsgardInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AsgardInstaller.php',
88
  'Composer\\Installers\\AttogramInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AttogramInstaller.php',
96
  'Composer\\Installers\\CockpitInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CockpitInstaller.php',
97
  'Composer\\Installers\\CodeIgniterInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php',
98
  'Composer\\Installers\\Concrete5Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Concrete5Installer.php',
 
99
  'Composer\\Installers\\CroogoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CroogoInstaller.php',
100
  'Composer\\Installers\\DecibelInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DecibelInstaller.php',
101
  'Composer\\Installers\\DframeInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DframeInstaller.php',
113
  'Composer\\Installers\\ImageCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ImageCMSInstaller.php',
114
  'Composer\\Installers\\Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Installer.php',
115
  'Composer\\Installers\\ItopInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ItopInstaller.php',
 
116
  'Composer\\Installers\\KanboardInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KanboardInstaller.php',
 
117
  'Composer\\Installers\\KnownInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KnownInstaller.php',
118
  'Composer\\Installers\\KodiCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KodiCMSInstaller.php',
119
  'Composer\\Installers\\KohanaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KohanaInstaller.php',
127
  'Composer\\Installers\\MajimaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MajimaInstaller.php',
128
  'Composer\\Installers\\MakoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MakoInstaller.php',
129
  'Composer\\Installers\\MantisBTInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MantisBTInstaller.php',
130
+ 'Composer\\Installers\\MatomoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MatomoInstaller.php',
131
  'Composer\\Installers\\MauticInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MauticInstaller.php',
132
  'Composer\\Installers\\MayaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MayaInstaller.php',
133
  'Composer\\Installers\\MediaWikiInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MediaWikiInstaller.php',
143
  'Composer\\Installers\\PantheonInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PantheonInstaller.php',
144
  'Composer\\Installers\\PhiftyInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PhiftyInstaller.php',
145
  'Composer\\Installers\\PhpBBInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PhpBBInstaller.php',
 
146
  'Composer\\Installers\\PiwikInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PiwikInstaller.php',
147
  'Composer\\Installers\\PlentymarketsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php',
148
  'Composer\\Installers\\Plugin' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Plugin.php',
163
  'Composer\\Installers\\StarbugInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/StarbugInstaller.php',
164
  'Composer\\Installers\\SyDESInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SyDESInstaller.php',
165
  'Composer\\Installers\\SyliusInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SyliusInstaller.php',
 
 
 
166
  'Composer\\Installers\\TaoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TaoInstaller.php',
167
  'Composer\\Installers\\TastyIgniterInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php',
168
  'Composer\\Installers\\TheliaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TheliaInstaller.php',
179
  'Composer\\Installers\\ZikulaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ZikulaInstaller.php',
180
  'Routes' => __DIR__ . '/..' . '/upstatement/routes/Routes.php',
181
  'Symfony\\Polyfill\\Ctype\\Ctype' => __DIR__ . '/..' . '/symfony/polyfill-ctype/Ctype.php',
182
+ 'Symfony\\Polyfill\\Mbstring\\Mbstring' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/Mbstring.php',
183
+ 'Symfony\\Polyfill\\Php72\\Php72' => __DIR__ . '/..' . '/symfony/polyfill-php72/Php72.php',
184
  'Timber\\Admin' => __DIR__ . '/../..' . '/lib/Admin.php',
185
  'Timber\\Archives' => __DIR__ . '/../..' . '/lib/Archives.php',
186
  'Timber\\Cache\\Cleaner' => __DIR__ . '/../..' . '/lib/Cache/Cleaner.php',
261
  'Twig\\Error\\RuntimeError' => __DIR__ . '/..' . '/twig/twig/src/Error/RuntimeError.php',
262
  'Twig\\Error\\SyntaxError' => __DIR__ . '/..' . '/twig/twig/src/Error/SyntaxError.php',
263
  'Twig\\ExpressionParser' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser.php',
264
+ 'Twig\\ExtensionSet' => __DIR__ . '/..' . '/twig/twig/src/ExtensionSet.php',
265
  'Twig\\Extension\\AbstractExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/AbstractExtension.php',
266
  'Twig\\Extension\\CoreExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/CoreExtension.php',
267
  'Twig\\Extension\\DebugExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/DebugExtension.php',
287
  'Twig\\NodeTraverser' => __DIR__ . '/..' . '/twig/twig/src/NodeTraverser.php',
288
  'Twig\\NodeVisitor\\AbstractNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/AbstractNodeVisitor.php',
289
  'Twig\\NodeVisitor\\EscaperNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/EscaperNodeVisitor.php',
290
+ 'Twig\\NodeVisitor\\MacroAutoImportNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/MacroAutoImportNodeVisitor.php',
291
  'Twig\\NodeVisitor\\NodeVisitorInterface' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/NodeVisitorInterface.php',
292
  'Twig\\NodeVisitor\\OptimizerNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/OptimizerNodeVisitor.php',
293
  'Twig\\NodeVisitor\\SafeAnalysisNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php',
296
  'Twig\\Node\\BlockNode' => __DIR__ . '/..' . '/twig/twig/src/Node/BlockNode.php',
297
  'Twig\\Node\\BlockReferenceNode' => __DIR__ . '/..' . '/twig/twig/src/Node/BlockReferenceNode.php',
298
  'Twig\\Node\\BodyNode' => __DIR__ . '/..' . '/twig/twig/src/Node/BodyNode.php',
299
+ 'Twig\\Node\\CheckSecurityCallNode' => __DIR__ . '/..' . '/twig/twig/src/Node/CheckSecurityCallNode.php',
300
  'Twig\\Node\\CheckSecurityNode' => __DIR__ . '/..' . '/twig/twig/src/Node/CheckSecurityNode.php',
301
  'Twig\\Node\\CheckToStringNode' => __DIR__ . '/..' . '/twig/twig/src/Node/CheckToStringNode.php',
302
  'Twig\\Node\\DeprecatedNode' => __DIR__ . '/..' . '/twig/twig/src/Node/DeprecatedNode.php',
330
  'Twig\\Node\\Expression\\Binary\\OrBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/OrBinary.php',
331
  'Twig\\Node\\Expression\\Binary\\PowerBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/PowerBinary.php',
332
  'Twig\\Node\\Expression\\Binary\\RangeBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/RangeBinary.php',
333
+ 'Twig\\Node\\Expression\\Binary\\SpaceshipBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/SpaceshipBinary.php',
334
  'Twig\\Node\\Expression\\Binary\\StartsWithBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php',
335
  'Twig\\Node\\Expression\\Binary\\SubBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/SubBinary.php',
336
  'Twig\\Node\\Expression\\BlockReferenceExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/BlockReferenceExpression.php',
359
  'Twig\\Node\\Expression\\Unary\\NegUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/NegUnary.php',
360
  'Twig\\Node\\Expression\\Unary\\NotUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/NotUnary.php',
361
  'Twig\\Node\\Expression\\Unary\\PosUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/PosUnary.php',
362
+ 'Twig\\Node\\Expression\\VariadicExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/VariadicExpression.php',
363
  'Twig\\Node\\FlushNode' => __DIR__ . '/..' . '/twig/twig/src/Node/FlushNode.php',
364
  'Twig\\Node\\ForLoopNode' => __DIR__ . '/..' . '/twig/twig/src/Node/ForLoopNode.php',
365
  'Twig\\Node\\ForNode' => __DIR__ . '/..' . '/twig/twig/src/Node/ForNode.php',
375
  'Twig\\Node\\SandboxNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SandboxNode.php',
376
  'Twig\\Node\\SandboxedPrintNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SandboxedPrintNode.php',
377
  'Twig\\Node\\SetNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SetNode.php',
 
378
  'Twig\\Node\\SpacelessNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SpacelessNode.php',
379
  'Twig\\Node\\TextNode' => __DIR__ . '/..' . '/twig/twig/src/Node/TextNode.php',
380
  'Twig\\Node\\WithNode' => __DIR__ . '/..' . '/twig/twig/src/Node/WithNode.php',
432
  'Twig\\TwigTest' => __DIR__ . '/..' . '/twig/twig/src/TwigTest.php',
433
  'Twig\\Util\\DeprecationCollector' => __DIR__ . '/..' . '/twig/twig/src/Util/DeprecationCollector.php',
434
  'Twig\\Util\\TemplateDirIterator' => __DIR__ . '/..' . '/twig/twig/src/Util/TemplateDirIterator.php',
 
435
  'Twig_BaseNodeVisitor' => __DIR__ . '/..' . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
436
  'Twig_CacheInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/CacheInterface.php',
437
  'Twig_Cache_Filesystem' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Cache/Filesystem.php',
438
  'Twig_Cache_Null' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Cache/Null.php',
439
  'Twig_Compiler' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Compiler.php',
 
440
  'Twig_ContainerRuntimeLoader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ContainerRuntimeLoader.php',
441
  'Twig_Environment' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Environment.php',
442
  'Twig_Error' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Error.php',
447
  'Twig_ExpressionParser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ExpressionParser.php',
448
  'Twig_Extension' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension.php',
449
  'Twig_ExtensionInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ExtensionInterface.php',
450
+ 'Twig_ExtensionSet' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ExtensionSet.php',
451
  'Twig_Extension_Core' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Core.php',
452
  'Twig_Extension_Debug' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Debug.php',
453
  'Twig_Extension_Escaper' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Escaper.php',
461
  'Twig_FactoryRuntimeLoader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FactoryRuntimeLoader.php',
462
  'Twig_FileExtensionEscapingStrategy' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php',
463
  'Twig_Filter' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Filter.php',
 
 
 
 
 
464
  'Twig_Function' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Function.php',
 
 
 
 
 
465
  'Twig_Lexer' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Lexer.php',
 
466
  'Twig_LoaderInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/LoaderInterface.php',
467
  'Twig_Loader_Array' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Loader/Array.php',
468
  'Twig_Loader_Chain' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Loader/Chain.php',
469
  'Twig_Loader_Filesystem' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Loader/Filesystem.php',
 
470
  'Twig_Markup' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Markup.php',
471
  'Twig_Node' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node.php',
472
  'Twig_NodeCaptureInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeCaptureInterface.php',
 
473
  'Twig_NodeOutputInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeOutputInterface.php',
474
  'Twig_NodeTraverser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeTraverser.php',
475
  'Twig_NodeVisitorInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeVisitorInterface.php',
518
  'Twig_Node_Expression_Call' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Call.php',
519
  'Twig_Node_Expression_Conditional' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Conditional.php',
520
  'Twig_Node_Expression_Constant' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Constant.php',
 
521
  'Twig_Node_Expression_Filter' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Filter.php',
522
  'Twig_Node_Expression_Filter_Default' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Filter/Default.php',
523
  'Twig_Node_Expression_Function' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Function.php',
551
  'Twig_Node_Sandbox' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Sandbox.php',
552
  'Twig_Node_SandboxedPrint' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/SandboxedPrint.php',
553
  'Twig_Node_Set' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Set.php',
 
554
  'Twig_Node_Spaceless' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Spaceless.php',
555
  'Twig_Node_Text' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Text.php',
556
  'Twig_Node_With' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/With.php',
557
  'Twig_Parser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Parser.php',
 
558
  'Twig_Profiler_Dumper_Base' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Base.php',
559
  'Twig_Profiler_Dumper_Blackfire' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php',
560
  'Twig_Profiler_Dumper_Html' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Html.php',
578
  'Twig_Source' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Source.php',
579
  'Twig_SourceContextLoaderInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/SourceContextLoaderInterface.php',
580
  'Twig_Template' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Template.php',
 
581
  'Twig_TemplateWrapper' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TemplateWrapper.php',
582
  'Twig_Test' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test.php',
 
 
 
583
  'Twig_Test_IntegrationTestCase' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test/IntegrationTestCase.php',
 
 
584
  'Twig_Test_NodeTestCase' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test/NodeTestCase.php',
585
  'Twig_Token' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Token.php',
586
  'Twig_TokenParser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser.php',
 
 
587
  'Twig_TokenParserInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParserInterface.php',
588
  'Twig_TokenParser_AutoEscape' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/AutoEscape.php',
589
  'Twig_TokenParser_Block' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Block.php',
612
  public static function getInitializer(ClassLoader $loader)
613
  {
614
  return \Closure::bind(function () use ($loader) {
615
+ $loader->prefixLengthsPsr4 = ComposerStaticInit989702ef2dea046e4eae802005e7b013::$prefixLengthsPsr4;
616
+ $loader->prefixDirsPsr4 = ComposerStaticInit989702ef2dea046e4eae802005e7b013::$prefixDirsPsr4;
617
+ $loader->fallbackDirsPsr4 = ComposerStaticInit989702ef2dea046e4eae802005e7b013::$fallbackDirsPsr4;
618
+ $loader->prefixesPsr0 = ComposerStaticInit989702ef2dea046e4eae802005e7b013::$prefixesPsr0;
619
+ $loader->classMap = ComposerStaticInit989702ef2dea046e4eae802005e7b013::$classMap;
620
 
621
  }, null, ClassLoader::class);
622
  }
vendor/composer/installed.json CHANGED
@@ -65,41 +65,39 @@
65
  },
66
  {
67
  "name": "composer/installers",
68
- "version": "v1.12.0",
69
- "version_normalized": "1.12.0.0",
70
  "source": {
71
  "type": "git",
72
  "url": "https://github.com/composer/installers.git",
73
- "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19"
74
  },
75
  "dist": {
76
  "type": "zip",
77
- "url": "https://api.github.com/repos/composer/installers/zipball/d20a64ed3c94748397ff5973488761b22f6d3f19",
78
- "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19",
79
  "shasum": ""
80
  },
81
  "require": {
82
- "composer-plugin-api": "^1.0 || ^2.0"
83
- },
84
- "replace": {
85
- "roundcube/plugin-installer": "*",
86
- "shama/baton": "*"
87
  },
88
  "require-dev": {
89
  "composer/composer": "1.6.* || ^2.0",
90
  "composer/semver": "^1 || ^3",
91
  "phpstan/phpstan": "^0.12.55",
92
  "phpstan/phpstan-phpunit": "^0.12.16",
93
- "symfony/phpunit-bridge": "^4.2 || ^5",
94
- "symfony/process": "^2.3"
95
  },
96
- "time": "2021-09-13T08:19:44+00:00",
97
  "type": "composer-plugin",
98
  "extra": {
99
  "class": "Composer\\Installers\\Plugin",
100
  "branch-alias": {
101
- "dev-main": "1.x-dev"
102
- }
 
103
  },
104
  "installation-source": "dist",
105
  "autoload": {
@@ -121,7 +119,6 @@
121
  "description": "A multi-framework Composer library installer",
122
  "homepage": "https://composer.github.io/installers/",
123
  "keywords": [
124
- "Craft",
125
  "Dolibarr",
126
  "Eliasis",
127
  "Hurad",
@@ -142,7 +139,6 @@
142
  "Whmcs",
143
  "WolfCMS",
144
  "agl",
145
- "aimeos",
146
  "annotatecms",
147
  "attogram",
148
  "bitrix",
@@ -161,7 +157,6 @@
161
  "grav",
162
  "installer",
163
  "itop",
164
- "joomla",
165
  "known",
166
  "kohana",
167
  "laravel",
@@ -170,6 +165,7 @@
170
  "magento",
171
  "majima",
172
  "mako",
 
173
  "mediawiki",
174
  "miaoxing",
175
  "modulework",
@@ -189,9 +185,7 @@
189
  "silverstripe",
190
  "sydes",
191
  "sylius",
192
- "symfony",
193
  "tastyigniter",
194
- "typo3",
195
  "wordpress",
196
  "yawik",
197
  "zend",
@@ -199,7 +193,7 @@
199
  ],
200
  "support": {
201
  "issues": "https://github.com/composer/installers/issues",
202
- "source": "https://github.com/composer/installers/tree/v1.12.0"
203
  },
204
  "funding": [
205
  {
@@ -219,30 +213,33 @@
219
  },
220
  {
221
  "name": "symfony/polyfill-ctype",
222
- "version": "v1.19.0",
223
- "version_normalized": "1.19.0.0",
224
  "source": {
225
  "type": "git",
226
  "url": "https://github.com/symfony/polyfill-ctype.git",
227
- "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b"
228
  },
229
  "dist": {
230
  "type": "zip",
231
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/aed596913b70fae57be53d86faa2e9ef85a2297b",
232
- "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b",
233
  "shasum": ""
234
  },
235
  "require": {
236
- "php": ">=5.3.3"
 
 
 
237
  },
238
  "suggest": {
239
  "ext-ctype": "For best performance"
240
  },
241
- "time": "2020-10-23T09:01:57+00:00",
242
  "type": "library",
243
  "extra": {
244
  "branch-alias": {
245
- "dev-main": "1.19-dev"
246
  },
247
  "thanks": {
248
  "name": "symfony/polyfill",
@@ -281,7 +278,7 @@
281
  "portable"
282
  ],
283
  "support": {
284
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.19.0"
285
  },
286
  "funding": [
287
  {
@@ -299,6 +296,171 @@
299
  ],
300
  "install-path": "../symfony/polyfill-ctype"
301
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
  {
303
  "name": "twig/cache-extension",
304
  "version": "v1.5.0",
@@ -376,32 +538,34 @@
376
  },
377
  {
378
  "name": "twig/twig",
379
- "version": "v1.42.5",
380
- "version_normalized": "1.42.5.0",
381
  "source": {
382
  "type": "git",
383
  "url": "https://github.com/twigphp/Twig.git",
384
- "reference": "87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e"
385
  },
386
  "dist": {
387
  "type": "zip",
388
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e",
389
- "reference": "87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e",
390
  "shasum": ""
391
  },
392
  "require": {
393
- "php": ">=5.5.0",
394
- "symfony/polyfill-ctype": "^1.8"
 
 
395
  },
396
  "require-dev": {
397
  "psr/container": "^1.0",
398
- "symfony/phpunit-bridge": "^4.4|^5.0"
399
  },
400
- "time": "2020-02-11T05:59:23+00:00",
401
  "type": "library",
402
  "extra": {
403
  "branch-alias": {
404
- "dev-master": "1.42-dev"
405
  }
406
  },
407
  "installation-source": "dist",
@@ -441,8 +605,18 @@
441
  ],
442
  "support": {
443
  "issues": "https://github.com/twigphp/Twig/issues",
444
- "source": "https://github.com/twigphp/Twig/tree/1.x"
445
  },
 
 
 
 
 
 
 
 
 
 
446
  "install-path": "../twig/twig"
447
  },
448
  {
65
  },
66
  {
67
  "name": "composer/installers",
68
+ "version": "v2.2.0",
69
+ "version_normalized": "2.2.0.0",
70
  "source": {
71
  "type": "git",
72
  "url": "https://github.com/composer/installers.git",
73
+ "reference": "c29dc4b93137acb82734f672c37e029dfbd95b35"
74
  },
75
  "dist": {
76
  "type": "zip",
77
+ "url": "https://api.github.com/repos/composer/installers/zipball/c29dc4b93137acb82734f672c37e029dfbd95b35",
78
+ "reference": "c29dc4b93137acb82734f672c37e029dfbd95b35",
79
  "shasum": ""
80
  },
81
  "require": {
82
+ "composer-plugin-api": "^1.0 || ^2.0",
83
+ "php": "^7.2 || ^8.0"
 
 
 
84
  },
85
  "require-dev": {
86
  "composer/composer": "1.6.* || ^2.0",
87
  "composer/semver": "^1 || ^3",
88
  "phpstan/phpstan": "^0.12.55",
89
  "phpstan/phpstan-phpunit": "^0.12.16",
90
+ "symfony/phpunit-bridge": "^5.3",
91
+ "symfony/process": "^5"
92
  },
93
+ "time": "2022-08-20T06:45:11+00:00",
94
  "type": "composer-plugin",
95
  "extra": {
96
  "class": "Composer\\Installers\\Plugin",
97
  "branch-alias": {
98
+ "dev-main": "2.x-dev"
99
+ },
100
+ "plugin-modifies-install-path": true
101
  },
102
  "installation-source": "dist",
103
  "autoload": {
119
  "description": "A multi-framework Composer library installer",
120
  "homepage": "https://composer.github.io/installers/",
121
  "keywords": [
 
122
  "Dolibarr",
123
  "Eliasis",
124
  "Hurad",
139
  "Whmcs",
140
  "WolfCMS",
141
  "agl",
 
142
  "annotatecms",
143
  "attogram",
144
  "bitrix",
157
  "grav",
158
  "installer",
159
  "itop",
 
160
  "known",
161
  "kohana",
162
  "laravel",
165
  "magento",
166
  "majima",
167
  "mako",
168
+ "matomo",
169
  "mediawiki",
170
  "miaoxing",
171
  "modulework",
185
  "silverstripe",
186
  "sydes",
187
  "sylius",
 
188
  "tastyigniter",
 
189
  "wordpress",
190
  "yawik",
191
  "zend",
193
  ],
194
  "support": {
195
  "issues": "https://github.com/composer/installers/issues",
196
+ "source": "https://github.com/composer/installers/tree/v2.2.0"
197
  },
198
  "funding": [
199
  {
213
  },
214
  {
215
  "name": "symfony/polyfill-ctype",
216
+ "version": "v1.26.0",
217
+ "version_normalized": "1.26.0.0",
218
  "source": {
219
  "type": "git",
220
  "url": "https://github.com/symfony/polyfill-ctype.git",
221
+ "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4"
222
  },
223
  "dist": {
224
  "type": "zip",
225
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4",
226
+ "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4",
227
  "shasum": ""
228
  },
229
  "require": {
230
+ "php": ">=7.1"
231
+ },
232
+ "provide": {
233
+ "ext-ctype": "*"
234
  },
235
  "suggest": {
236
  "ext-ctype": "For best performance"
237
  },
238
+ "time": "2022-05-24T11:49:31+00:00",
239
  "type": "library",
240
  "extra": {
241
  "branch-alias": {
242
+ "dev-main": "1.26-dev"
243
  },
244
  "thanks": {
245
  "name": "symfony/polyfill",
278
  "portable"
279
  ],
280
  "support": {
281
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0"
282
  },
283
  "funding": [
284
  {
296
  ],
297
  "install-path": "../symfony/polyfill-ctype"
298
  },
299
+ {
300
+ "name": "symfony/polyfill-mbstring",
301
+ "version": "v1.26.0",
302
+ "version_normalized": "1.26.0.0",
303
+ "source": {
304
+ "type": "git",
305
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
306
+ "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e"
307
+ },
308
+ "dist": {
309
+ "type": "zip",
310
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
311
+ "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
312
+ "shasum": ""
313
+ },
314
+ "require": {
315
+ "php": ">=7.1"
316
+ },
317
+ "provide": {
318
+ "ext-mbstring": "*"
319
+ },
320
+ "suggest": {
321
+ "ext-mbstring": "For best performance"
322
+ },
323
+ "time": "2022-05-24T11:49:31+00:00",
324
+ "type": "library",
325
+ "extra": {
326
+ "branch-alias": {
327
+ "dev-main": "1.26-dev"
328
+ },
329
+ "thanks": {
330
+ "name": "symfony/polyfill",
331
+ "url": "https://github.com/symfony/polyfill"
332
+ }
333
+ },
334
+ "installation-source": "dist",
335
+ "autoload": {
336
+ "files": [
337
+ "bootstrap.php"
338
+ ],
339
+ "psr-4": {
340
+ "Symfony\\Polyfill\\Mbstring\\": ""
341
+ }
342
+ },
343
+ "notification-url": "https://packagist.org/downloads/",
344
+ "license": [
345
+ "MIT"
346
+ ],
347
+ "authors": [
348
+ {
349
+ "name": "Nicolas Grekas",
350
+ "email": "p@tchwork.com"
351
+ },
352
+ {
353
+ "name": "Symfony Community",
354
+ "homepage": "https://symfony.com/contributors"
355
+ }
356
+ ],
357
+ "description": "Symfony polyfill for the Mbstring extension",
358
+ "homepage": "https://symfony.com",
359
+ "keywords": [
360
+ "compatibility",
361
+ "mbstring",
362
+ "polyfill",
363
+ "portable",
364
+ "shim"
365
+ ],
366
+ "support": {
367
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0"
368
+ },
369
+ "funding": [
370
+ {
371
+ "url": "https://symfony.com/sponsor",
372
+ "type": "custom"
373
+ },
374
+ {
375
+ "url": "https://github.com/fabpot",
376
+ "type": "github"
377
+ },
378
+ {
379
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
380
+ "type": "tidelift"
381
+ }
382
+ ],
383
+ "install-path": "../symfony/polyfill-mbstring"
384
+ },
385
+ {
386
+ "name": "symfony/polyfill-php72",
387
+ "version": "v1.26.0",
388
+ "version_normalized": "1.26.0.0",
389
+ "source": {
390
+ "type": "git",
391
+ "url": "https://github.com/symfony/polyfill-php72.git",
392
+ "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2"
393
+ },
394
+ "dist": {
395
+ "type": "zip",
396
+ "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2",
397
+ "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2",
398
+ "shasum": ""
399
+ },
400
+ "require": {
401
+ "php": ">=7.1"
402
+ },
403
+ "time": "2022-05-24T11:49:31+00:00",
404
+ "type": "library",
405
+ "extra": {
406
+ "branch-alias": {
407
+ "dev-main": "1.26-dev"
408
+ },
409
+ "thanks": {
410
+ "name": "symfony/polyfill",
411
+ "url": "https://github.com/symfony/polyfill"
412
+ }
413
+ },
414
+ "installation-source": "dist",
415
+ "autoload": {
416
+ "files": [
417
+ "bootstrap.php"
418
+ ],
419
+ "psr-4": {
420
+ "Symfony\\Polyfill\\Php72\\": ""
421
+ }
422
+ },
423
+ "notification-url": "https://packagist.org/downloads/",
424
+ "license": [
425
+ "MIT"
426
+ ],
427
+ "authors": [
428
+ {
429
+ "name": "Nicolas Grekas",
430
+ "email": "p@tchwork.com"
431
+ },
432
+ {
433
+ "name": "Symfony Community",
434
+ "homepage": "https://symfony.com/contributors"
435
+ }
436
+ ],
437
+ "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
438
+ "homepage": "https://symfony.com",
439
+ "keywords": [
440
+ "compatibility",
441
+ "polyfill",
442
+ "portable",
443
+ "shim"
444
+ ],
445
+ "support": {
446
+ "source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0"
447
+ },
448
+ "funding": [
449
+ {
450
+ "url": "https://symfony.com/sponsor",
451
+ "type": "custom"
452
+ },
453
+ {
454
+ "url": "https://github.com/fabpot",
455
+ "type": "github"
456
+ },
457
+ {
458
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
459
+ "type": "tidelift"
460
+ }
461
+ ],
462
+ "install-path": "../symfony/polyfill-php72"
463
+ },
464
  {
465
  "name": "twig/cache-extension",
466
  "version": "v1.5.0",
538
  },
539
  {
540
  "name": "twig/twig",
541
+ "version": "v2.15.3",
542
+ "version_normalized": "2.15.3.0",
543
  "source": {
544
  "type": "git",
545
  "url": "https://github.com/twigphp/Twig.git",
546
+ "reference": "ab402673db8746cb3a4c46f3869d6253699f614a"
547
  },
548
  "dist": {
549
  "type": "zip",
550
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/ab402673db8746cb3a4c46f3869d6253699f614a",
551
+ "reference": "ab402673db8746cb3a4c46f3869d6253699f614a",
552
  "shasum": ""
553
  },
554
  "require": {
555
+ "php": ">=7.1.3",
556
+ "symfony/polyfill-ctype": "^1.8",
557
+ "symfony/polyfill-mbstring": "^1.3",
558
+ "symfony/polyfill-php72": "^1.8"
559
  },
560
  "require-dev": {
561
  "psr/container": "^1.0",
562
+ "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0"
563
  },
564
+ "time": "2022-09-28T08:40:08+00:00",
565
  "type": "library",
566
  "extra": {
567
  "branch-alias": {
568
+ "dev-master": "2.15-dev"
569
  }
570
  },
571
  "installation-source": "dist",
605
  ],
606
  "support": {
607
  "issues": "https://github.com/twigphp/Twig/issues",
608
+ "source": "https://github.com/twigphp/Twig/tree/v2.15.3"
609
  },
610
+ "funding": [
611
+ {
612
+ "url": "https://github.com/fabpot",
613
+ "type": "github"
614
+ },
615
+ {
616
+ "url": "https://tidelift.com/funding/github/packagist/twig/twig",
617
+ "type": "tidelift"
618
+ }
619
+ ],
620
  "install-path": "../twig/twig"
621
  },
622
  {
vendor/composer/installed.php CHANGED
@@ -1,12 +1,12 @@
1
  <?php return array (
2
  'root' =>
3
  array (
4
- 'pretty_version' => '1.20.0.x-dev',
5
- 'version' => '1.20.0.9999999-dev',
6
  'aliases' =>
7
  array (
8
  ),
9
- 'reference' => '3ac8c7629656009b9e0d6d9e4ccda202aad3b8e0',
10
  'name' => 'timber/timber',
11
  ),
12
  'versions' =>
@@ -22,44 +22,48 @@
22
  ),
23
  'composer/installers' =>
24
  array (
25
- 'pretty_version' => 'v1.12.0',
26
- 'version' => '1.12.0.0',
27
  'aliases' =>
28
  array (
29
  ),
30
- 'reference' => 'd20a64ed3c94748397ff5973488761b22f6d3f19',
31
  ),
32
- 'roundcube/plugin-installer' =>
33
  array (
34
- 'replaced' =>
 
 
35
  array (
36
- 0 => '*',
37
  ),
 
38
  ),
39
- 'shama/baton' =>
40
  array (
41
- 'replaced' =>
 
 
42
  array (
43
- 0 => '*',
44
  ),
 
45
  ),
46
- 'symfony/polyfill-ctype' =>
47
  array (
48
- 'pretty_version' => 'v1.19.0',
49
- 'version' => '1.19.0.0',
50
  'aliases' =>
51
  array (
52
  ),
53
- 'reference' => 'aed596913b70fae57be53d86faa2e9ef85a2297b',
54
  ),
55
  'timber/timber' =>
56
  array (
57
- 'pretty_version' => '1.20.0.x-dev',
58
- 'version' => '1.20.0.9999999-dev',
59
  'aliases' =>
60
  array (
61
  ),
62
- 'reference' => '3ac8c7629656009b9e0d6d9e4ccda202aad3b8e0',
63
  ),
64
  'twig/cache-extension' =>
65
  array (
@@ -72,12 +76,12 @@
72
  ),
73
  'twig/twig' =>
74
  array (
75
- 'pretty_version' => 'v1.42.5',
76
- 'version' => '1.42.5.0',
77
  'aliases' =>
78
  array (
79
  ),
80
- 'reference' => '87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e',
81
  ),
82
  'upstatement/routes' =>
83
  array (
1
  <?php return array (
2
  'root' =>
3
  array (
4
+ 'pretty_version' => '1.21.0.x-dev',
5
+ 'version' => '1.21.0.9999999-dev',
6
  'aliases' =>
7
  array (
8
  ),
9
+ 'reference' => '342007fffa62b89c7d0c345914ac61482e4fe939',
10
  'name' => 'timber/timber',
11
  ),
12
  'versions' =>
22
  ),
23
  'composer/installers' =>
24
  array (
25
+ 'pretty_version' => 'v2.2.0',
26
+ 'version' => '2.2.0.0',
27
  'aliases' =>
28
  array (
29
  ),
30
+ 'reference' => 'c29dc4b93137acb82734f672c37e029dfbd95b35',
31
  ),
32
+ 'symfony/polyfill-ctype' =>
33
  array (
34
+ 'pretty_version' => 'v1.26.0',
35
+ 'version' => '1.26.0.0',
36
+ 'aliases' =>
37
  array (
 
38
  ),
39
+ 'reference' => '6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4',
40
  ),
41
+ 'symfony/polyfill-mbstring' =>
42
  array (
43
+ 'pretty_version' => 'v1.26.0',
44
+ 'version' => '1.26.0.0',
45
+ 'aliases' =>
46
  array (
 
47
  ),
48
+ 'reference' => '9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e',
49
  ),
50
+ 'symfony/polyfill-php72' =>
51
  array (
52
+ 'pretty_version' => 'v1.26.0',
53
+ 'version' => '1.26.0.0',
54
  'aliases' =>
55
  array (
56
  ),
57
+ 'reference' => 'bf44a9fd41feaac72b074de600314a93e2ae78e2',
58
  ),
59
  'timber/timber' =>
60
  array (
61
+ 'pretty_version' => '1.21.0.x-dev',
62
+ 'version' => '1.21.0.9999999-dev',
63
  'aliases' =>
64
  array (
65
  ),
66
+ 'reference' => '342007fffa62b89c7d0c345914ac61482e4fe939',
67
  ),
68
  'twig/cache-extension' =>
69
  array (
76
  ),
77
  'twig/twig' =>
78
  array (
79
+ 'pretty_version' => 'v2.15.3',
80
+ 'version' => '2.15.3.0',
81
  'aliases' =>
82
  array (
83
  ),
84
+ 'reference' => 'ab402673db8746cb3a4c46f3869d6253699f614a',
85
  ),
86
  'upstatement/routes' =>
87
  array (
vendor/composer/installers/.github/workflows/continuous-integration.yml CHANGED
@@ -17,12 +17,6 @@ jobs:
17
  strategy:
18
  matrix:
19
  php-version:
20
- - "5.3"
21
- - "5.4"
22
- - "5.5"
23
- - "5.6"
24
- - "7.0"
25
- - "7.1"
26
  - "7.2"
27
  - "7.3"
28
  - "7.4"
@@ -30,7 +24,7 @@ jobs:
30
  - "8.1"
31
  dependencies: [locked]
32
  include:
33
- - php-version: "5.3"
34
  dependencies: lowest
35
  - php-version: "8.1"
36
  dependencies: lowest
@@ -61,16 +55,8 @@ jobs:
61
  if: "contains(matrix.dependencies, 'lowest')"
62
  run: "echo \"COMPOSER_FLAGS=$COMPOSER_FLAGS --prefer-lowest\" >> $GITHUB_ENV"
63
 
64
- - name: "Upgrade phpunit-bridge if needed for php 8 lowest build"
65
- if: "contains(matrix.php-version, '8.')"
66
- run: |
67
- composer require symfony/phpunit-bridge:^5.3.3 --dev --no-update
68
-
69
  - name: "Install latest dependencies"
70
- run: |
71
- # Remove PHPStan as it requires a newer PHP
72
- composer remove phpstan/phpstan phpstan/phpstan-phpunit --dev --no-update
73
- composer update ${{ env.COMPOSER_FLAGS }}
74
 
75
  - name: "Run tests"
76
  run: "vendor/bin/simple-phpunit --verbose"
17
  strategy:
18
  matrix:
19
  php-version:
 
 
 
 
 
 
20
  - "7.2"
21
  - "7.3"
22
  - "7.4"
24
  - "8.1"
25
  dependencies: [locked]
26
  include:
27
+ - php-version: "7.2"
28
  dependencies: lowest
29
  - php-version: "8.1"
30
  dependencies: lowest
55
  if: "contains(matrix.dependencies, 'lowest')"
56
  run: "echo \"COMPOSER_FLAGS=$COMPOSER_FLAGS --prefer-lowest\" >> $GITHUB_ENV"
57
 
 
 
 
 
 
58
  - name: "Install latest dependencies"
59
+ run: "composer update ${{ env.COMPOSER_FLAGS }}"
 
 
 
60
 
61
  - name: "Run tests"
62
  run: "vendor/bin/simple-phpunit --verbose"
vendor/composer/installers/.github/workflows/lint.yml CHANGED
@@ -13,8 +13,8 @@ jobs:
13
  strategy:
14
  matrix:
15
  php-version:
16
- - "5.3"
17
- - "8.0"
18
 
19
  steps:
20
  - name: "Checkout"
13
  strategy:
14
  matrix:
15
  php-version:
16
+ - "7.2"
17
+ - "latest"
18
 
19
  steps:
20
  - name: "Checkout"
vendor/composer/installers/.github/workflows/phpstan.yml CHANGED
@@ -17,8 +17,7 @@ jobs:
17
  strategy:
18
  matrix:
19
  php-version:
20
- # pinned to 7.4 because we need PHPUnit 7.5 which does not support PHP 8
21
- - "7.4"
22
 
23
  steps:
24
  - name: "Checkout"
@@ -45,7 +44,6 @@ jobs:
45
  run: "composer update ${{ env.COMPOSER_FLAGS }}"
46
 
47
  - name: Run PHPStan
48
- # Locked to phpunit 7.5 here as newer ones have void return types which break inheritance
49
  run: |
50
- composer require --dev phpunit/phpunit:^7.5.20 --with-all-dependencies ${{ env.COMPOSER_FLAGS }}
51
  vendor/bin/phpstan analyse
17
  strategy:
18
  matrix:
19
  php-version:
20
+ - "8.0"
 
21
 
22
  steps:
23
  - name: "Checkout"
44
  run: "composer update ${{ env.COMPOSER_FLAGS }}"
45
 
46
  - name: Run PHPStan
 
47
  run: |
48
+ composer require --dev phpunit/phpunit:^8.5.18 --with-all-dependencies ${{ env.COMPOSER_FLAGS }}
49
  vendor/bin/phpstan analyse
vendor/composer/installers/composer.json CHANGED
@@ -5,7 +5,6 @@
5
  "description": "A multi-framework Composer library installer",
6
  "keywords": [
7
  "installer",
8
- "Aimeos",
9
  "AGL",
10
  "AnnotateCms",
11
  "Attogram",
@@ -15,7 +14,6 @@
15
  "Cockpit",
16
  "CodeIgniter",
17
  "concrete5",
18
- "Craft",
19
  "Croogo",
20
  "DokuWiki",
21
  "Dolibarr",
@@ -29,7 +27,6 @@
29
  "Hurad",
30
  "ImageCMS",
31
  "iTop",
32
- "Joomla",
33
  "Kanboard",
34
  "Known",
35
  "Kohana",
@@ -41,6 +38,7 @@
41
  "majima",
42
  "Mako",
43
  "MantisBT",
 
44
  "Mautic",
45
  "Maya",
46
  "MODX",
@@ -69,10 +67,8 @@
69
  "Starbug",
70
  "SyDES",
71
  "Sylius",
72
- "symfony",
73
  "TastyIgniter",
74
  "Thelia",
75
- "TYPO3",
76
  "WHMCS",
77
  "WolfCMS",
78
  "WordPress",
@@ -97,26 +93,24 @@
97
  "extra": {
98
  "class": "Composer\\Installers\\Plugin",
99
  "branch-alias": {
100
- "dev-main": "1.x-dev"
101
- }
102
- },
103
- "replace": {
104
- "shama/baton": "*",
105
- "roundcube/plugin-installer": "*"
106
  },
107
  "require": {
 
108
  "composer-plugin-api": "^1.0 || ^2.0"
109
  },
110
  "require-dev": {
111
  "composer/composer": "1.6.* || ^2.0",
112
  "composer/semver": "^1 || ^3",
113
- "symfony/phpunit-bridge": "^4.2 || ^5",
114
  "phpstan/phpstan": "^0.12.55",
115
- "symfony/process": "^2.3",
116
  "phpstan/phpstan-phpunit": "^0.12.16"
117
  },
118
  "scripts": {
119
- "test": "SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT=1 vendor/bin/simple-phpunit",
120
  "phpstan": "vendor/bin/phpstan analyse"
121
  }
122
  }
5
  "description": "A multi-framework Composer library installer",
6
  "keywords": [
7
  "installer",
 
8
  "AGL",
9
  "AnnotateCms",
10
  "Attogram",
14
  "Cockpit",
15
  "CodeIgniter",
16
  "concrete5",
 
17
  "Croogo",
18
  "DokuWiki",
19
  "Dolibarr",
27
  "Hurad",
28
  "ImageCMS",
29
  "iTop",
 
30
  "Kanboard",
31
  "Known",
32
  "Kohana",
38
  "majima",
39
  "Mako",
40
  "MantisBT",
41
+ "Matomo",
42
  "Mautic",
43
  "Maya",
44
  "MODX",
67
  "Starbug",
68
  "SyDES",
69
  "Sylius",
 
70
  "TastyIgniter",
71
  "Thelia",
 
72
  "WHMCS",
73
  "WolfCMS",
74
  "WordPress",
93
  "extra": {
94
  "class": "Composer\\Installers\\Plugin",
95
  "branch-alias": {
96
+ "dev-main": "2.x-dev"
97
+ },
98
+ "plugin-modifies-install-path": true
 
 
 
99
  },
100
  "require": {
101
+ "php": "^7.2 || ^8.0",
102
  "composer-plugin-api": "^1.0 || ^2.0"
103
  },
104
  "require-dev": {
105
  "composer/composer": "1.6.* || ^2.0",
106
  "composer/semver": "^1 || ^3",
107
+ "symfony/phpunit-bridge": "^5.3",
108
  "phpstan/phpstan": "^0.12.55",
109
+ "symfony/process": "^5",
110
  "phpstan/phpstan-phpunit": "^0.12.16"
111
  },
112
  "scripts": {
113
+ "test": "vendor/bin/simple-phpunit",
114
  "phpstan": "vendor/bin/phpstan analyse"
115
  }
116
  }
vendor/composer/installers/phpstan.neon.dist CHANGED
@@ -1,10 +1,12 @@
1
  parameters:
2
- level: 5
3
  paths:
4
  - src
5
  - tests
6
  excludes_analyse:
7
  - tests/Composer/Installers/Test/PolyfillTestCase.php
 
 
8
 
9
  includes:
10
  - vendor/phpstan/phpstan-phpunit/extension.neon
1
  parameters:
2
+ level: 8
3
  paths:
4
  - src
5
  - tests
6
  excludes_analyse:
7
  - tests/Composer/Installers/Test/PolyfillTestCase.php
8
+ ignoreErrors:
9
+ - '~Test::[a-zA-Z0-9]+Provider\(\) return type~'
10
 
11
  includes:
12
  - vendor/phpstan/phpstan-phpunit/extension.neon
vendor/composer/installers/src/Composer/Installers/AglInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class AglInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'More/{$name}/',
8
  );
@@ -10,12 +12,18 @@ class AglInstaller extends BaseInstaller
10
  /**
11
  * Format package name to CamelCase
12
  */
13
- public function inflectPackageVars($vars)
14
  {
15
- $vars['name'] = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) {
16
  return strtoupper($matches[1]);
17
  }, $vars['name']);
18
 
 
 
 
 
 
 
19
  return $vars;
20
  }
21
  }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class AglInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'More/{$name}/',
10
  );
12
  /**
13
  * Format package name to CamelCase
14
  */
15
+ public function inflectPackageVars(array $vars): array
16
  {
17
+ $name = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) {
18
  return strtoupper($matches[1]);
19
  }, $vars['name']);
20
 
21
+ if (null === $name) {
22
+ throw new \RuntimeException('Failed to run preg_replace_callback: '.preg_last_error());
23
+ }
24
+
25
+ $vars['name'] = $name;
26
+
27
  return $vars;
28
  }
29
  }
vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php DELETED
@@ -1,9 +0,0 @@
1
- <?php
2
- namespace Composer\Installers;
3
-
4
- class AimeosInstaller extends BaseInstaller
5
- {
6
- protected $locations = array(
7
- 'extension' => 'ext/{$name}/',
8
- );
9
- }
 
 
 
 
 
 
 
 
 
vendor/composer/installers/src/Composer/Installers/AkauntingInstaller.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Composer\Installers;
4
+
5
+ class AkauntingInstaller extends BaseInstaller
6
+ {
7
+ /** @var array<string, string> */
8
+ protected $locations = array(
9
+ 'module' => 'modules/{$name}',
10
+ );
11
+
12
+ /**
13
+ * Format package name to CamelCase
14
+ */
15
+ public function inflectPackageVars(array $vars): array
16
+ {
17
+ $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
18
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
19
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
20
+
21
+ return $vars;
22
+ }
23
+ }
vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class AnnotateCmsInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'addons/modules/{$name}/',
8
  'component' => 'addons/components/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class AnnotateCmsInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'addons/modules/{$name}/',
10
  'component' => 'addons/components/{$name}/',
vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class AsgardInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'Modules/{$name}/',
8
  'theme' => 'Themes/{$name}/'
@@ -14,9 +16,8 @@ class AsgardInstaller extends BaseInstaller
14
  * For package type asgard-module, cut off a trailing '-plugin' if present.
15
  *
16
  * For package type asgard-theme, cut off a trailing '-theme' if present.
17
- *
18
  */
19
- public function inflectPackageVars($vars)
20
  {
21
  if ($vars['type'] === 'asgard-module') {
22
  return $this->inflectPluginVars($vars);
@@ -29,18 +30,26 @@ class AsgardInstaller extends BaseInstaller
29
  return $vars;
30
  }
31
 
32
- protected function inflectPluginVars($vars)
 
 
 
 
33
  {
34
- $vars['name'] = preg_replace('/-module$/', '', $vars['name']);
35
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
36
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
37
 
38
  return $vars;
39
  }
40
 
41
- protected function inflectThemeVars($vars)
 
 
 
 
42
  {
43
- $vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
44
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
45
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
46
 
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class AsgardInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'Modules/{$name}/',
10
  'theme' => 'Themes/{$name}/'
16
  * For package type asgard-module, cut off a trailing '-plugin' if present.
17
  *
18
  * For package type asgard-theme, cut off a trailing '-theme' if present.
 
19
  */
20
+ public function inflectPackageVars(array $vars): array
21
  {
22
  if ($vars['type'] === 'asgard-module') {
23
  return $this->inflectPluginVars($vars);
30
  return $vars;
31
  }
32
 
33
+ /**
34
+ * @param array<string, string> $vars
35
+ * @return array<string, string>
36
+ */
37
+ protected function inflectPluginVars(array $vars): array
38
  {
39
+ $vars['name'] = $this->pregReplace('/-module$/', '', $vars['name']);
40
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
41
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
42
 
43
  return $vars;
44
  }
45
 
46
+ /**
47
+ * @param array<string, string> $vars
48
+ * @return array<string, string>
49
+ */
50
+ protected function inflectThemeVars(array $vars): array
51
  {
52
+ $vars['name'] = $this->pregReplace('/-theme$/', '', $vars['name']);
53
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
54
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
55
 
vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class AttogramInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'modules/{$name}/',
8
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class AttogramInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'modules/{$name}/',
10
  );
vendor/composer/installers/src/Composer/Installers/BaseInstaller.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  use Composer\IO\IOInterface;
@@ -7,19 +8,19 @@ use Composer\Package\PackageInterface;
7
 
8
  abstract class BaseInstaller
9
  {
 
10
  protected $locations = array();
 
11
  protected $composer;
 
12
  protected $package;
 
13
  protected $io;
14
 
15
  /**
16
  * Initializes base installer.
17
- *
18
- * @param PackageInterface $package
19
- * @param Composer $composer
20
- * @param IOInterface $io
21
  */
22
- public function __construct(PackageInterface $package = null, Composer $composer = null, IOInterface $io = null)
23
  {
24
  $this->composer = $composer;
25
  $this->package = $package;
@@ -28,12 +29,8 @@ abstract class BaseInstaller
28
 
29
  /**
30
  * Return the install path based on package type.
31
- *
32
- * @param PackageInterface $package
33
- * @param string $frameworkType
34
- * @return string
35
  */
36
- public function getInstallPath(PackageInterface $package, $frameworkType = '')
37
  {
38
  $type = $this->package->getType();
39
 
@@ -52,18 +49,16 @@ abstract class BaseInstaller
52
  $availableVars['name'] = $extra['installer-name'];
53
  }
54
 
55
- if ($this->composer->getPackage()) {
56
- $extra = $this->composer->getPackage()->getExtra();
57
- if (!empty($extra['installer-paths'])) {
58
- $customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor);
59
- if ($customPath !== false) {
60
- return $this->templatePath($customPath, $availableVars);
61
- }
62
  }
63
  }
64
 
65
  $packageType = substr($type, strlen($frameworkType) + 1);
66
- $locations = $this->getLocations();
67
  if (!isset($locations[$packageType])) {
68
  throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type));
69
  }
@@ -77,7 +72,7 @@ abstract class BaseInstaller
77
  * @param array<string, string> $vars This will normally receive array{name: string, vendor: string, type: string}
78
  * @return array<string, string>
79
  */
80
- public function inflectPackageVars($vars)
81
  {
82
  return $vars;
83
  }
@@ -87,7 +82,7 @@ abstract class BaseInstaller
87
  *
88
  * @return array<string, string> map of package types => install path
89
  */
90
- public function getLocations()
91
  {
92
  return $this->locations;
93
  }
@@ -95,11 +90,9 @@ abstract class BaseInstaller
95
  /**
96
  * Replace vars in a path
97
  *
98
- * @param string $path
99
  * @param array<string, string> $vars
100
- * @return string
101
  */
102
- protected function templatePath($path, array $vars = array())
103
  {
104
  if (strpos($path, '{') !== false) {
105
  extract($vars);
@@ -117,13 +110,10 @@ abstract class BaseInstaller
117
  /**
118
  * Search through a passed paths array for a custom install path.
119
  *
120
- * @param array $paths
121
- * @param string $name
122
- * @param string $type
123
- * @param string $vendor = NULL
124
  * @return string|false
125
  */
126
- protected function mapCustomInstallPaths(array $paths, $name, $type, $vendor = NULL)
127
  {
128
  foreach ($paths as $path => $names) {
129
  $names = (array) $names;
@@ -134,4 +124,14 @@ abstract class BaseInstaller
134
 
135
  return false;
136
  }
 
 
 
 
 
 
 
 
 
 
137
  }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  use Composer\IO\IOInterface;
8
 
9
  abstract class BaseInstaller
10
  {
11
+ /** @var array<string, string> */
12
  protected $locations = array();
13
+ /** @var Composer */
14
  protected $composer;
15
+ /** @var PackageInterface */
16
  protected $package;
17
+ /** @var IOInterface */
18
  protected $io;
19
 
20
  /**
21
  * Initializes base installer.
 
 
 
 
22
  */
23
+ public function __construct(PackageInterface $package, Composer $composer, IOInterface $io)
24
  {
25
  $this->composer = $composer;
26
  $this->package = $package;
29
 
30
  /**
31
  * Return the install path based on package type.
 
 
 
 
32
  */
33
+ public function getInstallPath(PackageInterface $package, string $frameworkType = ''): string
34
  {
35
  $type = $this->package->getType();
36
 
49
  $availableVars['name'] = $extra['installer-name'];
50
  }
51
 
52
+ $extra = $this->composer->getPackage()->getExtra();
53
+ if (!empty($extra['installer-paths'])) {
54
+ $customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor);
55
+ if ($customPath !== false) {
56
+ return $this->templatePath($customPath, $availableVars);
 
 
57
  }
58
  }
59
 
60
  $packageType = substr($type, strlen($frameworkType) + 1);
61
+ $locations = $this->getLocations($frameworkType);
62
  if (!isset($locations[$packageType])) {
63
  throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type));
64
  }
72
  * @param array<string, string> $vars This will normally receive array{name: string, vendor: string, type: string}
73
  * @return array<string, string>
74
  */
75
+ public function inflectPackageVars(array $vars): array
76
  {
77
  return $vars;
78
  }
82
  *
83
  * @return array<string, string> map of package types => install path
84
  */
85
+ public function getLocations(string $frameworkType)
86
  {
87
  return $this->locations;
88
  }
90
  /**
91
  * Replace vars in a path
92
  *
 
93
  * @param array<string, string> $vars
 
94
  */
95
+ protected function templatePath(string $path, array $vars = array()): string
96
  {
97
  if (strpos($path, '{') !== false) {
98
  extract($vars);
110
  /**
111
  * Search through a passed paths array for a custom install path.
112
  *
113
+ * @param array<string, string[]|string> $paths
 
 
 
114
  * @return string|false
115
  */
116
+ protected function mapCustomInstallPaths(array $paths, string $name, string $type, ?string $vendor = null)
117
  {
118
  foreach ($paths as $path => $names) {
119
  $names = (array) $names;
124
 
125
  return false;
126
  }
127
+
128
+ protected function pregReplace(string $pattern, string $replacement, string $subject): string
129
+ {
130
+ $result = preg_replace($pattern, $replacement, $subject);
131
+ if (null === $result) {
132
+ throw new \RuntimeException('Failed to run preg_replace with '.$pattern.': '.preg_last_error());
133
+ }
134
+
135
+ return $result;
136
+ }
137
  }
vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php CHANGED
@@ -9,9 +9,9 @@ use Composer\Util\Filesystem;
9
  * - `bitrix-d7-module` — copy the module to directory `bitrix/modules/<vendor>.<name>`.
10
  * - `bitrix-d7-component` — copy the component to directory `bitrix/components/<vendor>/<name>`.
11
  * - `bitrix-d7-template` — copy the template to directory `bitrix/templates/<vendor>_<name>`.
12
- *
13
  * You can set custom path to directory with Bitrix kernel in `composer.json`:
14
- *
15
  * ```json
16
  * {
17
  * "extra": {
@@ -25,6 +25,7 @@ use Composer\Util\Filesystem;
25
  */
26
  class BitrixInstaller extends BaseInstaller
27
  {
 
28
  protected $locations = array(
29
  'module' => '{$bitrix_dir}/modules/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
30
  'component' => '{$bitrix_dir}/components/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
@@ -35,15 +36,13 @@ class BitrixInstaller extends BaseInstaller
35
  );
36
 
37
  /**
38
- * @var array Storage for informations about duplicates at all the time of installation packages.
39
  */
40
  private static $checkedDuplicates = array();
41
 
42
- /**
43
- * {@inheritdoc}
44
- */
45
- public function inflectPackageVars($vars)
46
  {
 
47
  if ($this->composer->getPackage()) {
48
  $extra = $this->composer->getPackage()->getExtra();
49
 
@@ -62,7 +61,7 @@ class BitrixInstaller extends BaseInstaller
62
  /**
63
  * {@inheritdoc}
64
  */
65
- protected function templatePath($path, array $vars = array())
66
  {
67
  $templatePath = parent::templatePath($path, $vars);
68
  $this->checkDuplicates($templatePath, $vars);
@@ -73,10 +72,9 @@ class BitrixInstaller extends BaseInstaller
73
  /**
74
  * Duplicates search packages.
75
  *
76
- * @param string $path
77
- * @param array $vars
78
  */
79
- protected function checkDuplicates($path, array $vars = array())
80
  {
81
  $packageType = substr($vars['type'], strlen('bitrix') + 1);
82
  $localDir = explode('/', $vars['bitrix_dir']);
@@ -94,8 +92,7 @@ class BitrixInstaller extends BaseInstaller
94
  return;
95
  }
96
 
97
- if ($oldPath !== $path && file_exists($oldPath) && $this->io && $this->io->isInteractive()) {
98
-
99
  $this->io->writeError(' <error>Duplication of packages:</error>');
100
  $this->io->writeError(' <info>Package ' . $oldPath . ' will be called instead package ' . $path . '</info>');
101
 
9
  * - `bitrix-d7-module` — copy the module to directory `bitrix/modules/<vendor>.<name>`.
10
  * - `bitrix-d7-component` — copy the component to directory `bitrix/components/<vendor>/<name>`.
11
  * - `bitrix-d7-template` — copy the template to directory `bitrix/templates/<vendor>_<name>`.
12
+ *
13
  * You can set custom path to directory with Bitrix kernel in `composer.json`:
14
+ *
15
  * ```json
16
  * {
17
  * "extra": {
25
  */
26
  class BitrixInstaller extends BaseInstaller
27
  {
28
+ /** @var array<string, string> */
29
  protected $locations = array(
30
  'module' => '{$bitrix_dir}/modules/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
31
  'component' => '{$bitrix_dir}/components/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
36
  );
37
 
38
  /**
39
+ * @var string[] Storage for informations about duplicates at all the time of installation packages.
40
  */
41
  private static $checkedDuplicates = array();
42
 
43
+ public function inflectPackageVars(array $vars): array
 
 
 
44
  {
45
+ /** @phpstan-ignore-next-line */
46
  if ($this->composer->getPackage()) {
47
  $extra = $this->composer->getPackage()->getExtra();
48
 
61
  /**
62
  * {@inheritdoc}
63
  */
64
+ protected function templatePath(string $path, array $vars = array()): string
65
  {
66
  $templatePath = parent::templatePath($path, $vars);
67
  $this->checkDuplicates($templatePath, $vars);
72
  /**
73
  * Duplicates search packages.
74
  *
75
+ * @param array<string, string> $vars
 
76
  */
77
+ protected function checkDuplicates(string $path, array $vars = array()): void
78
  {
79
  $packageType = substr($vars['type'], strlen('bitrix') + 1);
80
  $localDir = explode('/', $vars['bitrix_dir']);
92
  return;
93
  }
94
 
95
+ if ($oldPath !== $path && file_exists($oldPath) && $this->io->isInteractive()) {
 
96
  $this->io->writeError(' <error>Duplication of packages:</error>');
97
  $this->io->writeError(' <info>Package ' . $oldPath . ' will be called instead package ' . $path . '</info>');
98
 
vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class BonefishInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'package' => 'Packages/{$vendor}/{$name}/'
8
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class BonefishInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'package' => 'Packages/{$vendor}/{$name}/'
10
  );
vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  use Composer\DependencyResolver\Pool;
@@ -6,6 +7,7 @@ use Composer\Semver\Constraint\Constraint;
6
 
7
  class CakePHPInstaller extends BaseInstaller
8
  {
 
9
  protected $locations = array(
10
  'plugin' => 'Plugin/{$name}/',
11
  );
@@ -13,7 +15,7 @@ class CakePHPInstaller extends BaseInstaller
13
  /**
14
  * Format package name to CamelCase
15
  */
16
- public function inflectPackageVars($vars)
17
  {
18
  if ($this->matchesCakeVersion('>=', '3.0.0')) {
19
  return $vars;
@@ -21,7 +23,7 @@ class CakePHPInstaller extends BaseInstaller
21
 
22
  $nameParts = explode('/', $vars['name']);
23
  foreach ($nameParts as &$value) {
24
- $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
25
  $value = str_replace(array('-', '_'), ' ', $value);
26
  $value = str_replace(' ', '', ucwords($value));
27
  }
@@ -33,7 +35,7 @@ class CakePHPInstaller extends BaseInstaller
33
  /**
34
  * Change the default plugin location when cakephp >= 3.0
35
  */
36
- public function getLocations()
37
  {
38
  if ($this->matchesCakeVersion('>=', '3.0.0')) {
39
  $this->locations['plugin'] = $this->composer->getConfig()->get('vendor-dir') . '/{$vendor}/{$name}/';
@@ -44,19 +46,18 @@ class CakePHPInstaller extends BaseInstaller
44
  /**
45
  * Check if CakePHP version matches against a version
46
  *
47
- * @param string $matcher
48
- * @param string $version
49
- * @return bool
50
  * @phpstan-param Constraint::STR_OP_* $matcher
51
  */
52
- protected function matchesCakeVersion($matcher, $version)
53
  {
54
  $repositoryManager = $this->composer->getRepositoryManager();
55
- if (! $repositoryManager) {
 
56
  return false;
57
  }
58
 
59
  $repos = $repositoryManager->getLocalRepository();
 
60
  if (!$repos) {
61
  return false;
62
  }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  use Composer\DependencyResolver\Pool;
7
 
8
  class CakePHPInstaller extends BaseInstaller
9
  {
10
+ /** @var array<string, string> */
11
  protected $locations = array(
12
  'plugin' => 'Plugin/{$name}/',
13
  );
15
  /**
16
  * Format package name to CamelCase
17
  */
18
+ public function inflectPackageVars(array $vars): array
19
  {
20
  if ($this->matchesCakeVersion('>=', '3.0.0')) {
21
  return $vars;
23
 
24
  $nameParts = explode('/', $vars['name']);
25
  foreach ($nameParts as &$value) {
26
+ $value = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $value));
27
  $value = str_replace(array('-', '_'), ' ', $value);
28
  $value = str_replace(' ', '', ucwords($value));
29
  }
35
  /**
36
  * Change the default plugin location when cakephp >= 3.0
37
  */
38
+ public function getLocations(string $frameworkType): array
39
  {
40
  if ($this->matchesCakeVersion('>=', '3.0.0')) {
41
  $this->locations['plugin'] = $this->composer->getConfig()->get('vendor-dir') . '/{$vendor}/{$name}/';
46
  /**
47
  * Check if CakePHP version matches against a version
48
  *
 
 
 
49
  * @phpstan-param Constraint::STR_OP_* $matcher
50
  */
51
+ protected function matchesCakeVersion(string $matcher, string $version): bool
52
  {
53
  $repositoryManager = $this->composer->getRepositoryManager();
54
+ /** @phpstan-ignore-next-line */
55
+ if (!$repositoryManager) {
56
  return false;
57
  }
58
 
59
  $repos = $repositoryManager->getLocalRepository();
60
+ /** @phpstan-ignore-next-line */
61
  if (!$repos) {
62
  return false;
63
  }
vendor/composer/installers/src/Composer/Installers/ChefInstaller.php CHANGED
@@ -1,11 +1,12 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class ChefInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'cookbook' => 'Chef/{$vendor}/{$name}/',
8
  'role' => 'Chef/roles/{$name}/',
9
  );
10
  }
11
-
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class ChefInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'cookbook' => 'Chef/{$vendor}/{$name}/',
10
  'role' => 'Chef/roles/{$name}/',
11
  );
12
  }
 
vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class CiviCrmInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'ext' => 'ext/{$name}/'
8
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class CiviCrmInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'ext' => 'ext/{$name}/'
10
  );
vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php CHANGED
@@ -1,10 +1,12 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class ClanCatsFrameworkInstaller extends BaseInstaller
5
  {
6
- protected $locations = array(
7
- 'ship' => 'CCF/orbit/{$name}/',
8
- 'theme' => 'CCF/app/themes/{$name}/',
9
- );
10
- }
 
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class ClanCatsFrameworkInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
+ protected $locations = array(
9
+ 'ship' => 'CCF/orbit/{$name}/',
10
+ 'theme' => 'CCF/app/themes/{$name}/',
11
+ );
12
+ }
vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class CockpitInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'cockpit/modules/addons/{$name}/',
8
  );
@@ -11,10 +13,8 @@ class CockpitInstaller extends BaseInstaller
11
  * Format module name.
12
  *
13
  * Strip `module-` prefix from package name.
14
- *
15
- * {@inheritDoc}
16
  */
17
- public function inflectPackageVars($vars)
18
  {
19
  if ($vars['type'] == 'cockpit-module') {
20
  return $this->inflectModuleVars($vars);
@@ -23,9 +23,13 @@ class CockpitInstaller extends BaseInstaller
23
  return $vars;
24
  }
25
 
26
- public function inflectModuleVars($vars)
 
 
 
 
27
  {
28
- $vars['name'] = ucfirst(preg_replace('/cockpit-/i', '', $vars['name']));
29
 
30
  return $vars;
31
  }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class CockpitInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'cockpit/modules/addons/{$name}/',
10
  );
13
  * Format module name.
14
  *
15
  * Strip `module-` prefix from package name.
 
 
16
  */
17
+ public function inflectPackageVars(array $vars): array
18
  {
19
  if ($vars['type'] == 'cockpit-module') {
20
  return $this->inflectModuleVars($vars);
23
  return $vars;
24
  }
25
 
26
+ /**
27
+ * @param array<string, string> $vars
28
+ * @return array<string, string>
29
+ */
30
+ public function inflectModuleVars(array $vars): array
31
  {
32
+ $vars['name'] = ucfirst($this->pregReplace('/cockpit-/i', '', $vars['name']));
33
 
34
  return $vars;
35
  }
vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class CodeIgniterInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'library' => 'application/libraries/{$name}/',
8
  'third-party' => 'application/third_party/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class CodeIgniterInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'library' => 'application/libraries/{$name}/',
10
  'third-party' => 'application/third_party/{$name}/',
vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class Concrete5Installer extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'core' => 'concrete/',
8
  'block' => 'application/blocks/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class Concrete5Installer extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'core' => 'concrete/',
10
  'block' => 'application/blocks/{$name}/',
vendor/composer/installers/src/Composer/Installers/CraftInstaller.php DELETED
@@ -1,35 +0,0 @@
1
- <?php
2
- namespace Composer\Installers;
3
-
4
- /**
5
- * Installer for Craft Plugins
6
- */
7
- class CraftInstaller extends BaseInstaller
8
- {
9
- const NAME_PREFIX = 'craft';
10
- const NAME_SUFFIX = 'plugin';
11
-
12
- protected $locations = array(
13
- 'plugin' => 'craft/plugins/{$name}/',
14
- );
15
-
16
- /**
17
- * Strip `craft-` prefix and/or `-plugin` suffix from package names
18
- *
19
- * @param array $vars
20
- *
21
- * @return array
22
- */
23
- final public function inflectPackageVars($vars)
24
- {
25
- return $this->inflectPluginVars($vars);
26
- }
27
-
28
- private function inflectPluginVars($vars)
29
- {
30
- $vars['name'] = preg_replace('/-' . self::NAME_SUFFIX . '$/i', '', $vars['name']);
31
- $vars['name'] = preg_replace('/^' . self::NAME_PREFIX . '-/i', '', $vars['name']);
32
-
33
- return $vars;
34
- }
35
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class CroogoInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'plugin' => 'Plugin/{$name}/',
8
  'theme' => 'View/Themed/{$name}/',
@@ -11,7 +13,7 @@ class CroogoInstaller extends BaseInstaller
11
  /**
12
  * Format package name to CamelCase
13
  */
14
- public function inflectPackageVars($vars)
15
  {
16
  $vars['name'] = strtolower(str_replace(array('-', '_'), ' ', $vars['name']));
17
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class CroogoInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'plugin' => 'Plugin/{$name}/',
10
  'theme' => 'View/Themed/{$name}/',
13
  /**
14
  * Format package name to CamelCase
15
  */
16
+ public function inflectPackageVars(array $vars): array
17
  {
18
  $vars['name'] = strtolower(str_replace(array('-', '_'), ' ', $vars['name']));
19
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php CHANGED
@@ -1,9 +1,11 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class DecibelInstaller extends BaseInstaller
5
  {
6
  /** @var array */
 
7
  protected $locations = array(
8
  'app' => 'app/{$name}/',
9
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class DecibelInstaller extends BaseInstaller
6
  {
7
  /** @var array */
8
+ /** @var array<string, string> */
9
  protected $locations = array(
10
  'app' => 'app/{$name}/',
11
  );
vendor/composer/installers/src/Composer/Installers/DframeInstaller.php CHANGED
@@ -4,6 +4,7 @@ namespace Composer\Installers;
4
 
5
  class DframeInstaller extends BaseInstaller
6
  {
 
7
  protected $locations = array(
8
  'module' => 'modules/{$vendor}/{$name}/',
9
  );
4
 
5
  class DframeInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'modules/{$vendor}/{$name}/',
10
  );
vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class DokuWikiInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'plugin' => 'lib/plugins/{$name}/',
8
  'template' => 'lib/tpl/{$name}/',
@@ -11,15 +13,13 @@ class DokuWikiInstaller extends BaseInstaller
11
  /**
12
  * Format package name.
13
  *
14
- * For package type dokuwiki-plugin, cut off a trailing '-plugin',
15
  * or leading dokuwiki_ if present.
16
- *
17
- * For package type dokuwiki-template, cut off a trailing '-template' if present.
18
  *
 
19
  */
20
- public function inflectPackageVars($vars)
21
  {
22
-
23
  if ($vars['type'] === 'dokuwiki-plugin') {
24
  return $this->inflectPluginVars($vars);
25
  }
@@ -31,20 +31,27 @@ class DokuWikiInstaller extends BaseInstaller
31
  return $vars;
32
  }
33
 
34
- protected function inflectPluginVars($vars)
 
 
 
 
35
  {
36
- $vars['name'] = preg_replace('/-plugin$/', '', $vars['name']);
37
- $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']);
38
 
39
  return $vars;
40
  }
41
 
42
- protected function inflectTemplateVars($vars)
 
 
 
 
43
  {
44
- $vars['name'] = preg_replace('/-template$/', '', $vars['name']);
45
- $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']);
46
 
47
  return $vars;
48
  }
49
-
50
  }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class DokuWikiInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'plugin' => 'lib/plugins/{$name}/',
10
  'template' => 'lib/tpl/{$name}/',
13
  /**
14
  * Format package name.
15
  *
16
+ * For package type dokuwiki-plugin, cut off a trailing '-plugin',
17
  * or leading dokuwiki_ if present.
 
 
18
  *
19
+ * For package type dokuwiki-template, cut off a trailing '-template' if present.
20
  */
21
+ public function inflectPackageVars(array $vars): array
22
  {
 
23
  if ($vars['type'] === 'dokuwiki-plugin') {
24
  return $this->inflectPluginVars($vars);
25
  }
31
  return $vars;
32
  }
33
 
34
+ /**
35
+ * @param array<string, string> $vars
36
+ * @return array<string, string>
37
+ */
38
+ protected function inflectPluginVars(array $vars): array
39
  {
40
+ $vars['name'] = $this->pregReplace('/-plugin$/', '', $vars['name']);
41
+ $vars['name'] = $this->pregReplace('/^dokuwiki_?-?/', '', $vars['name']);
42
 
43
  return $vars;
44
  }
45
 
46
+ /**
47
+ * @param array<string, string> $vars
48
+ * @return array<string, string>
49
+ */
50
+ protected function inflectTemplateVars(array $vars): array
51
  {
52
+ $vars['name'] = $this->pregReplace('/-template$/', '', $vars['name']);
53
+ $vars['name'] = $this->pregReplace('/^dokuwiki_?-?/', '', $vars['name']);
54
 
55
  return $vars;
56
  }
 
57
  }
vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  /**
@@ -10,6 +11,7 @@ namespace Composer\Installers;
10
  class DolibarrInstaller extends BaseInstaller
11
  {
12
  //TODO: Add support for scripts and themes
 
13
  protected $locations = array(
14
  'module' => 'htdocs/custom/{$name}/',
15
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  /**
11
  class DolibarrInstaller extends BaseInstaller
12
  {
13
  //TODO: Add support for scripts and themes
14
+ /** @var array<string, string> */
15
  protected $locations = array(
16
  'module' => 'htdocs/custom/{$name}/',
17
  );
vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class DrupalInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'core' => 'core/',
8
  'module' => 'modules/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class DrupalInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'core' => 'core/',
10
  'module' => 'modules/{$name}/',
vendor/composer/installers/src/Composer/Installers/ElggInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class ElggInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'plugin' => 'mod/{$name}/',
8
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class ElggInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'plugin' => 'mod/{$name}/',
10
  );
vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class EliasisInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'component' => 'components/{$name}/',
8
  'module' => 'modules/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class EliasisInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'component' => 'components/{$name}/',
10
  'module' => 'modules/{$name}/',
vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php CHANGED
@@ -1,29 +1,31 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  use Composer\Package\PackageInterface;
5
 
6
  class ExpressionEngineInstaller extends BaseInstaller
7
  {
8
-
9
- protected $locations = array();
10
-
11
  private $ee2Locations = array(
12
  'addon' => 'system/expressionengine/third_party/{$name}/',
13
  'theme' => 'themes/third_party/{$name}/',
14
  );
15
 
 
16
  private $ee3Locations = array(
17
  'addon' => 'system/user/addons/{$name}/',
18
  'theme' => 'themes/user/{$name}/',
19
  );
20
 
21
- public function getInstallPath(PackageInterface $package, $frameworkType = '')
22
  {
 
 
 
 
 
23
 
24
- $version = "{$frameworkType}Locations";
25
- $this->locations = $this->$version;
26
-
27
- return parent::getInstallPath($package, $frameworkType);
28
  }
29
  }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  use Composer\Package\PackageInterface;
6
 
7
  class ExpressionEngineInstaller extends BaseInstaller
8
  {
9
+ /** @var array<string, string> */
 
 
10
  private $ee2Locations = array(
11
  'addon' => 'system/expressionengine/third_party/{$name}/',
12
  'theme' => 'themes/third_party/{$name}/',
13
  );
14
 
15
+ /** @var array<string, string> */
16
  private $ee3Locations = array(
17
  'addon' => 'system/user/addons/{$name}/',
18
  'theme' => 'themes/user/{$name}/',
19
  );
20
 
21
+ public function getLocations(string $frameworkType): array
22
  {
23
+ if ($frameworkType === 'ee2') {
24
+ $this->locations = $this->ee2Locations;
25
+ } else {
26
+ $this->locations = $this->ee3Locations;
27
+ }
28
 
29
+ return $this->locations;
 
 
 
30
  }
31
  }
vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class EzPlatformInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'meta-assets' => 'web/assets/ezplatform/',
8
  'assets' => 'web/assets/ezplatform/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class EzPlatformInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'meta-assets' => 'web/assets/ezplatform/',
10
  'assets' => 'web/assets/ezplatform/{$name}/',
vendor/composer/installers/src/Composer/Installers/FuelInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class FuelInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'fuel/app/modules/{$name}/',
8
  'package' => 'fuel/packages/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class FuelInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'fuel/app/modules/{$name}/',
10
  'package' => 'fuel/packages/{$name}/',
vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class FuelphpInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'component' => 'components/{$name}/',
8
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class FuelphpInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'component' => 'components/{$name}/',
10
  );
vendor/composer/installers/src/Composer/Installers/GravInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class GravInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'plugin' => 'user/plugins/{$name}/',
8
  'theme' => 'user/themes/{$name}/',
@@ -10,17 +12,14 @@ class GravInstaller extends BaseInstaller
10
 
11
  /**
12
  * Format package name
13
- *
14
- * @param array $vars
15
- *
16
- * @return array
17
  */
18
- public function inflectPackageVars($vars)
19
  {
20
  $restrictedWords = implode('|', array_keys($this->locations));
21
 
22
  $vars['name'] = strtolower($vars['name']);
23
- $vars['name'] = preg_replace('/^(?:grav-)?(?:(?:'.$restrictedWords.')-)?(.*?)(?:-(?:'.$restrictedWords.'))?$/ui',
 
24
  '$1',
25
  $vars['name']
26
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class GravInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'plugin' => 'user/plugins/{$name}/',
10
  'theme' => 'user/themes/{$name}/',
12
 
13
  /**
14
  * Format package name
 
 
 
 
15
  */
16
+ public function inflectPackageVars(array $vars): array
17
  {
18
  $restrictedWords = implode('|', array_keys($this->locations));
19
 
20
  $vars['name'] = strtolower($vars['name']);
21
+ $vars['name'] = $this->pregReplace(
22
+ '/^(?:grav-)?(?:(?:'.$restrictedWords.')-)?(.*?)(?:-(?:'.$restrictedWords.'))?$/ui',
23
  '$1',
24
  $vars['name']
25
  );
vendor/composer/installers/src/Composer/Installers/HuradInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class HuradInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'plugin' => 'plugins/{$name}/',
8
  'theme' => 'plugins/{$name}/',
@@ -11,11 +13,11 @@ class HuradInstaller extends BaseInstaller
11
  /**
12
  * Format package name to CamelCase
13
  */
14
- public function inflectPackageVars($vars)
15
  {
16
  $nameParts = explode('/', $vars['name']);
17
  foreach ($nameParts as &$value) {
18
- $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
19
  $value = str_replace(array('-', '_'), ' ', $value);
20
  $value = str_replace(' ', '', ucwords($value));
21
  }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class HuradInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'plugin' => 'plugins/{$name}/',
10
  'theme' => 'plugins/{$name}/',
13
  /**
14
  * Format package name to CamelCase
15
  */
16
+ public function inflectPackageVars(array $vars): array
17
  {
18
  $nameParts = explode('/', $vars['name']);
19
  foreach ($nameParts as &$value) {
20
+ $value = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $value));
21
  $value = str_replace(array('-', '_'), ' ', $value);
22
  $value = str_replace(' ', '', ucwords($value));
23
  }
vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class ImageCMSInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'template' => 'templates/{$name}/',
8
  'module' => 'application/modules/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class ImageCMSInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'template' => 'templates/{$name}/',
10
  'module' => 'application/modules/{$name}/',
vendor/composer/installers/src/Composer/Installers/Installer.php CHANGED
@@ -6,6 +6,7 @@ use Composer\Composer;
6
  use Composer\Installer\BinaryInstaller;
7
  use Composer\Installer\LibraryInstaller;
8
  use Composer\IO\IOInterface;
 
9
  use Composer\Package\PackageInterface;
10
  use Composer\Repository\InstalledRepositoryInterface;
11
  use Composer\Util\Filesystem;
@@ -13,14 +14,13 @@ use React\Promise\PromiseInterface;
13
 
14
  class Installer extends LibraryInstaller
15
  {
16
-
17
  /**
18
  * Package types to installer class map
19
  *
20
- * @var array
21
  */
22
  private $supportedTypes = array(
23
- 'aimeos' => 'AimeosInstaller',
24
  'asgard' => 'AsgardInstaller',
25
  'attogram' => 'AttogramInstaller',
26
  'agl' => 'AglInstaller',
@@ -34,7 +34,6 @@ class Installer extends LibraryInstaller
34
  'cockpit' => 'CockpitInstaller',
35
  'codeigniter' => 'CodeIgniterInstaller',
36
  'concrete5' => 'Concrete5Installer',
37
- 'craft' => 'CraftInstaller',
38
  'croogo' => 'CroogoInstaller',
39
  'dframe' => 'DframeInstaller',
40
  'dokuwiki' => 'DokuWikiInstaller',
@@ -53,13 +52,11 @@ class Installer extends LibraryInstaller
53
  'tastyigniter' => 'TastyIgniterInstaller',
54
  'imagecms' => 'ImageCMSInstaller',
55
  'itop' => 'ItopInstaller',
56
- 'joomla' => 'JoomlaInstaller',
57
  'kanboard' => 'KanboardInstaller',
58
- 'kirby' => 'KirbyInstaller',
59
  'known' => 'KnownInstaller',
60
  'kodicms' => 'KodiCMSInstaller',
61
  'kohana' => 'KohanaInstaller',
62
- 'lms' => 'LanManagementSystemInstaller',
63
  'laravel' => 'LaravelInstaller',
64
  'lavalite' => 'LavaLiteInstaller',
65
  'lithium' => 'LithiumInstaller',
@@ -67,6 +64,7 @@ class Installer extends LibraryInstaller
67
  'majima' => 'MajimaInstaller',
68
  'mantisbt' => 'MantisBTInstaller',
69
  'mako' => 'MakoInstaller',
 
70
  'maya' => 'MayaInstaller',
71
  'mautic' => 'MauticInstaller',
72
  'mediawiki' => 'MediaWikiInstaller',
@@ -82,7 +80,6 @@ class Installer extends LibraryInstaller
82
  'osclass' => 'OsclassInstaller',
83
  'pxcms' => 'PxcmsInstaller',
84
  'phpbb' => 'PhpBBInstaller',
85
- 'pimcore' => 'PimcoreInstaller',
86
  'piwik' => 'PiwikInstaller',
87
  'plentymarkets'=> 'PlentymarketsInstaller',
88
  'ppi' => 'PPIInstaller',
@@ -103,12 +100,9 @@ class Installer extends LibraryInstaller
103
  'starbug' => 'StarbugInstaller',
104
  'sydes' => 'SyDESInstaller',
105
  'sylius' => 'SyliusInstaller',
106
- 'symfony1' => 'Symfony1Installer',
107
  'tao' => 'TaoInstaller',
108
  'thelia' => 'TheliaInstaller',
109
  'tusk' => 'TuskInstaller',
110
- 'typo3-cms' => 'TYPO3CmsInstaller',
111
- 'typo3-flow' => 'TYPO3FlowInstaller',
112
  'userfrosting' => 'UserFrostingInstaller',
113
  'vanilla' => 'VanillaInstaller',
114
  'whmcs' => 'WHMCSInstaller',
@@ -122,26 +116,17 @@ class Installer extends LibraryInstaller
122
  );
123
 
124
  /**
125
- * Installer constructor.
126
- *
127
  * Disables installers specified in main composer extra installer-disable
128
  * list
129
- *
130
- * @param IOInterface $io
131
- * @param Composer $composer
132
- * @param string $type
133
- * @param Filesystem|null $filesystem
134
- * @param BinaryInstaller|null $binaryInstaller
135
  */
136
  public function __construct(
137
  IOInterface $io,
138
  Composer $composer,
139
- $type = 'library',
140
- Filesystem $filesystem = null,
141
- BinaryInstaller $binaryInstaller = null
142
  ) {
143
- parent::__construct($io, $composer, $type, $filesystem,
144
- $binaryInstaller);
145
  $this->removeDisabledInstallers();
146
  }
147
 
@@ -162,7 +147,12 @@ class Installer extends LibraryInstaller
162
  $class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
163
  $installer = new $class($package, $this->composer, $this->getIO());
164
 
165
- return $installer->getInstallPath($package, $frameworkType);
 
 
 
 
 
166
  }
167
 
168
  public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
@@ -205,10 +195,9 @@ class Installer extends LibraryInstaller
205
  /**
206
  * Finds a supported framework type if it exists and returns it
207
  *
208
- * @param string $type
209
  * @return string|false
210
  */
211
- protected function findFrameworkType($type)
212
  {
213
  krsort($this->supportedTypes);
214
 
@@ -224,30 +213,24 @@ class Installer extends LibraryInstaller
224
  /**
225
  * Get the second part of the regular expression to check for support of a
226
  * package type
227
- *
228
- * @param string $frameworkType
229
- * @return string
230
  */
231
- protected function getLocationPattern($frameworkType)
232
  {
233
- $pattern = false;
234
  if (!empty($this->supportedTypes[$frameworkType])) {
235
  $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
236
  /** @var BaseInstaller $framework */
237
- $framework = new $frameworkClass(null, $this->composer, $this->getIO());
238
- $locations = array_keys($framework->getLocations());
239
- $pattern = $locations ? '(' . implode('|', $locations) . ')' : false;
 
 
240
  }
241
 
242
- return $pattern ? : '(\w+)';
243
  }
244
 
245
- /**
246
- * Get I/O object
247
- *
248
- * @return IOInterface
249
- */
250
- private function getIO()
251
  {
252
  return $this->io;
253
  }
@@ -260,10 +243,8 @@ class Installer extends LibraryInstaller
260
  * - true, "all", and "*" - disable all installers.
261
  * - false - enable all installers (useful with
262
  * wikimedia/composer-merge-plugin or similar)
263
- *
264
- * @return void
265
  */
266
- protected function removeDisabledInstallers()
267
  {
268
  $extra = $this->composer->getPackage()->getExtra();
269
 
@@ -286,12 +267,13 @@ class Installer extends LibraryInstaller
286
  if (!empty($intersect)) {
287
  // Disable all installers
288
  $this->supportedTypes = array();
289
- } else {
290
- // Disable specified installers
291
- foreach ($disable as $key => $installer) {
292
- if (is_string($installer) && key_exists($installer, $this->supportedTypes)) {
293
- unset($this->supportedTypes[$installer]);
294
- }
 
295
  }
296
  }
297
  }
6
  use Composer\Installer\BinaryInstaller;
7
  use Composer\Installer\LibraryInstaller;
8
  use Composer\IO\IOInterface;
9
+ use Composer\Package\Package;
10
  use Composer\Package\PackageInterface;
11
  use Composer\Repository\InstalledRepositoryInterface;
12
  use Composer\Util\Filesystem;
14
 
15
  class Installer extends LibraryInstaller
16
  {
 
17
  /**
18
  * Package types to installer class map
19
  *
20
+ * @var array<string, string>
21
  */
22
  private $supportedTypes = array(
23
+ 'akaunting' => 'AkauntingInstaller',
24
  'asgard' => 'AsgardInstaller',
25
  'attogram' => 'AttogramInstaller',
26
  'agl' => 'AglInstaller',
34
  'cockpit' => 'CockpitInstaller',
35
  'codeigniter' => 'CodeIgniterInstaller',
36
  'concrete5' => 'Concrete5Installer',
 
37
  'croogo' => 'CroogoInstaller',
38
  'dframe' => 'DframeInstaller',
39
  'dokuwiki' => 'DokuWikiInstaller',
52
  'tastyigniter' => 'TastyIgniterInstaller',
53
  'imagecms' => 'ImageCMSInstaller',
54
  'itop' => 'ItopInstaller',
 
55
  'kanboard' => 'KanboardInstaller',
 
56
  'known' => 'KnownInstaller',
57
  'kodicms' => 'KodiCMSInstaller',
58
  'kohana' => 'KohanaInstaller',
59
+ 'lms' => 'LanManagementSystemInstaller',
60
  'laravel' => 'LaravelInstaller',
61
  'lavalite' => 'LavaLiteInstaller',
62
  'lithium' => 'LithiumInstaller',
64
  'majima' => 'MajimaInstaller',
65
  'mantisbt' => 'MantisBTInstaller',
66
  'mako' => 'MakoInstaller',
67
+ 'matomo' => 'MatomoInstaller',
68
  'maya' => 'MayaInstaller',
69
  'mautic' => 'MauticInstaller',
70
  'mediawiki' => 'MediaWikiInstaller',
80
  'osclass' => 'OsclassInstaller',
81
  'pxcms' => 'PxcmsInstaller',
82
  'phpbb' => 'PhpBBInstaller',
 
83
  'piwik' => 'PiwikInstaller',
84
  'plentymarkets'=> 'PlentymarketsInstaller',
85
  'ppi' => 'PPIInstaller',
100
  'starbug' => 'StarbugInstaller',
101
  'sydes' => 'SyDESInstaller',
102
  'sylius' => 'SyliusInstaller',
 
103
  'tao' => 'TaoInstaller',
104
  'thelia' => 'TheliaInstaller',
105
  'tusk' => 'TuskInstaller',
 
 
106
  'userfrosting' => 'UserFrostingInstaller',
107
  'vanilla' => 'VanillaInstaller',
108
  'whmcs' => 'WHMCSInstaller',
116
  );
117
 
118
  /**
 
 
119
  * Disables installers specified in main composer extra installer-disable
120
  * list
 
 
 
 
 
 
121
  */
122
  public function __construct(
123
  IOInterface $io,
124
  Composer $composer,
125
+ string $type = 'library',
126
+ ?Filesystem $filesystem = null,
127
+ ?BinaryInstaller $binaryInstaller = null
128
  ) {
129
+ parent::__construct($io, $composer, $type, $filesystem, $binaryInstaller);
 
130
  $this->removeDisabledInstallers();
131
  }
132
 
147
  $class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
148
  $installer = new $class($package, $this->composer, $this->getIO());
149
 
150
+ $path = $installer->getInstallPath($package, $frameworkType);
151
+ if (!$this->filesystem->isAbsolutePath($path)) {
152
+ $path = getcwd() . '/' . $path;
153
+ }
154
+
155
+ return $path;
156
  }
157
 
158
  public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
195
  /**
196
  * Finds a supported framework type if it exists and returns it
197
  *
 
198
  * @return string|false
199
  */
200
+ protected function findFrameworkType(string $type)
201
  {
202
  krsort($this->supportedTypes);
203
 
213
  /**
214
  * Get the second part of the regular expression to check for support of a
215
  * package type
 
 
 
216
  */
217
+ protected function getLocationPattern(string $frameworkType): string
218
  {
219
+ $pattern = null;
220
  if (!empty($this->supportedTypes[$frameworkType])) {
221
  $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
222
  /** @var BaseInstaller $framework */
223
+ $framework = new $frameworkClass(new Package('dummy/pkg', '1.0.0.0', '1.0.0'), $this->composer, $this->getIO());
224
+ $locations = array_keys($framework->getLocations($frameworkType));
225
+ if ($locations) {
226
+ $pattern = '(' . implode('|', $locations) . ')';
227
+ }
228
  }
229
 
230
+ return $pattern ?: '(\w+)';
231
  }
232
 
233
+ private function getIO(): IOInterface
 
 
 
 
 
234
  {
235
  return $this->io;
236
  }
243
  * - true, "all", and "*" - disable all installers.
244
  * - false - enable all installers (useful with
245
  * wikimedia/composer-merge-plugin or similar)
 
 
246
  */
247
+ protected function removeDisabledInstallers(): void
248
  {
249
  $extra = $this->composer->getPackage()->getExtra();
250
 
267
  if (!empty($intersect)) {
268
  // Disable all installers
269
  $this->supportedTypes = array();
270
+ return;
271
+ }
272
+
273
+ // Disable specified installers
274
+ foreach ($disable as $key => $installer) {
275
+ if (is_string($installer) && key_exists($installer, $this->supportedTypes)) {
276
+ unset($this->supportedTypes[$installer]);
277
  }
278
  }
279
  }
vendor/composer/installers/src/Composer/Installers/ItopInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class ItopInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'extension' => 'extensions/{$name}/',
8
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class ItopInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'extension' => 'extensions/{$name}/',
10
  );
vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php DELETED
@@ -1,15 +0,0 @@
1
- <?php
2
- namespace Composer\Installers;
3
-
4
- class JoomlaInstaller extends BaseInstaller
5
- {
6
- protected $locations = array(
7
- 'component' => 'components/{$name}/',
8
- 'module' => 'modules/{$name}/',
9
- 'template' => 'templates/{$name}/',
10
- 'plugin' => 'plugins/{$name}/',
11
- 'library' => 'libraries/{$name}/',
12
- );
13
-
14
- // TODO: Add inflector for mod_ and com_ names
15
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  /**
@@ -12,6 +13,7 @@ namespace Composer\Installers;
12
  */
13
  class KanboardInstaller extends BaseInstaller
14
  {
 
15
  protected $locations = array(
16
  'plugin' => 'plugins/{$name}/',
17
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  /**
13
  */
14
  class KanboardInstaller extends BaseInstaller
15
  {
16
+ /** @var array<string, string> */
17
  protected $locations = array(
18
  'plugin' => 'plugins/{$name}/',
19
  );
vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
- namespace Composer\Installers;
3
-
4
- class KirbyInstaller extends BaseInstaller
5
- {
6
- protected $locations = array(
7
- 'plugin' => 'site/plugins/{$name}/',
8
- 'field' => 'site/fields/{$name}/',
9
- 'tag' => 'site/tags/{$name}/'
10
- );
11
- }
 
 
 
 
 
 
 
 
 
 
 
vendor/composer/installers/src/Composer/Installers/KnownInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class KnownInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'plugin' => 'IdnoPlugins/{$name}/',
8
  'theme' => 'Themes/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class KnownInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'plugin' => 'IdnoPlugins/{$name}/',
10
  'theme' => 'Themes/{$name}/',
vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php CHANGED
@@ -1,10 +1,12 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class KodiCMSInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'plugin' => 'cms/plugins/{$name}/',
8
  'media' => 'cms/media/vendor/{$name}/'
9
  );
10
- }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class KodiCMSInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'plugin' => 'cms/plugins/{$name}/',
10
  'media' => 'cms/media/vendor/{$name}/'
11
  );
12
+ }
vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class KohanaInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'modules/{$name}/',
8
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class KohanaInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'modules/{$name}/',
10
  );
vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php CHANGED
@@ -5,6 +5,7 @@ namespace Composer\Installers;
5
  class LanManagementSystemInstaller extends BaseInstaller
6
  {
7
 
 
8
  protected $locations = array(
9
  'plugin' => 'plugins/{$name}/',
10
  'template' => 'templates/{$name}/',
@@ -15,13 +16,12 @@ class LanManagementSystemInstaller extends BaseInstaller
15
  /**
16
  * Format package name to CamelCase
17
  */
18
- public function inflectPackageVars($vars)
19
  {
20
- $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
21
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
22
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
23
 
24
  return $vars;
25
  }
26
-
27
  }
5
  class LanManagementSystemInstaller extends BaseInstaller
6
  {
7
 
8
+ /** @var array<string, string> */
9
  protected $locations = array(
10
  'plugin' => 'plugins/{$name}/',
11
  'template' => 'templates/{$name}/',
16
  /**
17
  * Format package name to CamelCase
18
  */
19
+ public function inflectPackageVars(array $vars): array
20
  {
21
+ $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
22
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
23
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
24
 
25
  return $vars;
26
  }
 
27
  }
vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class LaravelInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'library' => 'libraries/{$name}/',
8
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class LaravelInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'library' => 'libraries/{$name}/',
10
  );
vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class LavaLiteInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'package' => 'packages/{$vendor}/{$name}/',
8
  'theme' => 'public/themes/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class LavaLiteInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'package' => 'packages/{$vendor}/{$name}/',
10
  'theme' => 'public/themes/{$name}/',
vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class LithiumInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'library' => 'libraries/{$name}/',
8
  'source' => 'libraries/_source/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class LithiumInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'library' => 'libraries/{$name}/',
10
  'source' => 'libraries/_source/{$name}/',
vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class MODULEWorkInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'modules/{$name}/',
8
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class MODULEWorkInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'modules/{$name}/',
10
  );
vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  /**
@@ -6,6 +7,7 @@ namespace Composer\Installers;
6
  */
7
  class MODXEvoInstaller extends BaseInstaller
8
  {
 
9
  protected $locations = array(
10
  'snippet' => 'assets/snippets/{$name}/',
11
  'plugin' => 'assets/plugins/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  /**
7
  */
8
  class MODXEvoInstaller extends BaseInstaller
9
  {
10
+ /** @var array<string, string> */
11
  protected $locations = array(
12
  'snippet' => 'assets/snippets/{$name}/',
13
  'plugin' => 'assets/plugins/{$name}/',
vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class MagentoInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'theme' => 'app/design/frontend/{$name}/',
8
  'skin' => 'skin/frontend/default/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class MagentoInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'theme' => 'app/design/frontend/{$name}/',
10
  'skin' => 'skin/frontend/default/{$name}/',
vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  /**
@@ -7,30 +8,38 @@ namespace Composer\Installers;
7
  */
8
  class MajimaInstaller extends BaseInstaller
9
  {
 
10
  protected $locations = array(
11
  'plugin' => 'plugins/{$name}/',
12
  );
13
 
14
  /**
15
  * Transforms the names
16
- * @param array $vars
17
- * @return array
 
18
  */
19
- public function inflectPackageVars($vars)
20
  {
21
  return $this->correctPluginName($vars);
22
  }
23
 
24
  /**
25
  * Change hyphenated names to camelcase
26
- * @param array $vars
27
- * @return array
 
28
  */
29
- private function correctPluginName($vars)
30
  {
31
  $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) {
32
  return strtoupper($matches[0][1]);
33
  }, $vars['name']);
 
 
 
 
 
34
  $vars['name'] = ucfirst($camelCasedName);
35
  return $vars;
36
  }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  /**
8
  */
9
  class MajimaInstaller extends BaseInstaller
10
  {
11
+ /** @var array<string, string> */
12
  protected $locations = array(
13
  'plugin' => 'plugins/{$name}/',
14
  );
15
 
16
  /**
17
  * Transforms the names
18
+ *
19
+ * @param array<string, string> $vars
20
+ * @return array<string, string>
21
  */
22
+ public function inflectPackageVars(array $vars): array
23
  {
24
  return $this->correctPluginName($vars);
25
  }
26
 
27
  /**
28
  * Change hyphenated names to camelcase
29
+ *
30
+ * @param array<string, string> $vars
31
+ * @return array<string, string>
32
  */
33
+ private function correctPluginName(array $vars): array
34
  {
35
  $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) {
36
  return strtoupper($matches[0][1]);
37
  }, $vars['name']);
38
+
39
+ if (null === $camelCasedName) {
40
+ throw new \RuntimeException('Failed to run preg_replace_callback: '.preg_last_error());
41
+ }
42
+
43
  $vars['name'] = ucfirst($camelCasedName);
44
  return $vars;
45
  }
vendor/composer/installers/src/Composer/Installers/MakoInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class MakoInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'package' => 'app/packages/{$name}/',
8
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class MakoInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'package' => 'app/packages/{$name}/',
10
  );
vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php CHANGED
@@ -1,10 +1,12 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  use Composer\DependencyResolver\Pool;
5
 
6
  class MantisBTInstaller extends BaseInstaller
7
  {
 
8
  protected $locations = array(
9
  'plugin' => 'plugins/{$name}/',
10
  );
@@ -12,9 +14,9 @@ class MantisBTInstaller extends BaseInstaller
12
  /**
13
  * Format package name to CamelCase
14
  */
15
- public function inflectPackageVars($vars)
16
  {
17
- $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
18
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
19
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
20
 
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  use Composer\DependencyResolver\Pool;
6
 
7
  class MantisBTInstaller extends BaseInstaller
8
  {
9
+ /** @var array<string, string> */
10
  protected $locations = array(
11
  'plugin' => 'plugins/{$name}/',
12
  );
14
  /**
15
  * Format package name to CamelCase
16
  */
17
+ public function inflectPackageVars(array $vars): array
18
  {
19
+ $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
20
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
21
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
22
 
vendor/composer/installers/src/Composer/Installers/{PimcoreInstaller.php → MatomoInstaller.php} RENAMED
@@ -1,8 +1,15 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
- class PimcoreInstaller extends BaseInstaller
 
 
 
 
 
5
  {
 
6
  protected $locations = array(
7
  'plugin' => 'plugins/{$name}/',
8
  );
@@ -10,9 +17,9 @@ class PimcoreInstaller extends BaseInstaller
10
  /**
11
  * Format package name to CamelCase
12
  */
13
- public function inflectPackageVars($vars)
14
  {
15
- $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
16
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
17
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
18
 
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
+ /**
6
+ * Class MatomoInstaller
7
+ *
8
+ * @package Composer\Installers
9
+ */
10
+ class MatomoInstaller extends BaseInstaller
11
  {
12
+ /** @var array<string, string> */
13
  protected $locations = array(
14
  'plugin' => 'plugins/{$name}/',
15
  );
17
  /**
18
  * Format package name to CamelCase
19
  */
20
+ public function inflectPackageVars(array $vars): array
21
  {
22
+ $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
23
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
24
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
25
 
vendor/composer/installers/src/Composer/Installers/MauticInstaller.php CHANGED
@@ -1,17 +1,19 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  use Composer\Package\PackageInterface;
5
 
6
  class MauticInstaller extends BaseInstaller
7
  {
 
8
  protected $locations = array(
9
  'plugin' => 'plugins/{$name}/',
10
  'theme' => 'themes/{$name}/',
11
  'core' => 'app/',
12
  );
13
 
14
- private function getDirectoryName()
15
  {
16
  $extra = $this->package->getExtra();
17
  if (!empty($extra['install-directory-name'])) {
@@ -21,12 +23,7 @@ class MauticInstaller extends BaseInstaller
21
  return $this->toCamelCase($this->package->getPrettyName());
22
  }
23
 
24
- /**
25
- * @param string $packageName
26
- *
27
- * @return string
28
- */
29
- private function toCamelCase($packageName)
30
  {
31
  return str_replace(' ', '', ucwords(str_replace('-', ' ', basename($packageName))));
32
  }
@@ -34,9 +31,8 @@ class MauticInstaller extends BaseInstaller
34
  /**
35
  * Format package name of mautic-plugins to CamelCase
36
  */
37
- public function inflectPackageVars($vars)
38
  {
39
-
40
  if ($vars['type'] == 'mautic-plugin' || $vars['type'] == 'mautic-theme') {
41
  $directoryName = $this->getDirectoryName();
42
  $vars['name'] = $directoryName;
@@ -44,5 +40,4 @@ class MauticInstaller extends BaseInstaller
44
 
45
  return $vars;
46
  }
47
-
48
  }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  use Composer\Package\PackageInterface;
6
 
7
  class MauticInstaller extends BaseInstaller
8
  {
9
+ /** @var array<string, string> */
10
  protected $locations = array(
11
  'plugin' => 'plugins/{$name}/',
12
  'theme' => 'themes/{$name}/',
13
  'core' => 'app/',
14
  );
15
 
16
+ private function getDirectoryName(): string
17
  {
18
  $extra = $this->package->getExtra();
19
  if (!empty($extra['install-directory-name'])) {
23
  return $this->toCamelCase($this->package->getPrettyName());
24
  }
25
 
26
+ private function toCamelCase(string $packageName): string
 
 
 
 
 
27
  {
28
  return str_replace(' ', '', ucwords(str_replace('-', ' ', basename($packageName))));
29
  }
31
  /**
32
  * Format package name of mautic-plugins to CamelCase
33
  */
34
+ public function inflectPackageVars(array $vars): array
35
  {
 
36
  if ($vars['type'] == 'mautic-plugin' || $vars['type'] == 'mautic-theme') {
37
  $directoryName = $this->getDirectoryName();
38
  $vars['name'] = $directoryName;
40
 
41
  return $vars;
42
  }
 
43
  }
vendor/composer/installers/src/Composer/Installers/MayaInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class MayaInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'modules/{$name}/',
8
  );
@@ -11,9 +13,8 @@ class MayaInstaller extends BaseInstaller
11
  * Format package name.
12
  *
13
  * For package type maya-module, cut off a trailing '-module' if present.
14
- *
15
  */
16
- public function inflectPackageVars($vars)
17
  {
18
  if ($vars['type'] === 'maya-module') {
19
  return $this->inflectModuleVars($vars);
@@ -22,9 +23,13 @@ class MayaInstaller extends BaseInstaller
22
  return $vars;
23
  }
24
 
25
- protected function inflectModuleVars($vars)
 
 
 
 
26
  {
27
- $vars['name'] = preg_replace('/-module$/', '', $vars['name']);
28
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
29
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
30
 
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class MayaInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'modules/{$name}/',
10
  );
13
  * Format package name.
14
  *
15
  * For package type maya-module, cut off a trailing '-module' if present.
 
16
  */
17
+ public function inflectPackageVars(array $vars): array
18
  {
19
  if ($vars['type'] === 'maya-module') {
20
  return $this->inflectModuleVars($vars);
23
  return $vars;
24
  }
25
 
26
+ /**
27
+ * @param array<string, string> $vars
28
+ * @return array<string, string>
29
+ */
30
+ protected function inflectModuleVars(array $vars): array
31
  {
32
+ $vars['name'] = $this->pregReplace('/-module$/', '', $vars['name']);
33
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
34
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
35
 
vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class MediaWikiInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'core' => 'core/',
8
  'extension' => 'extensions/{$name}/',
@@ -16,11 +18,9 @@ class MediaWikiInstaller extends BaseInstaller
16
  * to CamelCase keeping existing uppercase chars.
17
  *
18
  * For package type mediawiki-skin, cut off a trailing '-skin' if present.
19
- *
20
  */
21
- public function inflectPackageVars($vars)
22
  {
23
-
24
  if ($vars['type'] === 'mediawiki-extension') {
25
  return $this->inflectExtensionVars($vars);
26
  }
@@ -32,20 +32,27 @@ class MediaWikiInstaller extends BaseInstaller
32
  return $vars;
33
  }
34
 
35
- protected function inflectExtensionVars($vars)
 
 
 
 
36
  {
37
- $vars['name'] = preg_replace('/-extension$/', '', $vars['name']);
38
  $vars['name'] = str_replace('-', ' ', $vars['name']);
39
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
40
 
41
  return $vars;
42
  }
43
 
44
- protected function inflectSkinVars($vars)
 
 
 
 
45
  {
46
- $vars['name'] = preg_replace('/-skin$/', '', $vars['name']);
47
 
48
  return $vars;
49
  }
50
-
51
  }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class MediaWikiInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'core' => 'core/',
10
  'extension' => 'extensions/{$name}/',
18
  * to CamelCase keeping existing uppercase chars.
19
  *
20
  * For package type mediawiki-skin, cut off a trailing '-skin' if present.
 
21
  */
22
+ public function inflectPackageVars(array $vars): array
23
  {
 
24
  if ($vars['type'] === 'mediawiki-extension') {
25
  return $this->inflectExtensionVars($vars);
26
  }
32
  return $vars;
33
  }
34
 
35
+ /**
36
+ * @param array<string, string> $vars
37
+ * @return array<string, string>
38
+ */
39
+ protected function inflectExtensionVars(array $vars): array
40
  {
41
+ $vars['name'] = $this->pregReplace('/-extension$/', '', $vars['name']);
42
  $vars['name'] = str_replace('-', ' ', $vars['name']);
43
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
44
 
45
  return $vars;
46
  }
47
 
48
+ /**
49
+ * @param array<string, string> $vars
50
+ * @return array<string, string>
51
+ */
52
+ protected function inflectSkinVars(array $vars): array
53
  {
54
+ $vars['name'] = $this->pregReplace('/-skin$/', '', $vars['name']);
55
 
56
  return $vars;
57
  }
 
58
  }
vendor/composer/installers/src/Composer/Installers/MiaoxingInstaller.php CHANGED
@@ -4,6 +4,7 @@ namespace Composer\Installers;
4
 
5
  class MiaoxingInstaller extends BaseInstaller
6
  {
 
7
  protected $locations = array(
8
  'plugin' => 'plugins/{$name}/',
9
  );
4
 
5
  class MiaoxingInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'plugin' => 'plugins/{$name}/',
10
  );
vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class MicroweberInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'userfiles/modules/{$install_item_dir}/',
8
  'module-skin' => 'userfiles/modules/{$install_item_dir}/templates/',
@@ -18,13 +20,10 @@ class MicroweberInstaller extends BaseInstaller
18
  * For package type microweber-module, cut off a trailing '-module' if present
19
  *
20
  * For package type microweber-template, cut off a trailing '-template' if present.
21
- *
22
  */
23
- public function inflectPackageVars($vars)
24
  {
25
-
26
-
27
- if ($this->package->getTargetDir()) {
28
  $vars['install_item_dir'] = $this->package->getTargetDir();
29
  } else {
30
  $vars['install_item_dir'] = $vars['name'];
@@ -54,65 +53,92 @@ class MicroweberInstaller extends BaseInstaller
54
  }
55
  }
56
 
57
-
58
  return $vars;
59
  }
60
 
61
- protected function inflectTemplateVars($vars)
 
 
 
 
62
  {
63
- $vars['install_item_dir'] = preg_replace('/-template$/', '', $vars['install_item_dir']);
64
- $vars['install_item_dir'] = preg_replace('/template-$/', '', $vars['install_item_dir']);
65
 
66
  return $vars;
67
  }
68
 
69
- protected function inflectTemplatesVars($vars)
 
 
 
 
70
  {
71
- $vars['install_item_dir'] = preg_replace('/-templates$/', '', $vars['install_item_dir']);
72
- $vars['install_item_dir'] = preg_replace('/templates-$/', '', $vars['install_item_dir']);
73
 
74
  return $vars;
75
  }
76
 
77
- protected function inflectCoreVars($vars)
 
 
 
 
78
  {
79
- $vars['install_item_dir'] = preg_replace('/-providers$/', '', $vars['install_item_dir']);
80
- $vars['install_item_dir'] = preg_replace('/-provider$/', '', $vars['install_item_dir']);
81
- $vars['install_item_dir'] = preg_replace('/-adapter$/', '', $vars['install_item_dir']);
82
 
83
  return $vars;
84
  }
85
 
86
- protected function inflectModuleVars($vars)
 
 
 
 
87
  {
88
- $vars['install_item_dir'] = preg_replace('/-module$/', '', $vars['install_item_dir']);
89
- $vars['install_item_dir'] = preg_replace('/module-$/', '', $vars['install_item_dir']);
90
 
91
  return $vars;
92
  }
93
 
94
- protected function inflectModulesVars($vars)
 
 
 
 
95
  {
96
- $vars['install_item_dir'] = preg_replace('/-modules$/', '', $vars['install_item_dir']);
97
- $vars['install_item_dir'] = preg_replace('/modules-$/', '', $vars['install_item_dir']);
98
 
99
  return $vars;
100
  }
101
 
102
- protected function inflectSkinVars($vars)
 
 
 
 
103
  {
104
- $vars['install_item_dir'] = preg_replace('/-skin$/', '', $vars['install_item_dir']);
105
- $vars['install_item_dir'] = preg_replace('/skin-$/', '', $vars['install_item_dir']);
106
 
107
  return $vars;
108
  }
109
 
110
- protected function inflectElementVars($vars)
 
 
 
 
111
  {
112
- $vars['install_item_dir'] = preg_replace('/-elements$/', '', $vars['install_item_dir']);
113
- $vars['install_item_dir'] = preg_replace('/elements-$/', '', $vars['install_item_dir']);
114
- $vars['install_item_dir'] = preg_replace('/-element$/', '', $vars['install_item_dir']);
115
- $vars['install_item_dir'] = preg_replace('/element-$/', '', $vars['install_item_dir']);
116
 
117
  return $vars;
118
  }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class MicroweberInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'userfiles/modules/{$install_item_dir}/',
10
  'module-skin' => 'userfiles/modules/{$install_item_dir}/templates/',
20
  * For package type microweber-module, cut off a trailing '-module' if present
21
  *
22
  * For package type microweber-template, cut off a trailing '-template' if present.
 
23
  */
24
+ public function inflectPackageVars(array $vars): array
25
  {
26
+ if ($this->package->getTargetDir() !== null && $this->package->getTargetDir() !== '') {
 
 
27
  $vars['install_item_dir'] = $this->package->getTargetDir();
28
  } else {
29
  $vars['install_item_dir'] = $vars['name'];
53
  }
54
  }
55
 
 
56
  return $vars;
57
  }
58
 
59
+ /**
60
+ * @param array<string, string> $vars
61
+ * @return array<string, string>
62
+ */
63
+ protected function inflectTemplateVars(array $vars): array
64
  {
65
+ $vars['install_item_dir'] = $this->pregReplace('/-template$/', '', $vars['install_item_dir']);
66
+ $vars['install_item_dir'] = $this->pregReplace('/template-$/', '', $vars['install_item_dir']);
67
 
68
  return $vars;
69
  }
70
 
71
+ /**
72
+ * @param array<string, string> $vars
73
+ * @return array<string, string>
74
+ */
75
+ protected function inflectTemplatesVars(array $vars): array
76
  {
77
+ $vars['install_item_dir'] = $this->pregReplace('/-templates$/', '', $vars['install_item_dir']);
78
+ $vars['install_item_dir'] = $this->pregReplace('/templates-$/', '', $vars['install_item_dir']);
79
 
80
  return $vars;
81
  }
82
 
83
+ /**
84
+ * @param array<string, string> $vars
85
+ * @return array<string, string>
86
+ */
87
+ protected function inflectCoreVars(array $vars): array
88
  {
89
+ $vars['install_item_dir'] = $this->pregReplace('/-providers$/', '', $vars['install_item_dir']);
90
+ $vars['install_item_dir'] = $this->pregReplace('/-provider$/', '', $vars['install_item_dir']);
91
+ $vars['install_item_dir'] = $this->pregReplace('/-adapter$/', '', $vars['install_item_dir']);
92
 
93
  return $vars;
94
  }
95
 
96
+ /**
97
+ * @param array<string, string> $vars
98
+ * @return array<string, string>
99
+ */
100
+ protected function inflectModuleVars(array $vars): array
101
  {
102
+ $vars['install_item_dir'] = $this->pregReplace('/-module$/', '', $vars['install_item_dir']);
103
+ $vars['install_item_dir'] = $this->pregReplace('/module-$/', '', $vars['install_item_dir']);
104
 
105
  return $vars;
106
  }
107
 
108
+ /**
109
+ * @param array<string, string> $vars
110
+ * @return array<string, string>
111
+ */
112
+ protected function inflectModulesVars(array $vars): array
113
  {
114
+ $vars['install_item_dir'] = $this->pregReplace('/-modules$/', '', $vars['install_item_dir']);
115
+ $vars['install_item_dir'] = $this->pregReplace('/modules-$/', '', $vars['install_item_dir']);
116
 
117
  return $vars;
118
  }
119
 
120
+ /**
121
+ * @param array<string, string> $vars
122
+ * @return array<string, string>
123
+ */
124
+ protected function inflectSkinVars(array $vars): array
125
  {
126
+ $vars['install_item_dir'] = $this->pregReplace('/-skin$/', '', $vars['install_item_dir']);
127
+ $vars['install_item_dir'] = $this->pregReplace('/skin-$/', '', $vars['install_item_dir']);
128
 
129
  return $vars;
130
  }
131
 
132
+ /**
133
+ * @param array<string, string> $vars
134
+ * @return array<string, string>
135
+ */
136
+ protected function inflectElementVars(array $vars): array
137
  {
138
+ $vars['install_item_dir'] = $this->pregReplace('/-elements$/', '', $vars['install_item_dir']);
139
+ $vars['install_item_dir'] = $this->pregReplace('/elements-$/', '', $vars['install_item_dir']);
140
+ $vars['install_item_dir'] = $this->pregReplace('/-element$/', '', $vars['install_item_dir']);
141
+ $vars['install_item_dir'] = $this->pregReplace('/element-$/', '', $vars['install_item_dir']);
142
 
143
  return $vars;
144
  }
vendor/composer/installers/src/Composer/Installers/ModxInstaller.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  /**
@@ -6,6 +7,7 @@ namespace Composer\Installers;
6
  */
7
  class ModxInstaller extends BaseInstaller
8
  {
 
9
  protected $locations = array(
10
  'extra' => 'core/packages/{$name}/'
11
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  /**
7
  */
8
  class ModxInstaller extends BaseInstaller
9
  {
10
+ /** @var array<string, string> */
11
  protected $locations = array(
12
  'extra' => 'core/packages/{$name}/'
13
  );
vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class MoodleInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'mod' => 'mod/{$name}/',
8
  'admin_report' => 'admin/report/{$name}/',
@@ -11,6 +13,7 @@ class MoodleInstaller extends BaseInstaller
11
  'assignment' => 'mod/assignment/type/{$name}/',
12
  'assignsubmission' => 'mod/assign/submission/{$name}/',
13
  'assignfeedback' => 'mod/assign/feedback/{$name}/',
 
14
  'auth' => 'auth/{$name}/',
15
  'availability' => 'availability/condition/{$name}/',
16
  'block' => 'blocks/{$name}/',
@@ -18,11 +21,14 @@ class MoodleInstaller extends BaseInstaller
18
  'cachestore' => 'cache/stores/{$name}/',
19
  'cachelock' => 'cache/locks/{$name}/',
20
  'calendartype' => 'calendar/type/{$name}/',
 
21
  'fileconverter' => 'files/converter/{$name}/',
22
  'format' => 'course/format/{$name}/',
23
  'coursereport' => 'course/report/{$name}/',
 
24
  'customcertelement' => 'mod/customcert/element/{$name}/',
25
  'datafield' => 'mod/data/field/{$name}/',
 
26
  'datapreset' => 'mod/data/preset/{$name}/',
27
  'editor' => 'lib/editor/{$name}/',
28
  'enrol' => 'enrol/{$name}/',
@@ -35,8 +41,10 @@ class MoodleInstaller extends BaseInstaller
35
  'logstore' => 'admin/tool/log/store/{$name}/',
36
  'ltisource' => 'mod/lti/source/{$name}/',
37
  'ltiservice' => 'mod/lti/service/{$name}/',
 
38
  'message' => 'message/output/{$name}/',
39
  'mnetservice' => 'mnet/service/{$name}/',
 
40
  'plagiarism' => 'plagiarism/{$name}/',
41
  'portfolio' => 'portfolio/{$name}/',
42
  'qbehaviour' => 'question/behaviour/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class MoodleInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'mod' => 'mod/{$name}/',
10
  'admin_report' => 'admin/report/{$name}/',
13
  'assignment' => 'mod/assignment/type/{$name}/',
14
  'assignsubmission' => 'mod/assign/submission/{$name}/',
15
  'assignfeedback' => 'mod/assign/feedback/{$name}/',
16
+ 'antivirus' => 'lib/antivirus/{$name}/',
17
  'auth' => 'auth/{$name}/',
18
  'availability' => 'availability/condition/{$name}/',
19
  'block' => 'blocks/{$name}/',
21
  'cachestore' => 'cache/stores/{$name}/',
22
  'cachelock' => 'cache/locks/{$name}/',
23
  'calendartype' => 'calendar/type/{$name}/',
24
+ 'customfield' => 'customfield/field/{$name}/',
25
  'fileconverter' => 'files/converter/{$name}/',
26
  'format' => 'course/format/{$name}/',
27
  'coursereport' => 'course/report/{$name}/',
28
+ 'contenttype' => 'contentbank/contenttype/{$name}/',
29
  'customcertelement' => 'mod/customcert/element/{$name}/',
30
  'datafield' => 'mod/data/field/{$name}/',
31
+ 'dataformat' => 'dataformat/{$name}/',
32
  'datapreset' => 'mod/data/preset/{$name}/',
33
  'editor' => 'lib/editor/{$name}/',
34
  'enrol' => 'enrol/{$name}/',
41
  'logstore' => 'admin/tool/log/store/{$name}/',
42
  'ltisource' => 'mod/lti/source/{$name}/',
43
  'ltiservice' => 'mod/lti/service/{$name}/',
44
+ 'media' => 'media/player/{$name}/',
45
  'message' => 'message/output/{$name}/',
46
  'mnetservice' => 'mnet/service/{$name}/',
47
+ 'paygw' => 'payment/gateway/{$name}/',
48
  'plagiarism' => 'plagiarism/{$name}/',
49
  'portfolio' => 'portfolio/{$name}/',
50
  'qbehaviour' => 'question/behaviour/{$name}/',
vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class OctoberInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'modules/{$name}/',
8
  'plugin' => 'plugins/{$vendor}/{$name}/',
@@ -15,9 +17,8 @@ class OctoberInstaller extends BaseInstaller
15
  * For package type october-plugin, cut off a trailing '-plugin' if present.
16
  *
17
  * For package type october-theme, cut off a trailing '-theme' if present.
18
- *
19
  */
20
- public function inflectPackageVars($vars)
21
  {
22
  if ($vars['type'] === 'october-plugin') {
23
  return $this->inflectPluginVars($vars);
@@ -30,18 +31,26 @@ class OctoberInstaller extends BaseInstaller
30
  return $vars;
31
  }
32
 
33
- protected function inflectPluginVars($vars)
 
 
 
 
34
  {
35
- $vars['name'] = preg_replace('/^oc-|-plugin$/', '', $vars['name']);
36
- $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']);
37
 
38
  return $vars;
39
  }
40
 
41
- protected function inflectThemeVars($vars)
 
 
 
 
42
  {
43
- $vars['name'] = preg_replace('/^oc-|-theme$/', '', $vars['name']);
44
- $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']);
45
 
46
  return $vars;
47
  }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class OctoberInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'modules/{$name}/',
10
  'plugin' => 'plugins/{$vendor}/{$name}/',
17
  * For package type october-plugin, cut off a trailing '-plugin' if present.
18
  *
19
  * For package type october-theme, cut off a trailing '-theme' if present.
 
20
  */
21
+ public function inflectPackageVars(array $vars): array
22
  {
23
  if ($vars['type'] === 'october-plugin') {
24
  return $this->inflectPluginVars($vars);
31
  return $vars;
32
  }
33
 
34
+ /**
35
+ * @param array<string, string> $vars
36
+ * @return array<string, string>
37
+ */
38
+ protected function inflectPluginVars(array $vars): array
39
  {
40
+ $vars['name'] = $this->pregReplace('/^oc-|-plugin$/', '', $vars['name']);
41
+ $vars['vendor'] = $this->pregReplace('/[^a-z0-9_]/i', '', $vars['vendor']);
42
 
43
  return $vars;
44
  }
45
 
46
+ /**
47
+ * @param array<string, string> $vars
48
+ * @return array<string, string>
49
+ */
50
+ protected function inflectThemeVars(array $vars): array
51
  {
52
+ $vars['name'] = $this->pregReplace('/^oc-|-theme$/', '', $vars['name']);
53
+ $vars['vendor'] = $this->pregReplace('/[^a-z0-9_]/i', '', $vars['vendor']);
54
 
55
  return $vars;
56
  }
vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class OntoWikiInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'extension' => 'extensions/{$name}/',
8
  'theme' => 'extensions/themes/{$name}/',
@@ -12,12 +14,12 @@ class OntoWikiInstaller extends BaseInstaller
12
  /**
13
  * Format package name to lower case and remove ".ontowiki" suffix
14
  */
15
- public function inflectPackageVars($vars)
16
  {
17
  $vars['name'] = strtolower($vars['name']);
18
- $vars['name'] = preg_replace('/.ontowiki$/', '', $vars['name']);
19
- $vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
20
- $vars['name'] = preg_replace('/-translation$/', '', $vars['name']);
21
 
22
  return $vars;
23
  }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class OntoWikiInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'extension' => 'extensions/{$name}/',
10
  'theme' => 'extensions/themes/{$name}/',
14
  /**
15
  * Format package name to lower case and remove ".ontowiki" suffix
16
  */
17
+ public function inflectPackageVars(array $vars): array
18
  {
19
  $vars['name'] = strtolower($vars['name']);
20
+ $vars['name'] = $this->pregReplace('/.ontowiki$/', '', $vars['name']);
21
+ $vars['name'] = $this->pregReplace('/-theme$/', '', $vars['name']);
22
+ $vars['name'] = $this->pregReplace('/-translation$/', '', $vars['name']);
23
 
24
  return $vars;
25
  }
vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php CHANGED
@@ -1,14 +1,14 @@
1
  <?php
2
- namespace Composer\Installers;
3
 
 
4
 
5
- class OsclassInstaller extends BaseInstaller
6
  {
7
 
 
8
  protected $locations = array(
9
  'plugin' => 'oc-content/plugins/{$name}/',
10
  'theme' => 'oc-content/themes/{$name}/',
11
  'language' => 'oc-content/languages/{$name}/',
12
  );
13
-
14
  }
1
  <?php
 
2
 
3
+ namespace Composer\Installers;
4
 
5
+ class OsclassInstaller extends BaseInstaller
6
  {
7
 
8
+ /** @var array<string, string> */
9
  protected $locations = array(
10
  'plugin' => 'oc-content/plugins/{$name}/',
11
  'theme' => 'oc-content/themes/{$name}/',
12
  'language' => 'oc-content/languages/{$name}/',
13
  );
 
14
  }
vendor/composer/installers/src/Composer/Installers/OxidInstaller.php CHANGED
@@ -1,59 +1,49 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  use Composer\Package\PackageInterface;
5
 
6
  class OxidInstaller extends BaseInstaller
7
  {
8
- const VENDOR_PATTERN = '/^modules\/(?P<vendor>.+)\/.+/';
9
 
 
10
  protected $locations = array(
11
  'module' => 'modules/{$name}/',
12
  'theme' => 'application/views/{$name}/',
13
  'out' => 'out/{$name}/',
14
  );
15
 
16
- /**
17
- * getInstallPath
18
- *
19
- * @param PackageInterface $package
20
- * @param string $frameworkType
21
- * @return string
22
- */
23
- public function getInstallPath(PackageInterface $package, $frameworkType = '')
24
- {
25
- $installPath = parent::getInstallPath($package, $frameworkType);
26
- $type = $this->package->getType();
27
- if ($type === 'oxid-module') {
28
- $this->prepareVendorDirectory($installPath);
29
- }
30
- return $installPath;
31
- }
32
-
33
- /**
34
- * prepareVendorDirectory
35
- *
36
- * Makes sure there is a vendormetadata.php file inside
37
- * the vendor folder if there is a vendor folder.
38
- *
39
- * @param string $installPath
40
- * @return void
41
- */
42
- protected function prepareVendorDirectory($installPath)
43
- {
44
- $matches = '';
45
- $hasVendorDirectory = preg_match(self::VENDOR_PATTERN, $installPath, $matches);
46
- if (!$hasVendorDirectory) {
47
- return;
48
- }
49
-
50
- $vendorDirectory = $matches['vendor'];
51
- $vendorPath = getcwd() . '/modules/' . $vendorDirectory;
52
- if (!file_exists($vendorPath)) {
53
- mkdir($vendorPath, 0755, true);
54
- }
55
-
56
- $vendorMetaDataPath = $vendorPath . '/vendormetadata.php';
57
- touch($vendorMetaDataPath);
58
- }
59
  }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  use Composer\Package\PackageInterface;
6
 
7
  class OxidInstaller extends BaseInstaller
8
  {
9
+ const VENDOR_PATTERN = '/^modules\/(?P<vendor>.+)\/.+/';
10
 
11
+ /** @var array<string, string> */
12
  protected $locations = array(
13
  'module' => 'modules/{$name}/',
14
  'theme' => 'application/views/{$name}/',
15
  'out' => 'out/{$name}/',
16
  );
17
 
18
+ public function getInstallPath(PackageInterface $package, string $frameworkType = ''): string
19
+ {
20
+ $installPath = parent::getInstallPath($package, $frameworkType);
21
+ $type = $this->package->getType();
22
+ if ($type === 'oxid-module') {
23
+ $this->prepareVendorDirectory($installPath);
24
+ }
25
+ return $installPath;
26
+ }
27
+
28
+ /**
29
+ * Makes sure there is a vendormetadata.php file inside
30
+ * the vendor folder if there is a vendor folder.
31
+ */
32
+ protected function prepareVendorDirectory(string $installPath): void
33
+ {
34
+ $matches = '';
35
+ $hasVendorDirectory = preg_match(self::VENDOR_PATTERN, $installPath, $matches);
36
+ if (!$hasVendorDirectory) {
37
+ return;
38
+ }
39
+
40
+ $vendorDirectory = $matches['vendor'];
41
+ $vendorPath = getcwd() . '/modules/' . $vendorDirectory;
42
+ if (!file_exists($vendorPath)) {
43
+ mkdir($vendorPath, 0755, true);
44
+ }
45
+
46
+ $vendorMetaDataPath = $vendorPath . '/vendormetadata.php';
47
+ touch($vendorMetaDataPath);
48
+ }
 
 
 
 
 
 
 
 
 
 
 
 
49
  }
vendor/composer/installers/src/Composer/Installers/PPIInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class PPIInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'modules/{$name}/',
8
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class PPIInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'modules/{$name}/',
10
  );
vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class PhiftyInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'bundle' => 'bundles/{$name}/',
8
  'library' => 'libraries/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class PhiftyInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'bundle' => 'bundles/{$name}/',
10
  'library' => 'libraries/{$name}/',
vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class PhpBBInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'extension' => 'ext/{$vendor}/{$name}/',
8
  'language' => 'language/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class PhpBBInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'extension' => 'ext/{$vendor}/{$name}/',
10
  'language' => 'language/{$name}/',
vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  /**
@@ -8,22 +9,17 @@ namespace Composer\Installers;
8
  */
9
  class PiwikInstaller extends BaseInstaller
10
  {
11
- /**
12
- * @var array
13
- */
14
  protected $locations = array(
15
  'plugin' => 'plugins/{$name}/',
16
  );
17
 
18
  /**
19
  * Format package name to CamelCase
20
- * @param array $vars
21
- *
22
- * @return array
23
  */
24
- public function inflectPackageVars($vars)
25
  {
26
- $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
27
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
28
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
29
 
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  /**
9
  */
10
  class PiwikInstaller extends BaseInstaller
11
  {
12
+ /** @var array<string, string> */
 
 
13
  protected $locations = array(
14
  'plugin' => 'plugins/{$name}/',
15
  );
16
 
17
  /**
18
  * Format package name to CamelCase
 
 
 
19
  */
20
+ public function inflectPackageVars(array $vars): array
21
  {
22
+ $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
23
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
24
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
25
 
vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php CHANGED
@@ -1,28 +1,27 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class PlentymarketsInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'plugin' => '{$name}/'
8
  );
9
 
10
  /**
11
  * Remove hyphen, "plugin" and format to camelcase
12
- * @param array $vars
13
- *
14
- * @return array
15
  */
16
- public function inflectPackageVars($vars)
17
  {
18
- $vars['name'] = explode("-", $vars['name']);
19
- foreach ($vars['name'] as $key => $name) {
20
- $vars['name'][$key] = ucfirst($vars['name'][$key]);
21
  if (strcasecmp($name, "Plugin") == 0) {
22
- unset($vars['name'][$key]);
23
  }
24
  }
25
- $vars['name'] = implode("",$vars['name']);
26
 
27
  return $vars;
28
  }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class PlentymarketsInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'plugin' => '{$name}/'
10
  );
11
 
12
  /**
13
  * Remove hyphen, "plugin" and format to camelcase
 
 
 
14
  */
15
+ public function inflectPackageVars(array $vars): array
16
  {
17
+ $nameBits = explode("-", $vars['name']);
18
+ foreach ($nameBits as $key => $name) {
19
+ $nameBits[$key] = ucfirst($name);
20
  if (strcasecmp($name, "Plugin") == 0) {
21
+ unset($nameBits[$key]);
22
  }
23
  }
24
+ $vars['name'] = implode('', $nameBits);
25
 
26
  return $vars;
27
  }
vendor/composer/installers/src/Composer/Installers/Plugin.php CHANGED
@@ -8,20 +8,21 @@ use Composer\Plugin\PluginInterface;
8
 
9
  class Plugin implements PluginInterface
10
  {
 
11
  private $installer;
12
 
13
- public function activate(Composer $composer, IOInterface $io)
14
  {
15
  $this->installer = new Installer($io, $composer);
16
  $composer->getInstallationManager()->addInstaller($this->installer);
17
  }
18
 
19
- public function deactivate(Composer $composer, IOInterface $io)
20
  {
21
  $composer->getInstallationManager()->removeInstaller($this->installer);
22
  }
23
 
24
- public function uninstall(Composer $composer, IOInterface $io)
25
  {
26
  }
27
  }
8
 
9
  class Plugin implements PluginInterface
10
  {
11
+ /** @var Installer */
12
  private $installer;
13
 
14
+ public function activate(Composer $composer, IOInterface $io): void
15
  {
16
  $this->installer = new Installer($io, $composer);
17
  $composer->getInstallationManager()->addInstaller($this->installer);
18
  }
19
 
20
+ public function deactivate(Composer $composer, IOInterface $io): void
21
  {
22
  $composer->getInstallationManager()->removeInstaller($this->installer);
23
  }
24
 
25
+ public function uninstall(Composer $composer, IOInterface $io): void
26
  {
27
  }
28
  }
vendor/composer/installers/src/Composer/Installers/PortoInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class PortoInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'container' => 'app/Containers/{$name}/',
8
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class PortoInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'container' => 'app/Containers/{$name}/',
10
  );
vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class PrestashopInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'modules/{$name}/',
8
  'theme' => 'themes/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class PrestashopInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'modules/{$name}/',
10
  'theme' => 'themes/{$name}/',
vendor/composer/installers/src/Composer/Installers/ProcessWireInstaller.php CHANGED
@@ -4,6 +4,7 @@ namespace Composer\Installers;
4
 
5
  class ProcessWireInstaller extends BaseInstaller
6
  {
 
7
  protected $locations = array(
8
  'module' => 'site/modules/{$name}/',
9
  );
@@ -11,9 +12,9 @@ class ProcessWireInstaller extends BaseInstaller
11
  /**
12
  * Format package name to CamelCase
13
  */
14
- public function inflectPackageVars($vars)
15
  {
16
- $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
17
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
18
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
19
 
4
 
5
  class ProcessWireInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'site/modules/{$name}/',
10
  );
12
  /**
13
  * Format package name to CamelCase
14
  */
15
+ public function inflectPackageVars(array $vars): array
16
  {
17
+ $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
18
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
19
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
20
 
vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php CHANGED
@@ -5,6 +5,7 @@ namespace Composer\Installers;
5
  class PuppetInstaller extends BaseInstaller
6
  {
7
 
 
8
  protected $locations = array(
9
  'module' => 'modules/{$name}/',
10
  );
5
  class PuppetInstaller extends BaseInstaller
6
  {
7
 
8
+ /** @var array<string, string> */
9
  protected $locations = array(
10
  'module' => 'modules/{$name}/',
11
  );
vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class PxcmsInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'app/Modules/{$name}/',
8
  'theme' => 'themes/{$name}/',
@@ -10,12 +12,8 @@ class PxcmsInstaller extends BaseInstaller
10
 
11
  /**
12
  * Format package name.
13
- *
14
- * @param array $vars
15
- *
16
- * @return array
17
  */
18
- public function inflectPackageVars($vars)
19
  {
20
  if ($vars['type'] === 'pxcms-module') {
21
  return $this->inflectModuleVars($vars);
@@ -31,30 +29,31 @@ class PxcmsInstaller extends BaseInstaller
31
  /**
32
  * For package type pxcms-module, cut off a trailing '-plugin' if present.
33
  *
34
- * return string
 
35
  */
36
- protected function inflectModuleVars($vars)
37
  {
38
  $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy)
39
  $vars['name'] = str_replace('module-', '', $vars['name']); // strip out module-
40
- $vars['name'] = preg_replace('/-module$/', '', $vars['name']); // strip out -module
41
  $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s
42
  $vars['name'] = ucwords($vars['name']); // make module name camelcased
43
 
44
  return $vars;
45
  }
46
 
47
-
48
  /**
49
  * For package type pxcms-module, cut off a trailing '-plugin' if present.
50
  *
51
- * return string
 
52
  */
53
- protected function inflectThemeVars($vars)
54
  {
55
  $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy)
56
  $vars['name'] = str_replace('theme-', '', $vars['name']); // strip out theme-
57
- $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); // strip out -theme
58
  $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s
59
  $vars['name'] = ucwords($vars['name']); // make module name camelcased
60
 
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class PxcmsInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'app/Modules/{$name}/',
10
  'theme' => 'themes/{$name}/',
12
 
13
  /**
14
  * Format package name.
 
 
 
 
15
  */
16
+ public function inflectPackageVars(array $vars): array
17
  {
18
  if ($vars['type'] === 'pxcms-module') {
19
  return $this->inflectModuleVars($vars);
29
  /**
30
  * For package type pxcms-module, cut off a trailing '-plugin' if present.
31
  *
32
+ * @param array<string, string> $vars
33
+ * @return array<string, string>
34
  */
35
+ protected function inflectModuleVars(array $vars): array
36
  {
37
  $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy)
38
  $vars['name'] = str_replace('module-', '', $vars['name']); // strip out module-
39
+ $vars['name'] = $this->pregReplace('/-module$/', '', $vars['name']); // strip out -module
40
  $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s
41
  $vars['name'] = ucwords($vars['name']); // make module name camelcased
42
 
43
  return $vars;
44
  }
45
 
 
46
  /**
47
  * For package type pxcms-module, cut off a trailing '-plugin' if present.
48
  *
49
+ * @param array<string, string> $vars
50
+ * @return array<string, string>
51
  */
52
+ protected function inflectThemeVars(array $vars): array
53
  {
54
  $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy)
55
  $vars['name'] = str_replace('theme-', '', $vars['name']); // strip out theme-
56
+ $vars['name'] = $this->pregReplace('/-theme$/', '', $vars['name']); // strip out -theme
57
  $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s
58
  $vars['name'] = ucwords($vars['name']); // make module name camelcased
59
 
vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class RadPHPInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'bundle' => 'src/{$name}/'
8
  );
@@ -10,11 +12,11 @@ class RadPHPInstaller extends BaseInstaller
10
  /**
11
  * Format package name to CamelCase
12
  */
13
- public function inflectPackageVars($vars)
14
  {
15
  $nameParts = explode('/', $vars['name']);
16
  foreach ($nameParts as &$value) {
17
- $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
18
  $value = str_replace(array('-', '_'), ' ', $value);
19
  $value = str_replace(' ', '', ucwords($value));
20
  }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class RadPHPInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'bundle' => 'src/{$name}/'
10
  );
12
  /**
13
  * Format package name to CamelCase
14
  */
15
+ public function inflectPackageVars(array $vars): array
16
  {
17
  $nameParts = explode('/', $vars['name']);
18
  foreach ($nameParts as &$value) {
19
+ $value = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $value));
20
  $value = str_replace(array('-', '_'), ' ', $value);
21
  $value = str_replace(' ', '', ucwords($value));
22
  }
vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class ReIndexInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'theme' => 'themes/{$name}/',
8
  'plugin' => 'plugins/{$name}/'
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class ReIndexInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'theme' => 'themes/{$name}/',
10
  'plugin' => 'plugins/{$name}/'
vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class Redaxo5Installer extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'addon' => 'redaxo/src/addons/{$name}/',
8
  'bestyle-plugin' => 'redaxo/src/addons/be_style/plugins/{$name}/'
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class Redaxo5Installer extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'addon' => 'redaxo/src/addons/{$name}/',
10
  'bestyle-plugin' => 'redaxo/src/addons/be_style/plugins/{$name}/'
vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class RedaxoInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'addon' => 'redaxo/include/addons/{$name}/',
8
  'bestyle-plugin' => 'redaxo/include/addons/be_style/plugins/{$name}/'
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class RedaxoInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'addon' => 'redaxo/include/addons/{$name}/',
10
  'bestyle-plugin' => 'redaxo/include/addons/be_style/plugins/{$name}/'
vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php CHANGED
@@ -1,19 +1,18 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class RoundcubeInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'plugin' => 'plugins/{$name}/',
8
  );
9
 
10
  /**
11
  * Lowercase name and changes the name to a underscores
12
- *
13
- * @param array $vars
14
- * @return array
15
  */
16
- public function inflectPackageVars($vars)
17
  {
18
  $vars['name'] = strtolower(str_replace('-', '_', $vars['name']));
19
 
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class RoundcubeInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'plugin' => 'plugins/{$name}/',
10
  );
11
 
12
  /**
13
  * Lowercase name and changes the name to a underscores
 
 
 
14
  */
15
+ public function inflectPackageVars(array $vars): array
16
  {
17
  $vars['name'] = strtolower(str_replace('-', '_', $vars['name']));
18
 
vendor/composer/installers/src/Composer/Installers/SMFInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class SMFInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'Sources/{$name}/',
8
  'theme' => 'Themes/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class SMFInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'Sources/{$name}/',
10
  'theme' => 'Themes/{$name}/',
vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  /**
@@ -7,6 +8,7 @@ namespace Composer\Installers;
7
  */
8
  class ShopwareInstaller extends BaseInstaller
9
  {
 
10
  protected $locations = array(
11
  'backend-plugin' => 'engine/Shopware/Plugins/Local/Backend/{$name}/',
12
  'core-plugin' => 'engine/Shopware/Plugins/Local/Core/{$name}/',
@@ -18,29 +20,32 @@ class ShopwareInstaller extends BaseInstaller
18
 
19
  /**
20
  * Transforms the names
21
- * @param array $vars
22
- * @return array
23
  */
24
- public function inflectPackageVars($vars)
25
  {
26
  if ($vars['type'] === 'shopware-theme') {
27
  return $this->correctThemeName($vars);
28
  }
29
 
30
- return $this->correctPluginName($vars);
31
  }
32
 
33
  /**
34
  * Changes the name to a camelcased combination of vendor and name
35
- * @param array $vars
36
- * @return array
 
37
  */
38
- private function correctPluginName($vars)
39
  {
40
  $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) {
41
  return strtoupper($matches[0][1]);
42
  }, $vars['name']);
43
 
 
 
 
 
44
  $vars['name'] = ucfirst($vars['vendor']) . ucfirst($camelCasedName);
45
 
46
  return $vars;
@@ -48,10 +53,11 @@ class ShopwareInstaller extends BaseInstaller
48
 
49
  /**
50
  * Changes the name to a underscore separated name
51
- * @param array $vars
52
- * @return array
 
53
  */
54
- private function correctThemeName($vars)
55
  {
56
  $vars['name'] = str_replace('-', '_', $vars['name']);
57
 
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  /**
8
  */
9
  class ShopwareInstaller extends BaseInstaller
10
  {
11
+ /** @var array<string, string> */
12
  protected $locations = array(
13
  'backend-plugin' => 'engine/Shopware/Plugins/Local/Backend/{$name}/',
14
  'core-plugin' => 'engine/Shopware/Plugins/Local/Core/{$name}/',
20
 
21
  /**
22
  * Transforms the names
 
 
23
  */
24
+ public function inflectPackageVars(array $vars): array
25
  {
26
  if ($vars['type'] === 'shopware-theme') {
27
  return $this->correctThemeName($vars);
28
  }
29
 
30
+ return $this->correctPluginName($vars);
31
  }
32
 
33
  /**
34
  * Changes the name to a camelcased combination of vendor and name
35
+ *
36
+ * @param array<string, string> $vars
37
+ * @return array<string, string>
38
  */
39
+ private function correctPluginName(array $vars): array
40
  {
41
  $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) {
42
  return strtoupper($matches[0][1]);
43
  }, $vars['name']);
44
 
45
+ if (null === $camelCasedName) {
46
+ throw new \RuntimeException('Failed to run preg_replace_callback: '.preg_last_error());
47
+ }
48
+
49
  $vars['name'] = ucfirst($vars['vendor']) . ucfirst($camelCasedName);
50
 
51
  return $vars;
53
 
54
  /**
55
  * Changes the name to a underscore separated name
56
+ *
57
+ * @param array<string, string> $vars
58
+ * @return array<string, string>
59
  */
60
+ private function correctThemeName(array $vars): array
61
  {
62
  $vars['name'] = str_replace('-', '_', $vars['name']);
63
 
vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php CHANGED
@@ -1,10 +1,12 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  use Composer\Package\PackageInterface;
5
 
6
  class SilverStripeInstaller extends BaseInstaller
7
  {
 
8
  protected $locations = array(
9
  'module' => '{$name}/',
10
  'theme' => 'themes/{$name}/',
@@ -15,12 +17,8 @@ class SilverStripeInstaller extends BaseInstaller
15
  *
16
  * Relies on built-in BaseInstaller behaviour with one exception: silverstripe/framework
17
  * must be installed to 'sapphire' and not 'framework' if the version is <3.0.0
18
- *
19
- * @param PackageInterface $package
20
- * @param string $frameworkType
21
- * @return string
22
  */
23
- public function getInstallPath(PackageInterface $package, $frameworkType = '')
24
  {
25
  if (
26
  $package->getName() == 'silverstripe/framework'
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  use Composer\Package\PackageInterface;
6
 
7
  class SilverStripeInstaller extends BaseInstaller
8
  {
9
+ /** @var array<string, string> */
10
  protected $locations = array(
11
  'module' => '{$name}/',
12
  'theme' => 'themes/{$name}/',
17
  *
18
  * Relies on built-in BaseInstaller behaviour with one exception: silverstripe/framework
19
  * must be installed to 'sapphire' and not 'framework' if the version is <3.0.0
 
 
 
 
20
  */
21
+ public function getInstallPath(PackageInterface $package, string $frameworkType = ''): string
22
  {
23
  if (
24
  $package->getName() == 'silverstripe/framework'
vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php CHANGED
@@ -4,17 +4,26 @@ namespace Composer\Installers;
4
 
5
  class SiteDirectInstaller extends BaseInstaller
6
  {
 
7
  protected $locations = array(
8
  'module' => 'modules/{$vendor}/{$name}/',
9
  'plugin' => 'plugins/{$vendor}/{$name}/'
10
  );
11
 
12
- public function inflectPackageVars($vars)
 
 
 
 
13
  {
14
  return $this->parseVars($vars);
15
  }
16
 
17
- protected function parseVars($vars)
 
 
 
 
18
  {
19
  $vars['vendor'] = strtolower($vars['vendor']) == 'sitedirect' ? 'SiteDirect' : $vars['vendor'];
20
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
4
 
5
  class SiteDirectInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'modules/{$vendor}/{$name}/',
10
  'plugin' => 'plugins/{$vendor}/{$name}/'
11
  );
12
 
13
+ /**
14
+ * @param array<string, string> $vars
15
+ * @return array<string, string>
16
+ */
17
+ public function inflectPackageVars(array $vars): array
18
  {
19
  return $this->parseVars($vars);
20
  }
21
 
22
+ /**
23
+ * @param array<string, string> $vars
24
+ * @return array<string, string>
25
+ */
26
+ protected function parseVars(array $vars): array
27
  {
28
  $vars['vendor'] = strtolower($vars['vendor']) == 'sitedirect' ? 'SiteDirect' : $vars['vendor'];
29
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
vendor/composer/installers/src/Composer/Installers/StarbugInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class StarbugInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'modules/{$name}/',
8
  'theme' => 'themes/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class StarbugInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'modules/{$name}/',
10
  'theme' => 'themes/{$name}/',
vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class SyDESInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'app/modules/{$name}/',
8
  'theme' => 'themes/{$name}/',
@@ -12,10 +14,8 @@ class SyDESInstaller extends BaseInstaller
12
  * Format module name.
13
  *
14
  * Strip `sydes-` prefix and a trailing '-theme' or '-module' from package name if present.
15
- *
16
- * {@inerhitDoc}
17
  */
18
- public function inflectPackageVars($vars)
19
  {
20
  if ($vars['type'] == 'sydes-module') {
21
  return $this->inflectModuleVars($vars);
@@ -28,18 +28,26 @@ class SyDESInstaller extends BaseInstaller
28
  return $vars;
29
  }
30
 
31
- public function inflectModuleVars($vars)
 
 
 
 
32
  {
33
- $vars['name'] = preg_replace('/(^sydes-|-module$)/i', '', $vars['name']);
34
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
35
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
36
 
37
  return $vars;
38
  }
39
 
40
- protected function inflectThemeVars($vars)
 
 
 
 
41
  {
42
- $vars['name'] = preg_replace('/(^sydes-|-theme$)/', '', $vars['name']);
43
  $vars['name'] = strtolower($vars['name']);
44
 
45
  return $vars;
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class SyDESInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'app/modules/{$name}/',
10
  'theme' => 'themes/{$name}/',
14
  * Format module name.
15
  *
16
  * Strip `sydes-` prefix and a trailing '-theme' or '-module' from package name if present.
 
 
17
  */
18
+ public function inflectPackageVars(array $vars): array
19
  {
20
  if ($vars['type'] == 'sydes-module') {
21
  return $this->inflectModuleVars($vars);
28
  return $vars;
29
  }
30
 
31
+ /**
32
+ * @param array<string, string> $vars
33
+ * @return array<string, string>
34
+ */
35
+ public function inflectModuleVars(array $vars): array
36
  {
37
+ $vars['name'] = $this->pregReplace('/(^sydes-|-module$)/i', '', $vars['name']);
38
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
39
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
40
 
41
  return $vars;
42
  }
43
 
44
+ /**
45
+ * @param array<string, string> $vars
46
+ * @return array<string, string>
47
+ */
48
+ protected function inflectThemeVars(array $vars): array
49
  {
50
+ $vars['name'] = $this->pregReplace('/(^sydes-|-theme$)/', '', $vars['name']);
51
  $vars['name'] = strtolower($vars['name']);
52
 
53
  return $vars;
vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class SyliusInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'theme' => 'themes/{$name}/',
8
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class SyliusInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'theme' => 'themes/{$name}/',
10
  );
vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
- namespace Composer\Installers;
3
-
4
- /**
5
- * Plugin installer for symfony 1.x
6
- *
7
- * @author Jérôme Tamarelle <jerome@tamarelle.net>
8
- */
9
- class Symfony1Installer extends BaseInstaller
10
- {
11
- protected $locations = array(
12
- 'plugin' => 'plugins/{$name}/',
13
- );
14
-
15
- /**
16
- * Format package name to CamelCase
17
- */
18
- public function inflectPackageVars($vars)
19
- {
20
- $vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) {
21
- return strtoupper($matches[0][1]);
22
- }, $vars['name']);
23
-
24
- return $vars;
25
- }
26
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php DELETED
@@ -1,16 +0,0 @@
1
- <?php
2
- namespace Composer\Installers;
3
-
4
- /**
5
- * Extension installer for TYPO3 CMS
6
- *
7
- * @deprecated since 1.0.25, use https://packagist.org/packages/typo3/cms-composer-installers instead
8
- *
9
- * @author Sascha Egerer <sascha.egerer@dkd.de>
10
- */
11
- class TYPO3CmsInstaller extends BaseInstaller
12
- {
13
- protected $locations = array(
14
- 'extension' => 'typo3conf/ext/{$name}/',
15
- );
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php DELETED
@@ -1,38 +0,0 @@
1
- <?php
2
- namespace Composer\Installers;
3
-
4
- /**
5
- * An installer to handle TYPO3 Flow specifics when installing packages.
6
- */
7
- class TYPO3FlowInstaller extends BaseInstaller
8
- {
9
- protected $locations = array(
10
- 'package' => 'Packages/Application/{$name}/',
11
- 'framework' => 'Packages/Framework/{$name}/',
12
- 'plugin' => 'Packages/Plugins/{$name}/',
13
- 'site' => 'Packages/Sites/{$name}/',
14
- 'boilerplate' => 'Packages/Boilerplates/{$name}/',
15
- 'build' => 'Build/{$name}/',
16
- );
17
-
18
- /**
19
- * Modify the package name to be a TYPO3 Flow style key.
20
- *
21
- * @param array $vars
22
- * @return array
23
- */
24
- public function inflectPackageVars($vars)
25
- {
26
- $autoload = $this->package->getAutoload();
27
- if (isset($autoload['psr-0']) && is_array($autoload['psr-0'])) {
28
- $namespace = key($autoload['psr-0']);
29
- $vars['name'] = str_replace('\\', '.', $namespace);
30
- }
31
- if (isset($autoload['psr-4']) && is_array($autoload['psr-4'])) {
32
- $namespace = key($autoload['psr-4']);
33
- $vars['name'] = rtrim(str_replace('\\', '.', $namespace), '.');
34
- }
35
-
36
- return $vars;
37
- }
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/composer/installers/src/Composer/Installers/TaoInstaller.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  /**
@@ -8,11 +9,12 @@ class TaoInstaller extends BaseInstaller
8
  {
9
  const EXTRA_TAO_EXTENSION_NAME = 'tao-extension-name';
10
 
 
11
  protected $locations = array(
12
  'extension' => '{$name}'
13
  );
14
 
15
- public function inflectPackageVars($vars)
16
  {
17
  $extra = $this->package->getExtra();
18
 
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  /**
9
  {
10
  const EXTRA_TAO_EXTENSION_NAME = 'tao-extension-name';
11
 
12
+ /** @var array<string, string> */
13
  protected $locations = array(
14
  'extension' => '{$name}'
15
  );
16
 
17
+ public function inflectPackageVars(array $vars): array
18
  {
19
  $extra = $this->package->getExtra();
20
 
vendor/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php CHANGED
@@ -4,10 +4,12 @@ namespace Composer\Installers;
4
 
5
  class TastyIgniterInstaller extends BaseInstaller
6
  {
7
- protected $locations = array(
 
 
8
  'extension' => 'extensions/{$vendor}/{$name}/',
9
  'theme' => 'themes/{$name}/',
10
- );
11
 
12
  /**
13
  * Format package name.
@@ -16,17 +18,68 @@ class TastyIgniterInstaller extends BaseInstaller
16
  * Strip vendor name of characters that is not alphanumeric or an underscore
17
  *
18
  */
19
- public function inflectPackageVars($vars)
20
  {
 
 
 
 
 
 
21
  if ($vars['type'] === 'tastyigniter-extension') {
22
- $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']);
23
- $vars['name'] = preg_replace('/^ti-ext-/', '', $vars['name']);
24
  }
25
 
26
  if ($vars['type'] === 'tastyigniter-theme') {
27
- $vars['name'] = preg_replace('/^ti-theme-/', '', $vars['name']);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  }
29
 
 
 
30
  return $vars;
31
  }
32
- }
4
 
5
  class TastyIgniterInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
+ protected $locations = [
9
+ 'module' => 'app/{$name}/',
10
  'extension' => 'extensions/{$vendor}/{$name}/',
11
  'theme' => 'themes/{$name}/',
12
+ ];
13
 
14
  /**
15
  * Format package name.
18
  * Strip vendor name of characters that is not alphanumeric or an underscore
19
  *
20
  */
21
+ public function inflectPackageVars(array $vars): array
22
  {
23
+ $extra = $this->package->getExtra();
24
+
25
+ if ($vars['type'] === 'tastyigniter-module') {
26
+ return $this->inflectModuleVars($vars);
27
+ }
28
+
29
  if ($vars['type'] === 'tastyigniter-extension') {
30
+ return $this->inflectExtensionVars($vars, $extra);
 
31
  }
32
 
33
  if ($vars['type'] === 'tastyigniter-theme') {
34
+ return $this->inflectThemeVars($vars, $extra);
35
+ }
36
+
37
+ return $vars;
38
+ }
39
+
40
+ /**
41
+ * @param array<string, string> $vars
42
+ * @return array<string, string>
43
+ */
44
+ protected function inflectModuleVars(array $vars): array
45
+ {
46
+ $vars['name'] = $this->pregReplace('/^ti-module-/', '', $vars['name']);
47
+
48
+ return $vars;
49
+ }
50
+
51
+ /**
52
+ * @param array<string, string> $vars
53
+ * @param array<string, mixed> $extra
54
+ * @return array<string, string>
55
+ */
56
+ protected function inflectExtensionVars(array $vars, array $extra): array
57
+ {
58
+ if (!empty($extra['tastyigniter-extension']['code'])) {
59
+ $parts = explode('.', $extra['tastyigniter-extension']['code']);
60
+ $vars['vendor'] = (string)$parts[0];
61
+ $vars['name'] = (string)($parts[1] ?? '');
62
+ }
63
+
64
+ $vars['vendor'] = $this->pregReplace('/[^a-z0-9_]/i', '', $vars['vendor']);
65
+ $vars['name'] = $this->pregReplace('/^ti-ext-/', '', $vars['name']);
66
+
67
+ return $vars;
68
+ }
69
+
70
+ /**
71
+ * @param array<string, string> $vars
72
+ * @param array<string, mixed> $extra
73
+ * @return array<string, string>
74
+ */
75
+ protected function inflectThemeVars(array $vars, array $extra): array
76
+ {
77
+ if (!empty($extra['tastyigniter-theme']['code'])) {
78
+ $vars['name'] = $extra['tastyigniter-theme']['code'];
79
  }
80
 
81
+ $vars['name'] = $this->pregReplace('/^ti-theme-/', '', $vars['name']);
82
+
83
  return $vars;
84
  }
85
+ }
vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class TheliaInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'local/modules/{$name}/',
8
  'frontoffice-template' => 'templates/frontOffice/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class TheliaInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'local/modules/{$name}/',
10
  'frontoffice-template' => 'templates/frontOffice/{$name}/',
vendor/composer/installers/src/Composer/Installers/TuskInstaller.php CHANGED
@@ -1,14 +1,17 @@
1
  <?php
2
- namespace Composer\Installers;
3
- /**
4
- * Composer installer for 3rd party Tusk utilities
5
- * @author Drew Ewing <drew@phenocode.com>
6
- */
7
- class TuskInstaller extends BaseInstaller
8
- {
9
- protected $locations = array(
10
- 'task' => '.tusk/tasks/{$name}/',
11
- 'command' => '.tusk/commands/{$name}/',
12
- 'asset' => 'assets/tusk/{$name}/',
13
- );
14
- }
 
 
 
1
  <?php
2
+
3
+ namespace Composer\Installers;
4
+
5
+ /**
6
+ * Composer installer for 3rd party Tusk utilities
7
+ * @author Drew Ewing <drew@phenocode.com>
8
+ */
9
+ class TuskInstaller extends BaseInstaller
10
+ {
11
+ /** @var array<string, string> */
12
+ protected $locations = array(
13
+ 'task' => '.tusk/tasks/{$name}/',
14
+ 'command' => '.tusk/commands/{$name}/',
15
+ 'asset' => 'assets/tusk/{$name}/',
16
+ );
17
+ }
vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class UserFrostingInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'sprinkle' => 'app/sprinkles/{$name}/',
8
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class UserFrostingInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'sprinkle' => 'app/sprinkles/{$name}/',
10
  );
vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class VanillaInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'plugin' => 'plugins/{$name}/',
8
  'theme' => 'themes/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class VanillaInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'plugin' => 'plugins/{$name}/',
10
  'theme' => 'themes/{$name}/',
vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class VgmcpInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'bundle' => 'src/{$vendor}/{$name}/',
8
  'theme' => 'themes/{$name}/'
@@ -16,7 +18,7 @@ class VgmcpInstaller extends BaseInstaller
16
  * For package type vgmcp-theme, cut off a trailing '-theme' if present.
17
  *
18
  */
19
- public function inflectPackageVars($vars)
20
  {
21
  if ($vars['type'] === 'vgmcp-bundle') {
22
  return $this->inflectPluginVars($vars);
@@ -29,18 +31,26 @@ class VgmcpInstaller extends BaseInstaller
29
  return $vars;
30
  }
31
 
32
- protected function inflectPluginVars($vars)
 
 
 
 
33
  {
34
- $vars['name'] = preg_replace('/-bundle$/', '', $vars['name']);
35
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
36
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
37
 
38
  return $vars;
39
  }
40
 
41
- protected function inflectThemeVars($vars)
 
 
 
 
42
  {
43
- $vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
44
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
45
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
46
 
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class VgmcpInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'bundle' => 'src/{$vendor}/{$name}/',
10
  'theme' => 'themes/{$name}/'
18
  * For package type vgmcp-theme, cut off a trailing '-theme' if present.
19
  *
20
  */
21
+ public function inflectPackageVars(array $vars): array
22
  {
23
  if ($vars['type'] === 'vgmcp-bundle') {
24
  return $this->inflectPluginVars($vars);
31
  return $vars;
32
  }
33
 
34
+ /**
35
+ * @param array<string, string> $vars
36
+ * @return array<string, string>
37
+ */
38
+ protected function inflectPluginVars(array $vars): array
39
  {
40
+ $vars['name'] = $this->pregReplace('/-bundle$/', '', $vars['name']);
41
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
42
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
43
 
44
  return $vars;
45
  }
46
 
47
+ /**
48
+ * @param array<string, string> $vars
49
+ * @return array<string, string>
50
+ */
51
+ protected function inflectThemeVars(array $vars): array
52
  {
53
+ $vars['name'] = $this->pregReplace('/-theme$/', '', $vars['name']);
54
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
55
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
56
 
vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php CHANGED
@@ -4,6 +4,7 @@ namespace Composer\Installers;
4
 
5
  class WHMCSInstaller extends BaseInstaller
6
  {
 
7
  protected $locations = array(
8
  'addons' => 'modules/addons/{$vendor}_{$name}/',
9
  'fraud' => 'modules/fraud/{$vendor}_{$name}/',
4
 
5
  class WHMCSInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'addons' => 'modules/addons/{$vendor}_{$name}/',
10
  'fraud' => 'modules/fraud/{$vendor}_{$name}/',
vendor/composer/installers/src/Composer/Installers/WinterInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class WinterInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'modules/{$name}/',
8
  'plugin' => 'plugins/{$vendor}/{$name}/',
@@ -15,9 +17,8 @@ class WinterInstaller extends BaseInstaller
15
  * For package type winter-plugin, cut off a trailing '-plugin' if present.
16
  *
17
  * For package type winter-theme, cut off a trailing '-theme' if present.
18
- *
19
  */
20
- public function inflectPackageVars($vars)
21
  {
22
  if ($vars['type'] === 'winter-module') {
23
  return $this->inflectModuleVars($vars);
@@ -34,24 +35,36 @@ class WinterInstaller extends BaseInstaller
34
  return $vars;
35
  }
36
 
37
- protected function inflectModuleVars($vars)
 
 
 
 
38
  {
39
- $vars['name'] = preg_replace('/^wn-|-module$/', '', $vars['name']);
40
 
41
  return $vars;
42
  }
43
 
44
- protected function inflectPluginVars($vars)
 
 
 
 
45
  {
46
- $vars['name'] = preg_replace('/^wn-|-plugin$/', '', $vars['name']);
47
- $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']);
48
 
49
  return $vars;
50
  }
51
 
52
- protected function inflectThemeVars($vars)
 
 
 
 
53
  {
54
- $vars['name'] = preg_replace('/^wn-|-theme$/', '', $vars['name']);
55
 
56
  return $vars;
57
  }
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class WinterInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'modules/{$name}/',
10
  'plugin' => 'plugins/{$vendor}/{$name}/',
17
  * For package type winter-plugin, cut off a trailing '-plugin' if present.
18
  *
19
  * For package type winter-theme, cut off a trailing '-theme' if present.
 
20
  */
21
+ public function inflectPackageVars(array $vars): array
22
  {
23
  if ($vars['type'] === 'winter-module') {
24
  return $this->inflectModuleVars($vars);
35
  return $vars;
36
  }
37
 
38
+ /**
39
+ * @param array<string, string> $vars
40
+ * @return array<string, string>
41
+ */
42
+ protected function inflectModuleVars(array $vars): array
43
  {
44
+ $vars['name'] = $this->pregReplace('/^wn-|-module$/', '', $vars['name']);
45
 
46
  return $vars;
47
  }
48
 
49
+ /**
50
+ * @param array<string, string> $vars
51
+ * @return array<string, string>
52
+ */
53
+ protected function inflectPluginVars(array $vars): array
54
  {
55
+ $vars['name'] = $this->pregReplace('/^wn-|-plugin$/', '', $vars['name']);
56
+ $vars['vendor'] = $this->pregReplace('/[^a-z0-9_]/i', '', $vars['vendor']);
57
 
58
  return $vars;
59
  }
60
 
61
+ /**
62
+ * @param array<string, string> $vars
63
+ * @return array<string, string>
64
+ */
65
+ protected function inflectThemeVars(array $vars): array
66
  {
67
+ $vars['name'] = $this->pregReplace('/^wn-|-theme$/', '', $vars['name']);
68
 
69
  return $vars;
70
  }
vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class WolfCMSInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'plugin' => 'wolf/plugins/{$name}/',
8
  );
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class WolfCMSInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'plugin' => 'wolf/plugins/{$name}/',
10
  );
vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class WordPressInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'plugin' => 'wp-content/plugins/{$name}/',
8
  'theme' => 'wp-content/themes/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class WordPressInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'plugin' => 'wp-content/plugins/{$name}/',
10
  'theme' => 'wp-content/themes/{$name}/',
vendor/composer/installers/src/Composer/Installers/YawikInstaller.php CHANGED
@@ -1,32 +1,23 @@
1
  <?php
2
- /**
3
- * Created by PhpStorm.
4
- * User: cbleek
5
- * Date: 25.03.16
6
- * Time: 20:55
7
- */
8
 
9
  namespace Composer\Installers;
10
 
11
-
12
  class YawikInstaller extends BaseInstaller
13
  {
 
14
  protected $locations = array(
15
  'module' => 'module/{$name}/',
16
  );
17
 
18
  /**
19
  * Format package name to CamelCase
20
- * @param array $vars
21
- *
22
- * @return array
23
  */
24
- public function inflectPackageVars($vars)
25
  {
26
- $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
27
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
28
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
29
 
30
  return $vars;
31
  }
32
- }
1
  <?php
 
 
 
 
 
 
2
 
3
  namespace Composer\Installers;
4
 
 
5
  class YawikInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'module/{$name}/',
10
  );
11
 
12
  /**
13
  * Format package name to CamelCase
 
 
 
14
  */
15
+ public function inflectPackageVars(array $vars): array
16
  {
17
+ $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
18
  $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
19
  $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
20
 
21
  return $vars;
22
  }
23
+ }
vendor/composer/installers/src/Composer/Installers/ZendInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class ZendInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'library' => 'library/{$name}/',
8
  'extra' => 'extras/library/{$name}/',
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class ZendInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'library' => 'library/{$name}/',
10
  'extra' => 'extras/library/{$name}/',
vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php CHANGED
@@ -1,8 +1,10 @@
1
  <?php
 
2
  namespace Composer\Installers;
3
 
4
  class ZikulaInstaller extends BaseInstaller
5
  {
 
6
  protected $locations = array(
7
  'module' => 'modules/{$vendor}-{$name}/',
8
  'theme' => 'themes/{$vendor}-{$name}/'
1
  <?php
2
+
3
  namespace Composer\Installers;
4
 
5
  class ZikulaInstaller extends BaseInstaller
6
  {
7
+ /** @var array<string, string> */
8
  protected $locations = array(
9
  'module' => 'modules/{$vendor}-{$name}/',
10
  'theme' => 'themes/{$vendor}-{$name}/'
vendor/composer/installers/src/bootstrap.php CHANGED
@@ -1,9 +1,14 @@
1
  <?php
2
- function includeIfExists($file)
 
 
 
3
  {
4
  if (file_exists($file)) {
5
  return include $file;
6
  }
 
 
7
  }
8
  if ((!$loader = includeIfExists(__DIR__ . '/../vendor/autoload.php')) && (!$loader = includeIfExists(__DIR__ . '/../../../autoload.php'))) {
9
  die('You must set up the project dependencies, run the following commands:'.PHP_EOL.
1
  <?php
2
+
3
+ use Composer\Autoload\ClassLoader;
4
+
5
+ function includeIfExists(string $file): ?ClassLoader
6
  {
7
  if (file_exists($file)) {
8
  return include $file;
9
  }
10
+
11
+ return null;
12
  }
13
  if ((!$loader = includeIfExists(__DIR__ . '/../vendor/autoload.php')) && (!$loader = includeIfExists(__DIR__ . '/../../../autoload.php'))) {
14
  die('You must set up the project dependencies, run the following commands:'.PHP_EOL.
vendor/composer/platform_check.php CHANGED
@@ -4,8 +4,8 @@
4
 
5
  $issues = array();
6
 
7
- if (!(PHP_VERSION_ID >= 50600)) {
8
- $issues[] = 'Your Composer dependencies require a PHP version ">= 5.6.0". You are running ' . PHP_VERSION . '.';
9
  }
10
 
11
  if ($issues) {
4
 
5
  $issues = array();
6
 
7
+ if (!(PHP_VERSION_ID >= 70205)) {
8
+ $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.5". You are running ' . PHP_VERSION . '.';
9
  }
10
 
11
  if ($issues) {
vendor/symfony/polyfill-ctype/Ctype.php CHANGED
@@ -25,13 +25,13 @@ final class Ctype
25
  *
26
  * @see https://php.net/ctype-alnum
27
  *
28
- * @param string|int $text
29
  *
30
  * @return bool
31
  */
32
  public static function ctype_alnum($text)
33
  {
34
- $text = self::convert_int_to_char_for_ctype($text);
35
 
36
  return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z0-9]/', $text);
37
  }
@@ -41,13 +41,13 @@ final class Ctype
41
  *
42
  * @see https://php.net/ctype-alpha
43
  *
44
- * @param string|int $text
45
  *
46
  * @return bool
47
  */
48
  public static function ctype_alpha($text)
49
  {
50
- $text = self::convert_int_to_char_for_ctype($text);
51
 
52
  return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z]/', $text);
53
  }
@@ -57,13 +57,13 @@ final class Ctype
57
  *
58
  * @see https://php.net/ctype-cntrl
59
  *
60
- * @param string|int $text
61
  *
62
  * @return bool
63
  */
64
  public static function ctype_cntrl($text)
65
  {
66
- $text = self::convert_int_to_char_for_ctype($text);
67
 
68
  return \is_string($text) && '' !== $text && !preg_match('/[^\x00-\x1f\x7f]/', $text);
69
  }
@@ -73,13 +73,13 @@ final class Ctype
73
  *
74
  * @see https://php.net/ctype-digit
75
  *
76
- * @param string|int $text
77
  *
78
  * @return bool
79
  */
80
  public static function ctype_digit($text)
81
  {
82
- $text = self::convert_int_to_char_for_ctype($text);
83
 
84
  return \is_string($text) && '' !== $text && !preg_match('/[^0-9]/', $text);
85
  }
@@ -89,13 +89,13 @@ final class Ctype
89
  *
90
  * @see https://php.net/ctype-graph
91
  *
92
- * @param string|int $text
93
  *
94
  * @return bool
95
  */
96
  public static function ctype_graph($text)
97
  {
98
- $text = self::convert_int_to_char_for_ctype($text);
99
 
100
  return \is_string($text) && '' !== $text && !preg_match('/[^!-~]/', $text);
101
  }
@@ -105,13 +105,13 @@ final class Ctype
105
  *
106
  * @see https://php.net/ctype-lower
107
  *
108
- * @param string|int $text
109
  *
110
  * @return bool
111
  */
112
  public static function ctype_lower($text)
113
  {
114
- $text = self::convert_int_to_char_for_ctype($text);
115
 
116
  return \is_string($text) && '' !== $text && !preg_match('/[^a-z]/', $text);
117
  }
@@ -121,13 +121,13 @@ final class Ctype
121
  *
122
  * @see https://php.net/ctype-print
123
  *
124
- * @param string|int $text
125
  *
126
  * @return bool
127
  */
128
  public static function ctype_print($text)
129
  {
130
- $text = self::convert_int_to_char_for_ctype($text);
131
 
132
  return \is_string($text) && '' !== $text && !preg_match('/[^ -~]/', $text);
133
  }
@@ -137,13 +137,13 @@ final class Ctype
137
  *
138
  * @see https://php.net/ctype-punct
139
  *
140
- * @param string|int $text
141
  *
142
  * @return bool
143
  */
144
  public static function ctype_punct($text)
145
  {
146
- $text = self::convert_int_to_char_for_ctype($text);
147
 
148
  return \is_string($text) && '' !== $text && !preg_match('/[^!-\/\:-@\[-`\{-~]/', $text);
149
  }
@@ -153,13 +153,13 @@ final class Ctype
153
  *
154
  * @see https://php.net/ctype-space
155
  *
156
- * @param string|int $text
157
  *
158
  * @return bool
159
  */
160
  public static function ctype_space($text)
161
  {
162
- $text = self::convert_int_to_char_for_ctype($text);
163
 
164
  return \is_string($text) && '' !== $text && !preg_match('/[^\s]/', $text);
165
  }
@@ -169,13 +169,13 @@ final class Ctype
169
  *
170
  * @see https://php.net/ctype-upper
171
  *
172
- * @param string|int $text
173
  *
174
  * @return bool
175
  */
176
  public static function ctype_upper($text)
177
  {
178
- $text = self::convert_int_to_char_for_ctype($text);
179
 
180
  return \is_string($text) && '' !== $text && !preg_match('/[^A-Z]/', $text);
181
  }
@@ -185,13 +185,13 @@ final class Ctype
185
  *
186
  * @see https://php.net/ctype-xdigit
187
  *
188
- * @param string|int $text
189
  *
190
  * @return bool
191
  */
192
  public static function ctype_xdigit($text)
193
  {
194
- $text = self::convert_int_to_char_for_ctype($text);
195
 
196
  return \is_string($text) && '' !== $text && !preg_match('/[^A-Fa-f0-9]/', $text);
197
  }
@@ -204,11 +204,12 @@ final class Ctype
204
  * (negative values have 256 added in order to allow characters in the Extended ASCII range).
205
  * Any other integer is interpreted as a string containing the decimal digits of the integer.
206
  *
207
- * @param string|int $int
 
208
  *
209
  * @return mixed
210
  */
211
- private static function convert_int_to_char_for_ctype($int)
212
  {
213
  if (!\is_int($int)) {
214
  return $int;
@@ -218,6 +219,10 @@ final class Ctype
218
  return (string) $int;
219
  }
220
 
 
 
 
 
221
  if ($int < 0) {
222
  $int += 256;
223
  }
25
  *
26
  * @see https://php.net/ctype-alnum
27
  *
28
+ * @param mixed $text
29
  *
30
  * @return bool
31
  */
32
  public static function ctype_alnum($text)
33
  {
34
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
35
 
36
  return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z0-9]/', $text);
37
  }
41
  *
42
  * @see https://php.net/ctype-alpha
43
  *
44
+ * @param mixed $text
45
  *
46
  * @return bool
47
  */
48
  public static function ctype_alpha($text)
49
  {
50
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
51
 
52
  return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z]/', $text);
53
  }
57
  *
58
  * @see https://php.net/ctype-cntrl
59
  *
60
+ * @param mixed $text
61
  *
62
  * @return bool
63
  */
64
  public static function ctype_cntrl($text)
65
  {
66
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
67
 
68
  return \is_string($text) && '' !== $text && !preg_match('/[^\x00-\x1f\x7f]/', $text);
69
  }
73
  *
74
  * @see https://php.net/ctype-digit
75
  *
76
+ * @param mixed $text
77
  *
78
  * @return bool
79
  */
80
  public static function ctype_digit($text)
81
  {
82
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
83
 
84
  return \is_string($text) && '' !== $text && !preg_match('/[^0-9]/', $text);
85
  }
89
  *
90
  * @see https://php.net/ctype-graph
91
  *
92
+ * @param mixed $text
93
  *
94
  * @return bool
95
  */
96
  public static function ctype_graph($text)
97
  {
98
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
99
 
100
  return \is_string($text) && '' !== $text && !preg_match('/[^!-~]/', $text);
101
  }
105
  *
106
  * @see https://php.net/ctype-lower
107
  *
108
+ * @param mixed $text
109
  *
110
  * @return bool
111
  */
112
  public static function ctype_lower($text)
113
  {
114
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
115
 
116
  return \is_string($text) && '' !== $text && !preg_match('/[^a-z]/', $text);
117
  }
121
  *
122
  * @see https://php.net/ctype-print
123
  *
124
+ * @param mixed $text
125
  *
126
  * @return bool
127
  */
128
  public static function ctype_print($text)
129
  {
130
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
131
 
132
  return \is_string($text) && '' !== $text && !preg_match('/[^ -~]/', $text);
133
  }
137
  *
138
  * @see https://php.net/ctype-punct
139
  *
140
+ * @param mixed $text
141
  *
142
  * @return bool
143
  */
144
  public static function ctype_punct($text)
145
  {
146
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
147
 
148
  return \is_string($text) && '' !== $text && !preg_match('/[^!-\/\:-@\[-`\{-~]/', $text);
149
  }
153
  *
154
  * @see https://php.net/ctype-space
155
  *
156
+ * @param mixed $text
157
  *
158
  * @return bool
159
  */
160
  public static function ctype_space($text)
161
  {
162
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
163
 
164
  return \is_string($text) && '' !== $text && !preg_match('/[^\s]/', $text);
165
  }
169
  *
170
  * @see https://php.net/ctype-upper
171
  *
172
+ * @param mixed $text
173
  *
174
  * @return bool
175
  */
176
  public static function ctype_upper($text)
177
  {
178
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
179
 
180
  return \is_string($text) && '' !== $text && !preg_match('/[^A-Z]/', $text);
181
  }
185
  *
186
  * @see https://php.net/ctype-xdigit
187
  *
188
+ * @param mixed $text
189
  *
190
  * @return bool
191
  */
192
  public static function ctype_xdigit($text)
193
  {
194
+ $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
195
 
196
  return \is_string($text) && '' !== $text && !preg_match('/[^A-Fa-f0-9]/', $text);
197
  }
204
  * (negative values have 256 added in order to allow characters in the Extended ASCII range).
205
  * Any other integer is interpreted as a string containing the decimal digits of the integer.
206
  *
207
+ * @param mixed $int
208
+ * @param string $function
209
  *
210
  * @return mixed
211
  */
212
+ private static function convert_int_to_char_for_ctype($int, $function)
213
  {
214
  if (!\is_int($int)) {
215
  return $int;
219
  return (string) $int;
220
  }
221
 
222
+ if (\PHP_VERSION_ID >= 80100) {
223
+ @trigger_error($function.'(): Argument of type int will be interpreted as string in the future', \E_USER_DEPRECATED);
224
+ }
225
+
226
  if ($int < 0) {
227
  $int += 256;
228
  }
vendor/symfony/polyfill-ctype/README.md CHANGED
@@ -4,7 +4,7 @@ Symfony Polyfill / Ctype
4
  This component provides `ctype_*` functions to users who run php versions without the ctype extension.
5
 
6
  More information can be found in the
7
- [main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).
8
 
9
  License
10
  =======
4
  This component provides `ctype_*` functions to users who run php versions without the ctype extension.
5
 
6
  More information can be found in the
7
+ [main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).
8
 
9
  License
10
  =======
vendor/symfony/polyfill-ctype/bootstrap.php CHANGED
@@ -11,36 +11,40 @@
11
 
12
  use Symfony\Polyfill\Ctype as p;
13
 
 
 
 
 
14
  if (!function_exists('ctype_alnum')) {
15
- function ctype_alnum($input) { return p\Ctype::ctype_alnum($input); }
16
  }
17
  if (!function_exists('ctype_alpha')) {
18
- function ctype_alpha($input) { return p\Ctype::ctype_alpha($input); }
19
  }
20
  if (!function_exists('ctype_cntrl')) {
21
- function ctype_cntrl($input) { return p\Ctype::ctype_cntrl($input); }
22
  }
23
  if (!function_exists('ctype_digit')) {
24
- function ctype_digit($input) { return p\Ctype::ctype_digit($input); }
25
  }
26
  if (!function_exists('ctype_graph')) {
27
- function ctype_graph($input) { return p\Ctype::ctype_graph($input); }
28
  }
29
  if (!function_exists('ctype_lower')) {
30
- function ctype_lower($input) { return p\Ctype::ctype_lower($input); }
31
  }
32
  if (!function_exists('ctype_print')) {
33
- function ctype_print($input) { return p\Ctype::ctype_print($input); }
34
  }
35
  if (!function_exists('ctype_punct')) {
36
- function ctype_punct($input) { return p\Ctype::ctype_punct($input); }
37
  }
38
  if (!function_exists('ctype_space')) {
39
- function ctype_space($input) { return p\Ctype::ctype_space($input); }
40
  }
41
  if (!function_exists('ctype_upper')) {
42
- function ctype_upper($input) { return p\Ctype::ctype_upper($input); }
43
  }
44
  if (!function_exists('ctype_xdigit')) {
45
- function ctype_xdigit($input) { return p\Ctype::ctype_xdigit($input); }
46
  }
11
 
12
  use Symfony\Polyfill\Ctype as p;
13
 
14
+ if (\PHP_VERSION_ID >= 80000) {
15
+ return require __DIR__.'/bootstrap80.php';
16
+ }
17
+
18
  if (!function_exists('ctype_alnum')) {
19
+ function ctype_alnum($text) { return p\Ctype::ctype_alnum($text); }
20
  }
21
  if (!function_exists('ctype_alpha')) {
22
+ function ctype_alpha($text) { return p\Ctype::ctype_alpha($text); }
23
  }
24
  if (!function_exists('ctype_cntrl')) {
25
+ function ctype_cntrl($text) { return p\Ctype::ctype_cntrl($text); }
26
  }
27
  if (!function_exists('ctype_digit')) {
28
+ function ctype_digit($text) { return p\Ctype::ctype_digit($text); }
29
  }
30
  if (!function_exists('ctype_graph')) {
31
+ function ctype_graph($text) { return p\Ctype::ctype_graph($text); }
32
  }
33
  if (!function_exists('ctype_lower')) {
34
+ function ctype_lower($text) { return p\Ctype::ctype_lower($text); }
35
  }
36
  if (!function_exists('ctype_print')) {
37
+ function ctype_print($text) { return p\Ctype::ctype_print($text); }
38
  }
39
  if (!function_exists('ctype_punct')) {
40
+ function ctype_punct($text) { return p\Ctype::ctype_punct($text); }
41
  }
42
  if (!function_exists('ctype_space')) {
43
+ function ctype_space($text) { return p\Ctype::ctype_space($text); }
44
  }
45
  if (!function_exists('ctype_upper')) {
46
+ function ctype_upper($text) { return p\Ctype::ctype_upper($text); }
47
  }
48
  if (!function_exists('ctype_xdigit')) {
49
+ function ctype_xdigit($text) { return p\Ctype::ctype_xdigit($text); }
50
  }
vendor/symfony/polyfill-ctype/bootstrap80.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ use Symfony\Polyfill\Ctype as p;
13
+
14
+ if (!function_exists('ctype_alnum')) {
15
+ function ctype_alnum(mixed $text): bool { return p\Ctype::ctype_alnum($text); }
16
+ }
17
+ if (!function_exists('ctype_alpha')) {
18
+ function ctype_alpha(mixed $text): bool { return p\Ctype::ctype_alpha($text); }
19
+ }
20
+ if (!function_exists('ctype_cntrl')) {
21
+ function ctype_cntrl(mixed $text): bool { return p\Ctype::ctype_cntrl($text); }
22
+ }
23
+ if (!function_exists('ctype_digit')) {
24
+ function ctype_digit(mixed $text): bool { return p\Ctype::ctype_digit($text); }
25
+ }
26
+ if (!function_exists('ctype_graph')) {
27
+ function ctype_graph(mixed $text): bool { return p\Ctype::ctype_graph($text); }
28
+ }
29
+ if (!function_exists('ctype_lower')) {
30
+ function ctype_lower(mixed $text): bool { return p\Ctype::ctype_lower($text); }
31
+ }
32
+ if (!function_exists('ctype_print')) {
33
+ function ctype_print(mixed $text): bool { return p\Ctype::ctype_print($text); }
34
+ }
35
+ if (!function_exists('ctype_punct')) {
36
+ function ctype_punct(mixed $text): bool { return p\Ctype::ctype_punct($text); }
37
+ }
38
+ if (!function_exists('ctype_space')) {
39
+ function ctype_space(mixed $text): bool { return p\Ctype::ctype_space($text); }
40
+ }
41
+ if (!function_exists('ctype_upper')) {
42
+ function ctype_upper(mixed $text): bool { return p\Ctype::ctype_upper($text); }
43
+ }
44
+ if (!function_exists('ctype_xdigit')) {
45
+ function ctype_xdigit(mixed $text): bool { return p\Ctype::ctype_xdigit($text); }
46
+ }
vendor/symfony/polyfill-ctype/composer.json CHANGED
@@ -16,7 +16,10 @@
16
  }
17
  ],
18
  "require": {
19
- "php": ">=5.3.3"
 
 
 
20
  },
21
  "autoload": {
22
  "psr-4": { "Symfony\\Polyfill\\Ctype\\": "" },
@@ -28,7 +31,7 @@
28
  "minimum-stability": "dev",
29
  "extra": {
30
  "branch-alias": {
31
- "dev-main": "1.19-dev"
32
  },
33
  "thanks": {
34
  "name": "symfony/polyfill",
16
  }
17
  ],
18
  "require": {
19
+ "php": ">=7.1"
20
+ },
21
+ "provide": {
22
+ "ext-ctype": "*"
23
  },
24
  "autoload": {
25
  "psr-4": { "Symfony\\Polyfill\\Ctype\\": "" },
31
  "minimum-stability": "dev",
32
  "extra": {
33
  "branch-alias": {
34
+ "dev-main": "1.26-dev"
35
  },
36
  "thanks": {
37
  "name": "symfony/polyfill",
vendor/symfony/polyfill-mbstring/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2015-2019 Fabien Potencier
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
vendor/symfony/polyfill-mbstring/Mbstring.php ADDED
@@ -0,0 +1,873 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Polyfill\Mbstring;
13
+
14
+ /**
15
+ * Partial mbstring implementation in PHP, iconv based, UTF-8 centric.
16
+ *
17
+ * Implemented:
18
+ * - mb_chr - Returns a specific character from its Unicode code point
19
+ * - mb_convert_encoding - Convert character encoding
20
+ * - mb_convert_variables - Convert character code in variable(s)
21
+ * - mb_decode_mimeheader - Decode string in MIME header field
22
+ * - mb_encode_mimeheader - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED
23
+ * - mb_decode_numericentity - Decode HTML numeric string reference to character
24
+ * - mb_encode_numericentity - Encode character to HTML numeric string reference
25
+ * - mb_convert_case - Perform case folding on a string
26
+ * - mb_detect_encoding - Detect character encoding
27
+ * - mb_get_info - Get internal settings of mbstring
28
+ * - mb_http_input - Detect HTTP input character encoding
29
+ * - mb_http_output - Set/Get HTTP output character encoding
30
+ * - mb_internal_encoding - Set/Get internal character encoding
31
+ * - mb_list_encodings - Returns an array of all supported encodings
32
+ * - mb_ord - Returns the Unicode code point of a character
33
+ * - mb_output_handler - Callback function converts character encoding in output buffer
34
+ * - mb_scrub - Replaces ill-formed byte sequences with substitute characters
35
+ * - mb_strlen - Get string length
36
+ * - mb_strpos - Find position of first occurrence of string in a string
37
+ * - mb_strrpos - Find position of last occurrence of a string in a string
38
+ * - mb_str_split - Convert a string to an array
39
+ * - mb_strtolower - Make a string lowercase
40
+ * - mb_strtoupper - Make a string uppercase
41
+ * - mb_substitute_character - Set/Get substitution character
42
+ * - mb_substr - Get part of string
43
+ * - mb_stripos - Finds position of first occurrence of a string within another, case insensitive
44
+ * - mb_stristr - Finds first occurrence of a string within another, case insensitive
45
+ * - mb_strrchr - Finds the last occurrence of a character in a string within another
46
+ * - mb_strrichr - Finds the last occurrence of a character in a string within another, case insensitive
47
+ * - mb_strripos - Finds position of last occurrence of a string within another, case insensitive
48
+ * - mb_strstr - Finds first occurrence of a string within another
49
+ * - mb_strwidth - Return width of string
50
+ * - mb_substr_count - Count the number of substring occurrences
51
+ *
52
+ * Not implemented:
53
+ * - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
54
+ * - mb_ereg_* - Regular expression with multibyte support
55
+ * - mb_parse_str - Parse GET/POST/COOKIE data and set global variable
56
+ * - mb_preferred_mime_name - Get MIME charset string
57
+ * - mb_regex_encoding - Returns current encoding for multibyte regex as string
58
+ * - mb_regex_set_options - Set/Get the default options for mbregex functions
59
+ * - mb_send_mail - Send encoded mail
60
+ * - mb_split - Split multibyte string using regular expression
61
+ * - mb_strcut - Get part of string
62
+ * - mb_strimwidth - Get truncated string with specified width
63
+ *
64
+ * @author Nicolas Grekas <p@tchwork.com>
65
+ *
66
+ * @internal
67
+ */
68
+ final class Mbstring
69
+ {
70
+ public const MB_CASE_FOLD = \PHP_INT_MAX;
71
+
72
+ private const CASE_FOLD = [
73
+ ['µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"],
74
+ ['μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1", 'ι'],
75
+ ];
76
+
77
+ private static $encodingList = ['ASCII', 'UTF-8'];
78
+ private static $language = 'neutral';
79
+ private static $internalEncoding = 'UTF-8';
80
+
81
+ public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
82
+ {
83
+ if (\is_array($fromEncoding) || ($fromEncoding !== null && false !== strpos($fromEncoding, ','))) {
84
+ $fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
85
+ } else {
86
+ $fromEncoding = self::getEncoding($fromEncoding);
87
+ }
88
+
89
+ $toEncoding = self::getEncoding($toEncoding);
90
+
91
+ if ('BASE64' === $fromEncoding) {
92
+ $s = base64_decode($s);
93
+ $fromEncoding = $toEncoding;
94
+ }
95
+
96
+ if ('BASE64' === $toEncoding) {
97
+ return base64_encode($s);
98
+ }
99
+
100
+ if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) {
101
+ if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) {
102
+ $fromEncoding = 'Windows-1252';
103
+ }
104
+ if ('UTF-8' !== $fromEncoding) {
105
+ $s = \iconv($fromEncoding, 'UTF-8//IGNORE', $s);
106
+ }
107
+
108
+ return preg_replace_callback('/[\x80-\xFF]+/', [__CLASS__, 'html_encoding_callback'], $s);
109
+ }
110
+
111
+ if ('HTML-ENTITIES' === $fromEncoding) {
112
+ $s = html_entity_decode($s, \ENT_COMPAT, 'UTF-8');
113
+ $fromEncoding = 'UTF-8';
114
+ }
115
+
116
+ return \iconv($fromEncoding, $toEncoding.'//IGNORE', $s);
117
+ }
118
+
119
+ public static function mb_convert_variables($toEncoding, $fromEncoding, &...$vars)
120
+ {
121
+ $ok = true;
122
+ array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) {
123
+ if (false === $v = self::mb_convert_encoding($v, $toEncoding, $fromEncoding)) {
124
+ $ok = false;
125
+ }
126
+ });
127
+
128
+ return $ok ? $fromEncoding : false;
129
+ }
130
+
131
+ public static function mb_decode_mimeheader($s)
132
+ {
133
+ return \iconv_mime_decode($s, 2, self::$internalEncoding);
134
+ }
135
+
136
+ public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
137
+ {
138
+ trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', \E_USER_WARNING);
139
+ }
140
+
141
+ public static function mb_decode_numericentity($s, $convmap, $encoding = null)
142
+ {
143
+ if (null !== $s && !is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) {
144
+ trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING);
145
+
146
+ return null;
147
+ }
148
+
149
+ if (!\is_array($convmap) || (80000 > \PHP_VERSION_ID && !$convmap)) {
150
+ return false;
151
+ }
152
+
153
+ if (null !== $encoding && !is_scalar($encoding)) {
154
+ trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING);
155
+
156
+ return ''; // Instead of null (cf. mb_encode_numericentity).
157
+ }
158
+
159
+ $s = (string) $s;
160
+ if ('' === $s) {
161
+ return '';
162
+ }
163
+
164
+ $encoding = self::getEncoding($encoding);
165
+
166
+ if ('UTF-8' === $encoding) {
167
+ $encoding = null;
168
+ if (!preg_match('//u', $s)) {
169
+ $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
170
+ }
171
+ } else {
172
+ $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
173
+ }
174
+
175
+ $cnt = floor(\count($convmap) / 4) * 4;
176
+
177
+ for ($i = 0; $i < $cnt; $i += 4) {
178
+ // collector_decode_htmlnumericentity ignores $convmap[$i + 3]
179
+ $convmap[$i] += $convmap[$i + 2];
180
+ $convmap[$i + 1] += $convmap[$i + 2];
181
+ }
182
+
183
+ $s = preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', function (array $m) use ($cnt, $convmap) {
184
+ $c = isset($m[2]) ? (int) hexdec($m[2]) : $m[1];
185
+ for ($i = 0; $i < $cnt; $i += 4) {
186
+ if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) {
187
+ return self::mb_chr($c - $convmap[$i + 2]);
188
+ }
189
+ }
190
+
191
+ return $m[0];
192
+ }, $s);
193
+
194
+ if (null === $encoding) {
195
+ return $s;
196
+ }
197
+
198
+ return \iconv('UTF-8', $encoding.'//IGNORE', $s);
199
+ }
200
+
201
+ public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false)
202
+ {
203
+ if (null !== $s && !is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) {
204
+ trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING);
205
+
206
+ return null;
207
+ }
208
+
209
+ if (!\is_array($convmap) || (80000 > \PHP_VERSION_ID && !$convmap)) {
210
+ return false;
211
+ }
212
+
213
+ if (null !== $encoding && !is_scalar($encoding)) {
214
+ trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING);
215
+
216
+ return null; // Instead of '' (cf. mb_decode_numericentity).
217
+ }
218
+
219
+ if (null !== $is_hex && !is_scalar($is_hex)) {
220
+ trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.\gettype($s).' given', \E_USER_WARNING);
221
+
222
+ return null;
223
+ }
224
+
225
+ $s = (string) $s;
226
+ if ('' === $s) {
227
+ return '';
228
+ }
229
+
230
+ $encoding = self::getEncoding($encoding);
231
+
232
+ if ('UTF-8' === $encoding) {
233
+ $encoding = null;
234
+ if (!preg_match('//u', $s)) {
235
+ $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
236
+ }
237
+ } else {
238
+ $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
239
+ }
240
+
241
+ static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4];
242
+
243
+ $cnt = floor(\count($convmap) / 4) * 4;
244
+ $i = 0;
245
+ $len = \strlen($s);
246
+ $result = '';
247
+
248
+ while ($i < $len) {
249
+ $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
250
+ $uchr = substr($s, $i, $ulen);
251
+ $i += $ulen;
252
+ $c = self::mb_ord($uchr);
253
+
254
+ for ($j = 0; $j < $cnt; $j += 4) {
255
+ if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) {
256
+ $cOffset = ($c + $convmap[$j + 2]) & $convmap[$j + 3];
257
+ $result .= $is_hex ? sprintf('&#x%X;', $cOffset) : '&#'.$cOffset.';';
258
+ continue 2;
259
+ }
260
+ }
261
+ $result .= $uchr;
262
+ }
263
+
264
+ if (null === $encoding) {
265
+ return $result;
266
+ }
267
+
268
+ return \iconv('UTF-8', $encoding.'//IGNORE', $result);
269
+ }
270
+
271
+ public static function mb_convert_case($s, $mode, $encoding = null)
272
+ {
273
+ $s = (string) $s;
274
+ if ('' === $s) {
275
+ return '';
276
+ }
277
+
278
+ $encoding = self::getEncoding($encoding);
279
+
280
+ if ('UTF-8' === $encoding) {
281
+ $encoding = null;
282
+ if (!preg_match('//u', $s)) {
283
+ $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
284
+ }
285
+ } else {
286
+ $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
287
+ }
288
+
289
+ if (\MB_CASE_TITLE == $mode) {
290
+ static $titleRegexp = null;
291
+ if (null === $titleRegexp) {
292
+ $titleRegexp = self::getData('titleCaseRegexp');
293
+ }
294
+ $s = preg_replace_callback($titleRegexp, [__CLASS__, 'title_case'], $s);
295
+ } else {
296
+ if (\MB_CASE_UPPER == $mode) {
297
+ static $upper = null;
298
+ if (null === $upper) {
299
+ $upper = self::getData('upperCase');
300
+ }
301
+ $map = $upper;
302
+ } else {
303
+ if (self::MB_CASE_FOLD === $mode) {
304
+ $s = str_replace(self::CASE_FOLD[0], self::CASE_FOLD[1], $s);
305
+ }
306
+
307
+ static $lower = null;
308
+ if (null === $lower) {
309
+ $lower = self::getData('lowerCase');
310
+ }
311
+ $map = $lower;
312
+ }
313
+
314
+ static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4];
315
+
316
+ $i = 0;
317
+ $len = \strlen($s);
318
+
319
+ while ($i < $len) {
320
+ $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
321
+ $uchr = substr($s, $i, $ulen);
322
+ $i += $ulen;
323
+
324
+ if (isset($map[$uchr])) {
325
+ $uchr = $map[$uchr];
326
+ $nlen = \strlen($uchr);
327
+
328
+ if ($nlen == $ulen) {
329
+ $nlen = $i;
330
+ do {
331
+ $s[--$nlen] = $uchr[--$ulen];
332
+ } while ($ulen);
333
+ } else {
334
+ $s = substr_replace($s, $uchr, $i - $ulen, $ulen);
335
+ $len += $nlen - $ulen;
336
+ $i += $nlen - $ulen;
337
+ }
338
+ }
339
+ }
340
+ }
341
+
342
+ if (null === $encoding) {
343
+ return $s;
344
+ }
345
+
346
+ return \iconv('UTF-8', $encoding.'//IGNORE', $s);
347
+ }
348
+
349
+ public static function mb_internal_encoding($encoding = null)
350
+ {
351
+ if (null === $encoding) {
352
+ return self::$internalEncoding;
353
+ }
354
+
355
+ $normalizedEncoding = self::getEncoding($encoding);
356
+
357
+ if ('UTF-8' === $normalizedEncoding || false !== @\iconv($normalizedEncoding, $normalizedEncoding, ' ')) {
358
+ self::$internalEncoding = $normalizedEncoding;
359
+
360
+ return true;
361
+ }
362
+
363
+ if (80000 > \PHP_VERSION_ID) {
364
+ return false;
365
+ }
366
+
367
+ throw new \ValueError(sprintf('Argument #1 ($encoding) must be a valid encoding, "%s" given', $encoding));
368
+ }
369
+
370
+ public static function mb_language($lang = null)
371
+ {
372
+ if (null === $lang) {
373
+ return self::$language;
374
+ }
375
+
376
+ switch ($normalizedLang = strtolower($lang)) {
377
+ case 'uni':
378
+ case 'neutral':
379
+ self::$language = $normalizedLang;
380
+
381
+ return true;
382
+ }
383
+
384
+ if (80000 > \PHP_VERSION_ID) {
385
+ return false;
386
+ }
387
+
388
+ throw new \ValueError(sprintf('Argument #1 ($language) must be a valid language, "%s" given', $lang));
389
+ }
390
+
391
+ public static function mb_list_encodings()
392
+ {
393
+ return ['UTF-8'];
394
+ }
395
+
396
+ public static function mb_encoding_aliases($encoding)
397
+ {
398
+ switch (strtoupper($encoding)) {
399
+ case 'UTF8':
400
+ case 'UTF-8':
401
+ return ['utf8'];
402
+ }
403
+
404
+ return false;
405
+ }
406
+
407
+ public static function mb_check_encoding($var = null, $encoding = null)
408
+ {
409
+ if (null === $encoding) {
410
+ if (null === $var) {
411
+ return false;
412
+ }
413
+ $encoding = self::$internalEncoding;
414
+ }
415
+
416
+ return self::mb_detect_encoding($var, [$encoding]) || false !== @\iconv($encoding, $encoding, $var);
417
+ }
418
+
419
+ public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
420
+ {
421
+ if (null === $encodingList) {
422
+ $encodingList = self::$encodingList;
423
+ } else {
424
+ if (!\is_array($encodingList)) {
425
+ $encodingList = array_map('trim', explode(',', $encodingList));
426
+ }
427
+ $encodingList = array_map('strtoupper', $encodingList);
428
+ }
429
+
430
+ foreach ($encodingList as $enc) {
431
+ switch ($enc) {
432
+ case 'ASCII':
433
+ if (!preg_match('/[\x80-\xFF]/', $str)) {
434
+ return $enc;
435
+ }
436
+ break;
437
+
438
+ case 'UTF8':
439
+ case 'UTF-8':
440
+ if (preg_match('//u', $str)) {
441
+ return 'UTF-8';
442
+ }
443
+ break;
444
+
445
+ default:
446
+ if (0 === strncmp($enc, 'ISO-8859-', 9)) {
447
+ return $enc;
448
+ }
449
+ }
450
+ }
451
+
452
+ return false;
453
+ }
454
+
455
+ public static function mb_detect_order($encodingList = null)
456
+ {
457
+ if (null === $encodingList) {
458
+ return self::$encodingList;
459
+ }
460
+
461
+ if (!\is_array($encodingList)) {
462
+ $encodingList = array_map('trim', explode(',', $encodingList));
463
+ }
464
+ $encodingList = array_map('strtoupper', $encodingList);
465
+
466
+ foreach ($encodingList as $enc) {
467
+ switch ($enc) {
468
+ default:
469
+ if (strncmp($enc, 'ISO-8859-', 9)) {
470
+ return false;
471
+ }
472
+ // no break
473
+ case 'ASCII':
474
+ case 'UTF8':
475
+ case 'UTF-8':
476
+ }
477
+ }
478
+
479
+ self::$encodingList = $encodingList;
480
+
481
+ return true;
482
+ }
483
+
484
+ public static function mb_strlen($s, $encoding = null)
485
+ {
486
+ $encoding = self::getEncoding($encoding);
487
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
488
+ return \strlen($s);
489
+ }
490
+
491
+ return @\iconv_strlen($s, $encoding);
492
+ }
493
+
494
+ public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
495
+ {
496
+ $encoding = self::getEncoding($encoding);
497
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
498
+ return strpos($haystack, $needle, $offset);
499
+ }
500
+
501
+ $needle = (string) $needle;
502
+ if ('' === $needle) {
503
+ if (80000 > \PHP_VERSION_ID) {
504
+ trigger_error(__METHOD__.': Empty delimiter', \E_USER_WARNING);
505
+
506
+ return false;
507
+ }
508
+
509
+ return 0;
510
+ }
511
+
512
+ return \iconv_strpos($haystack, $needle, $offset, $encoding);
513
+ }
514
+
515
+ public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
516
+ {
517
+ $encoding = self::getEncoding($encoding);
518
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
519
+ return strrpos($haystack, $needle, $offset);
520
+ }
521
+
522
+ if ($offset != (int) $offset) {
523
+ $offset = 0;
524
+ } elseif ($offset = (int) $offset) {
525
+ if ($offset < 0) {
526
+ if (0 > $offset += self::mb_strlen($needle)) {
527
+ $haystack = self::mb_substr($haystack, 0, $offset, $encoding);
528
+ }
529
+ $offset = 0;
530
+ } else {
531
+ $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
532
+ }
533
+ }
534
+
535
+ $pos = '' !== $needle || 80000 > \PHP_VERSION_ID
536
+ ? \iconv_strrpos($haystack, $needle, $encoding)
537
+ : self::mb_strlen($haystack, $encoding);
538
+
539
+ return false !== $pos ? $offset + $pos : false;
540
+ }
541
+
542
+ public static function mb_str_split($string, $split_length = 1, $encoding = null)
543
+ {
544
+ if (null !== $string && !is_scalar($string) && !(\is_object($string) && method_exists($string, '__toString'))) {
545
+ trigger_error('mb_str_split() expects parameter 1 to be string, '.\gettype($string).' given', \E_USER_WARNING);
546
+
547
+ return null;
548
+ }
549
+
550
+ if (1 > $split_length = (int) $split_length) {
551
+ if (80000 > \PHP_VERSION_ID) {
552
+ trigger_error('The length of each segment must be greater than zero', \E_USER_WARNING);
553
+ return false;
554
+ }
555
+
556
+ throw new \ValueError('Argument #2 ($length) must be greater than 0');
557
+ }
558
+
559
+ if (null === $encoding) {
560
+ $encoding = mb_internal_encoding();
561
+ }
562
+
563
+ if ('UTF-8' === $encoding = self::getEncoding($encoding)) {
564
+ $rx = '/(';
565
+ while (65535 < $split_length) {
566
+ $rx .= '.{65535}';
567
+ $split_length -= 65535;
568
+ }
569
+ $rx .= '.{'.$split_length.'})/us';
570
+
571
+ return preg_split($rx, $string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY);
572
+ }
573
+
574
+ $result = [];
575
+ $length = mb_strlen($string, $encoding);
576
+
577
+ for ($i = 0; $i < $length; $i += $split_length) {
578
+ $result[] = mb_substr($string, $i, $split_length, $encoding);
579
+ }
580
+
581
+ return $result;
582
+ }
583
+
584
+ public static function mb_strtolower($s, $encoding = null)
585
+ {
586
+ return self::mb_convert_case($s, \MB_CASE_LOWER, $encoding);
587
+ }
588
+
589
+ public static function mb_strtoupper($s, $encoding = null)
590
+ {
591
+ return self::mb_convert_case($s, \MB_CASE_UPPER, $encoding);
592
+ }
593
+
594
+ public static function mb_substitute_character($c = null)
595
+ {
596
+ if (null === $c) {
597
+ return 'none';
598
+ }
599
+ if (0 === strcasecmp($c, 'none')) {
600
+ return true;
601
+ }
602
+ if (80000 > \PHP_VERSION_ID) {
603
+ return false;
604
+ }
605
+ if (\is_int($c) || 'long' === $c || 'entity' === $c) {
606
+ return false;
607
+ }
608
+
609
+ throw new \ValueError('Argument #1 ($substitute_character) must be "none", "long", "entity" or a valid codepoint');
610
+ }
611
+
612
+ public static function mb_substr($s, $start, $length = null, $encoding = null)
613
+ {
614
+ $encoding = self::getEncoding($encoding);
615
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
616
+ return (string) substr($s, $start, null === $length ? 2147483647 : $length);
617
+ }
618
+
619
+ if ($start < 0) {
620
+ $start = \iconv_strlen($s, $encoding) + $start;
621
+ if ($start < 0) {
622
+ $start = 0;
623
+ }
624
+ }
625
+
626
+ if (null === $length) {
627
+ $length = 2147483647;
628
+ } elseif ($length < 0) {
629
+ $length = \iconv_strlen($s, $encoding) + $length - $start;
630
+ if ($length < 0) {
631
+ return '';
632
+ }
633
+ }
634
+
635
+ return (string) \iconv_substr($s, $start, $length, $encoding);
636
+ }
637
+
638
+ public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
639
+ {
640
+ $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
641
+ $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
642
+
643
+ return self::mb_strpos($haystack, $needle, $offset, $encoding);
644
+ }
645
+
646
+ public static function mb_stristr($haystack, $needle, $part = false, $encoding = null)
647
+ {
648
+ $pos = self::mb_stripos($haystack, $needle, 0, $encoding);
649
+
650
+ return self::getSubpart($pos, $part, $haystack, $encoding);
651
+ }
652
+
653
+ public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null)
654
+ {
655
+ $encoding = self::getEncoding($encoding);
656
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
657
+ $pos = strrpos($haystack, $needle);
658
+ } else {
659
+ $needle = self::mb_substr($needle, 0, 1, $encoding);
660
+ $pos = \iconv_strrpos($haystack, $needle, $encoding);
661
+ }
662
+
663
+ return self::getSubpart($pos, $part, $haystack, $encoding);
664
+ }
665
+
666
+ public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null)
667
+ {
668
+ $needle = self::mb_substr($needle, 0, 1, $encoding);
669
+ $pos = self::mb_strripos($haystack, $needle, $encoding);
670
+
671
+ return self::getSubpart($pos, $part, $haystack, $encoding);
672
+ }
673
+
674
+ public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null)
675
+ {
676
+ $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
677
+ $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
678
+
679
+ return self::mb_strrpos($haystack, $needle, $offset, $encoding);
680
+ }
681
+
682
+ public static function mb_strstr($haystack, $needle, $part = false, $encoding = null)
683
+ {
684
+ $pos = strpos($haystack, $needle);
685
+ if (false === $pos) {
686
+ return false;
687
+ }
688
+ if ($part) {
689
+ return substr($haystack, 0, $pos);
690
+ }
691
+
692
+ return substr($haystack, $pos);
693
+ }
694
+
695
+ public static function mb_get_info($type = 'all')
696
+ {
697
+ $info = [
698
+ 'internal_encoding' => self::$internalEncoding,
699
+ 'http_output' => 'pass',
700
+ 'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)',
701
+ 'func_overload' => 0,
702
+ 'func_overload_list' => 'no overload',
703
+ 'mail_charset' => 'UTF-8',
704
+ 'mail_header_encoding' => 'BASE64',
705
+ 'mail_body_encoding' => 'BASE64',
706
+ 'illegal_chars' => 0,
707
+ 'encoding_translation' => 'Off',
708
+ 'language' => self::$language,
709
+ 'detect_order' => self::$encodingList,
710
+ 'substitute_character' => 'none',
711
+ 'strict_detection' => 'Off',
712
+ ];
713
+
714
+ if ('all' === $type) {
715
+ return $info;
716
+ }
717
+ if (isset($info[$type])) {
718
+ return $info[$type];
719
+ }
720
+
721
+ return false;
722
+ }
723
+
724
+ public static function mb_http_input($type = '')
725
+ {
726
+ return false;
727
+ }
728
+
729
+ public static function mb_http_output($encoding = null)
730
+ {
731
+ return null !== $encoding ? 'pass' === $encoding : 'pass';
732
+ }
733
+
734
+ public static function mb_strwidth($s, $encoding = null)
735
+ {
736
+ $encoding = self::getEncoding($encoding);
737
+
738
+ if ('UTF-8' !== $encoding) {
739
+ $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
740
+ }
741
+
742
+ $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide);
743
+
744
+ return ($wide << 1) + \iconv_strlen($s, 'UTF-8');
745
+ }
746
+
747
+ public static function mb_substr_count($haystack, $needle, $encoding = null)
748
+ {
749
+ return substr_count($haystack, $needle);
750
+ }
751
+
752
+ public static function mb_output_handler($contents, $status)
753
+ {
754
+ return $contents;
755
+ }
756
+
757
+ public static function mb_chr($code, $encoding = null)
758
+ {
759
+ if (0x80 > $code %= 0x200000) {
760
+ $s = \chr($code);
761
+ } elseif (0x800 > $code) {
762
+ $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F);
763
+ } elseif (0x10000 > $code) {
764
+ $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
765
+ } else {
766
+ $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
767
+ }
768
+
769
+ if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
770
+ $s = mb_convert_encoding($s, $encoding, 'UTF-8');
771
+ }
772
+
773
+ return $s;
774
+ }
775
+
776
+ public static function mb_ord($s, $encoding = null)
777
+ {
778
+ if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
779
+ $s = mb_convert_encoding($s, 'UTF-8', $encoding);
780
+ }
781
+
782
+ if (1 === \strlen($s)) {
783
+ return \ord($s);
784
+ }
785
+
786
+ $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
787
+ if (0xF0 <= $code) {
788
+ return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
789
+ }
790
+ if (0xE0 <= $code) {
791
+ return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
792
+ }
793
+ if (0xC0 <= $code) {
794
+ return (($code - 0xC0) << 6) + $s[2] - 0x80;
795
+ }
796
+
797
+ return $code;
798
+ }
799
+
800
+ private static function getSubpart($pos, $part, $haystack, $encoding)
801
+ {
802
+ if (false === $pos) {
803
+ return false;
804
+ }
805
+ if ($part) {
806
+ return self::mb_substr($haystack, 0, $pos, $encoding);
807
+ }
808
+
809
+ return self::mb_substr($haystack, $pos, null, $encoding);
810
+ }
811
+
812
+ private static function html_encoding_callback(array $m)
813
+ {
814
+ $i = 1;
815
+ $entities = '';
816
+ $m = unpack('C*', htmlentities($m[0], \ENT_COMPAT, 'UTF-8'));
817
+
818
+ while (isset($m[$i])) {
819
+ if (0x80 > $m[$i]) {
820
+ $entities .= \chr($m[$i++]);
821
+ continue;
822
+ }
823
+ if (0xF0 <= $m[$i]) {
824
+ $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
825
+ } elseif (0xE0 <= $m[$i]) {
826
+ $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
827
+ } else {
828
+ $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
829
+ }
830
+
831
+ $entities .= '&#'.$c.';';
832
+ }
833
+
834
+ return $entities;
835
+ }
836
+
837
+ private static function title_case(array $s)
838
+ {
839
+ return self::mb_convert_case($s[1], \MB_CASE_UPPER, 'UTF-8').self::mb_convert_case($s[2], \MB_CASE_LOWER, 'UTF-8');
840
+ }
841
+
842
+ private static function getData($file)
843
+ {
844
+ if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) {
845
+ return require $file;
846
+ }
847
+
848
+ return false;
849
+ }
850
+
851
+ private static function getEncoding($encoding)
852
+ {
853
+ if (null === $encoding) {
854
+ return self::$internalEncoding;
855
+ }
856
+
857
+ if ('UTF-8' === $encoding) {
858
+ return 'UTF-8';
859
+ }
860
+
861
+ $encoding = strtoupper($encoding);
862
+
863
+ if ('8BIT' === $encoding || 'BINARY' === $encoding) {
864
+ return 'CP850';
865
+ }
866
+
867
+ if ('UTF8' === $encoding) {
868
+ return 'UTF-8';
869
+ }
870
+
871
+ return $encoding;
872
+ }
873
+ }
vendor/symfony/polyfill-mbstring/README.md ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Symfony Polyfill / Mbstring
2
+ ===========================
3
+
4
+ This component provides a partial, native PHP implementation for the
5
+ [Mbstring](https://php.net/mbstring) extension.
6
+
7
+ More information can be found in the
8
+ [main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).
9
+
10
+ License
11
+ =======
12
+
13
+ This library is released under the [MIT license](LICENSE).
vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php ADDED
@@ -0,0 +1,1397 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ return array (
4
+ 'A' => 'a',
5
+ 'B' => 'b',
6
+ 'C' => 'c',
7
+ 'D' => 'd',
8
+ 'E' => 'e',
9
+ 'F' => 'f',
10
+ 'G' => 'g',
11
+ 'H' => 'h',
12
+ 'I' => 'i',
13
+ 'J' => 'j',
14
+ 'K' => 'k',
15
+ 'L' => 'l',
16
+ 'M' => 'm',
17
+ 'N' => 'n',
18
+ 'O' => 'o',
19
+ 'P' => 'p',
20
+ 'Q' => 'q',
21
+ 'R' => 'r',
22
+ 'S' => 's',
23
+ 'T' => 't',
24
+ 'U' => 'u',
25
+ 'V' => 'v',
26
+ 'W' => 'w',
27
+ 'X' => 'x',
28
+ 'Y' => 'y',
29
+ 'Z' => 'z',
30
+ 'À' => 'à',
31
+ 'Á' => 'á',
32
+ 'Â' => 'â',
33
+ 'Ã' => 'ã',
34
+ 'Ä' => 'ä',
35
+ 'Å' => 'å',
36
+ 'Æ' => 'æ',
37
+ 'Ç' => 'ç',
38
+ 'È' => 'è',
39
+ 'É' => 'é',
40
+ 'Ê' => 'ê',
41
+ 'Ë' => 'ë',
42
+ 'Ì' => 'ì',
43
+ 'Í' => 'í',
44
+ 'Î' => 'î',
45
+ 'Ï' => 'ï',
46
+ 'Ð' => 'ð',
47
+ 'Ñ' => 'ñ',
48
+ 'Ò' => 'ò',
49
+ 'Ó' => 'ó',
50
+ 'Ô' => 'ô',
51
+ 'Õ' => 'õ',
52
+ 'Ö' => 'ö',
53
+ 'Ø' => 'ø',
54
+ 'Ù' => 'ù',
55
+ 'Ú' => 'ú',
56
+ 'Û' => 'û',
57
+ 'Ü' => 'ü',
58
+ 'Ý' => 'ý',
59
+ 'Þ' => 'þ',
60
+ 'Ā' => 'ā',
61
+ 'Ă' => 'ă',
62
+ 'Ą' => 'ą',
63
+ 'Ć' => 'ć',
64
+ 'Ĉ' => 'ĉ',
65
+ 'Ċ' => 'ċ',
66
+ 'Č' => 'č',
67
+ 'Ď' => 'ď',
68
+ 'Đ' => 'đ',
69
+ 'Ē' => 'ē',
70
+ 'Ĕ' => 'ĕ',
71
+ 'Ė' => 'ė',
72
+ 'Ę' => 'ę',
73
+ 'Ě' => 'ě',
74
+ 'Ĝ' => 'ĝ',
75
+ 'Ğ' => 'ğ',
76
+ 'Ġ' => 'ġ',
77
+ 'Ģ' => 'ģ',
78
+ 'Ĥ' => 'ĥ',
79
+ 'Ħ' => 'ħ',
80
+ 'Ĩ' => 'ĩ',
81
+ 'Ī' => 'ī',
82
+ 'Ĭ' => 'ĭ',
83
+ 'Į' => 'į',
84
+ 'İ' => 'i̇',
85
+ 'IJ' => 'ij',
86
+ 'Ĵ' => 'ĵ',
87
+ 'Ķ' => 'ķ',
88
+ 'Ĺ' => 'ĺ',
89
+ 'Ļ' => 'ļ',
90
+ 'Ľ' => 'ľ',
91
+ 'Ŀ' => 'ŀ',
92
+ 'Ł' => 'ł',
93
+ 'Ń' => 'ń',
94
+ 'Ņ' => 'ņ',
95
+ 'Ň' => 'ň',
96
+ 'Ŋ' => 'ŋ',
97
+ 'Ō' => 'ō',
98
+ 'Ŏ' => 'ŏ',
99
+ 'Ő' => 'ő',
100
+ 'Œ' => 'œ',
101
+ 'Ŕ' => 'ŕ',
102
+ 'Ŗ' => 'ŗ',
103
+ 'Ř' => 'ř',
104
+ 'Ś' => 'ś',
105
+ 'Ŝ' => 'ŝ',
106
+ 'Ş' => 'ş',
107
+ 'Š' => 'š',
108
+ 'Ţ' => 'ţ',
109
+ 'Ť' => 'ť',
110
+ 'Ŧ' => 'ŧ',
111
+ 'Ũ' => 'ũ',
112
+ 'Ū' => 'ū',
113
+ 'Ŭ' => 'ŭ',
114
+ 'Ů' => 'ů',
115
+ 'Ű' => 'ű',
116
+ 'Ų' => 'ų',
117
+ 'Ŵ' => 'ŵ',
118
+ 'Ŷ' => 'ŷ',
119
+ 'Ÿ' => 'ÿ',
120
+ 'Ź' => 'ź',
121
+ 'Ż' => 'ż',
122
+ 'Ž' => 'ž',
123
+ 'Ɓ' => 'ɓ',
124
+ 'Ƃ' => 'ƃ',
125
+ 'Ƅ' => 'ƅ',
126
+ 'Ɔ' => 'ɔ',
127
+ 'Ƈ' => 'ƈ',
128
+ 'Ɖ' => 'ɖ',
129
+ 'Ɗ' => 'ɗ',
130
+ 'Ƌ' => 'ƌ',
131
+ 'Ǝ' => 'ǝ',
132
+ 'Ə' => 'ə',
133
+ 'Ɛ' => 'ɛ',
134
+ 'Ƒ' => 'ƒ',
135
+ 'Ɠ' => 'ɠ',
136
+ 'Ɣ' => 'ɣ',
137
+ 'Ɩ' => 'ɩ',
138
+ 'Ɨ' => 'ɨ',
139
+ 'Ƙ' => 'ƙ',
140
+ 'Ɯ' => 'ɯ',
141
+ 'Ɲ' => 'ɲ',
142
+ 'Ɵ' => 'ɵ',
143
+ 'Ơ' => 'ơ',
144
+ 'Ƣ' => 'ƣ',
145
+ 'Ƥ' => 'ƥ',
146
+ 'Ʀ' => 'ʀ',
147
+ 'Ƨ' => 'ƨ',
148
+ 'Ʃ' => 'ʃ',
149
+ 'Ƭ' => 'ƭ',
150
+ 'Ʈ' => 'ʈ',
151
+ 'Ư' => 'ư',
152
+ 'Ʊ' => 'ʊ',
153
+ 'Ʋ' => 'ʋ',
154
+ 'Ƴ' => 'ƴ',
155
+ 'Ƶ' => 'ƶ',
156
+ 'Ʒ' => 'ʒ',
157
+ 'Ƹ' => 'ƹ',
158
+ 'Ƽ' => 'ƽ',
159
+ 'DŽ' => 'dž',
160
+ 'Dž' => 'dž',
161
+ 'LJ' => 'lj',
162
+ 'Lj' => 'lj',
163
+ 'NJ' => 'nj',
164
+ 'Nj' => 'nj',
165
+ 'Ǎ' => 'ǎ',
166
+ 'Ǐ' => 'ǐ',
167
+ 'Ǒ' => 'ǒ',
168
+ 'Ǔ' => 'ǔ',
169
+ 'Ǖ' => 'ǖ',
170
+ 'Ǘ' => 'ǘ',
171
+ 'Ǚ' => 'ǚ',
172
+ 'Ǜ' => 'ǜ',
173
+ 'Ǟ' => 'ǟ',
174
+ 'Ǡ' => 'ǡ',
175
+ 'Ǣ' => 'ǣ',
176
+ 'Ǥ' => 'ǥ',
177
+ 'Ǧ' => 'ǧ',
178
+ 'Ǩ' => 'ǩ',
179
+ 'Ǫ' => 'ǫ',
180
+ 'Ǭ' => 'ǭ',
181
+ 'Ǯ' => 'ǯ',
182
+ 'DZ' => 'dz',
183
+ 'Dz' => 'dz',
184
+ 'Ǵ' => 'ǵ',
185
+ 'Ƕ' => 'ƕ',
186
+ 'Ƿ' => 'ƿ',
187
+ 'Ǹ' => 'ǹ',
188
+ 'Ǻ' => 'ǻ',
189
+ 'Ǽ' => 'ǽ',
190
+ 'Ǿ' => 'ǿ',
191
+ 'Ȁ' => 'ȁ',
192
+ 'Ȃ' => 'ȃ',
193
+ 'Ȅ' => 'ȅ',
194
+ 'Ȇ' => 'ȇ',
195
+ 'Ȉ' => 'ȉ',
196
+ 'Ȋ' => 'ȋ',
197
+ 'Ȍ' => 'ȍ',
198
+ 'Ȏ' => 'ȏ',
199
+ 'Ȑ' => 'ȑ',
200
+ 'Ȓ' => 'ȓ',
201
+ 'Ȕ' => 'ȕ',
202
+ 'Ȗ' => 'ȗ',
203
+ 'Ș' => 'ș',
204
+ 'Ț' => 'ț',
205
+ 'Ȝ' => 'ȝ',
206
+ 'Ȟ' => 'ȟ',
207
+ 'Ƞ' => 'ƞ',
208
+ 'Ȣ' => 'ȣ',
209
+ 'Ȥ' => 'ȥ',
210
+ 'Ȧ' => 'ȧ',
211
+ 'Ȩ' => 'ȩ',
212
+ 'Ȫ' => 'ȫ',
213
+ 'Ȭ' => 'ȭ',
214
+ 'Ȯ' => 'ȯ',
215
+ 'Ȱ' => 'ȱ',
216
+ 'Ȳ' => 'ȳ',
217
+ 'Ⱥ' => 'ⱥ',
218
+ 'Ȼ' => 'ȼ',
219
+ 'Ƚ' => 'ƚ',
220
+ 'Ⱦ' => 'ⱦ',
221
+ 'Ɂ' => 'ɂ',
222
+ 'Ƀ' => 'ƀ',
223
+ 'Ʉ' => 'ʉ',
224
+ 'Ʌ' => 'ʌ',
225
+ 'Ɇ' => 'ɇ',
226
+ 'Ɉ' => 'ɉ',
227
+ 'Ɋ' => 'ɋ',
228
+ 'Ɍ' => 'ɍ',
229
+ 'Ɏ' => 'ɏ',
230
+ 'Ͱ' => 'ͱ',
231
+ 'Ͳ' => 'ͳ',
232
+ 'Ͷ' => 'ͷ',
233
+ 'Ϳ' => 'ϳ',
234
+ 'Ά' => 'ά',
235
+ 'Έ' => 'έ',
236
+ 'Ή' => 'ή',
237
+ 'Ί' => 'ί',
238
+ 'Ό' => 'ό',
239
+ 'Ύ' => 'ύ',
240
+ 'Ώ' => 'ώ',
241
+ 'Α' => 'α',
242
+ 'Β' => 'β',
243
+ 'Γ' => 'γ',
244
+ 'Δ' => 'δ',
245
+ 'Ε' => 'ε',
246
+ 'Ζ' => 'ζ',
247
+ 'Η' => 'η',
248
+ 'Θ' => 'θ',
249
+ 'Ι' => 'ι',
250
+ 'Κ' => 'κ',
251
+ 'Λ' => 'λ',
252
+ 'Μ' => 'μ',
253
+ 'Ν' => 'ν',
254
+ 'Ξ' => 'ξ',
255
+ 'Ο' => 'ο',
256
+ 'Π' => 'π',
257
+ 'Ρ' => 'ρ',
258
+ 'Σ' => 'σ',
259
+ 'Τ' => 'τ',
260
+ 'Υ' => 'υ',
261
+ 'Φ' => 'φ',
262
+ 'Χ' => 'χ',
263
+ 'Ψ' => 'ψ',
264
+ 'Ω' => 'ω',
265
+ 'Ϊ' => 'ϊ',
266
+ 'Ϋ' => 'ϋ',
267
+ 'Ϗ' => 'ϗ',
268
+ 'Ϙ' => 'ϙ',
269
+ 'Ϛ' => 'ϛ',
270
+ 'Ϝ' => 'ϝ',
271
+ 'Ϟ' => 'ϟ',
272
+ 'Ϡ' => 'ϡ',
273
+ 'Ϣ' => 'ϣ',
274
+ 'Ϥ' => 'ϥ',
275
+ 'Ϧ' => 'ϧ',
276
+ 'Ϩ' => 'ϩ',
277
+ 'Ϫ' => 'ϫ',
278
+ 'Ϭ' => 'ϭ',
279
+ 'Ϯ' => 'ϯ',
280
+ 'ϴ' => 'θ',
281
+ 'Ϸ' => 'ϸ',
282
+ 'Ϲ' => 'ϲ',
283
+ 'Ϻ' => 'ϻ',
284
+ 'Ͻ' => 'ͻ',
285
+ 'Ͼ' => 'ͼ',
286
+ 'Ͽ' => 'ͽ',
287
+ 'Ѐ' => 'ѐ',
288
+ 'Ё' => 'ё',
289
+ 'Ђ' => 'ђ',
290
+ 'Ѓ' => 'ѓ',
291
+ 'Є' => 'є',
292
+ 'Ѕ' => 'ѕ',
293
+ 'І' => 'і',
294
+ 'Ї' => 'ї',
295
+ 'Ј' => 'ј',
296
+ 'Љ' => 'љ',
297
+ 'Њ' => 'њ',
298
+ 'Ћ' => 'ћ',
299
+ 'Ќ' => 'ќ',
300
+ 'Ѝ' => 'ѝ',
301
+ 'Ў' => 'ў',
302
+ 'Џ' => 'џ',
303
+ 'А' => 'а',
304
+ 'Б' => 'б',
305
+ 'В' => 'в',
306
+ 'Г' => 'г',
307
+ 'Д' => 'д',
308
+ 'Е' => 'е',
309
+ 'Ж' => 'ж',
310
+ 'З' => 'з',
311
+ 'И' => 'и',
312
+ 'Й' => 'й',
313
+ 'К' => 'к',
314
+ 'Л' => 'л',
315
+ 'М' => 'м',
316
+ 'Н' => 'н',
317
+ 'О' => 'о',
318
+ 'П' => 'п',
319
+ 'Р' => 'р',
320
+ 'С' => 'с',
321
+ 'Т' => 'т',
322
+ 'У' => 'у',
323
+ 'Ф' => 'ф',
324
+ 'Х' => 'х',
325
+ 'Ц' => 'ц',
326
+ 'Ч' => 'ч',
327
+ 'Ш' => 'ш',
328
+ 'Щ' => 'щ',
329
+ 'Ъ' => 'ъ',
330
+ 'Ы' => 'ы',
331
+ 'Ь' => 'ь',
332
+ 'Э' => 'э',
333
+ 'Ю' => 'ю',
334
+ 'Я' => 'я',
335
+ 'Ѡ' => 'ѡ',
336
+ 'Ѣ' => 'ѣ',
337
+ 'Ѥ' => 'ѥ',
338
+ 'Ѧ' => 'ѧ',
339
+ 'Ѩ' => 'ѩ',
340
+ 'Ѫ' => 'ѫ',
341
+ 'Ѭ' => 'ѭ',
342
+ 'Ѯ' => 'ѯ',
343
+ 'Ѱ' => 'ѱ',
344
+ 'Ѳ' => 'ѳ',
345
+ 'Ѵ' => 'ѵ',
346
+ 'Ѷ' => 'ѷ',
347
+ 'Ѹ' => 'ѹ',
348
+ 'Ѻ' => 'ѻ',
349
+ 'Ѽ' => 'ѽ',
350
+ 'Ѿ' => 'ѿ',
351
+ 'Ҁ' => 'ҁ',
352
+ 'Ҋ' => 'ҋ',
353
+ 'Ҍ' => 'ҍ',
354
+ 'Ҏ' => 'ҏ',
355
+ 'Ґ' => 'ґ',
356
+ 'Ғ' => 'ғ',
357
+ 'Ҕ' => 'ҕ',
358
+ 'Җ' => 'җ',
359
+ 'Ҙ' => 'ҙ',
360
+ 'Қ' => 'қ',
361
+ 'Ҝ' => 'ҝ',
362
+ 'Ҟ' => 'ҟ',
363
+ 'Ҡ' => 'ҡ',
364
+ 'Ң' => 'ң',
365
+ 'Ҥ' => 'ҥ',
366
+ 'Ҧ' => 'ҧ',
367
+ 'Ҩ' => 'ҩ',
368
+ 'Ҫ' => 'ҫ',
369
+ 'Ҭ' => 'ҭ',
370
+ 'Ү' => 'ү',
371
+ 'Ұ' => 'ұ',
372
+ 'Ҳ' => 'ҳ',
373
+ 'Ҵ' => 'ҵ',
374
+ 'Ҷ' => 'ҷ',
375
+ 'Ҹ' => 'ҹ',
376
+ 'Һ' => 'һ',
377
+ 'Ҽ' => 'ҽ',
378
+ 'Ҿ' => 'ҿ',
379
+ 'Ӏ' => 'ӏ',
380
+ 'Ӂ' => 'ӂ',
381
+ 'Ӄ' => 'ӄ',
382
+ 'Ӆ' => 'ӆ',
383
+ 'Ӈ' => 'ӈ',
384
+ 'Ӊ' => 'ӊ',
385
+ 'Ӌ' => 'ӌ',
386
+ 'Ӎ' => 'ӎ',
387
+ 'Ӑ' => 'ӑ',
388
+ 'Ӓ' => 'ӓ',
389
+ 'Ӕ' => 'ӕ',
390
+ 'Ӗ' => 'ӗ',
391
+ 'Ә' => 'ә',
392
+ 'Ӛ' => 'ӛ',
393
+ 'Ӝ' => 'ӝ',
394
+ 'Ӟ' => 'ӟ',
395
+ 'Ӡ' => 'ӡ',
396
+ 'Ӣ' => 'ӣ',
397
+ 'Ӥ' => 'ӥ',
398
+ 'Ӧ' => 'ӧ',
399
+ 'Ө' => 'ө',
400
+ 'Ӫ' => 'ӫ',
401
+ 'Ӭ' => 'ӭ',
402
+ 'Ӯ' => 'ӯ',
403
+ 'Ӱ' => 'ӱ',
404
+ 'Ӳ' => 'ӳ',
405
+ 'Ӵ' => 'ӵ',
406
+ 'Ӷ' => 'ӷ',
407
+ 'Ӹ' => 'ӹ',
408
+ 'Ӻ' => 'ӻ',
409
+ 'Ӽ' => 'ӽ',
410
+ 'Ӿ' => 'ӿ',
411
+ 'Ԁ' => 'ԁ',
412
+ 'Ԃ' => 'ԃ',
413
+ 'Ԅ' => 'ԅ',
414
+ 'Ԇ' => 'ԇ',
415
+ 'Ԉ' => 'ԉ',
416
+ 'Ԋ' => 'ԋ',
417
+ 'Ԍ' => 'ԍ',
418
+ 'Ԏ' => 'ԏ',
419
+ 'Ԑ' => 'ԑ',
420
+ 'Ԓ' => 'ԓ',
421
+ 'Ԕ' => 'ԕ',
422
+ 'Ԗ' => 'ԗ',
423
+ 'Ԙ' => 'ԙ',
424
+ 'Ԛ' => 'ԛ',
425
+ 'Ԝ' => 'ԝ',
426
+ 'Ԟ' => 'ԟ',
427
+ 'Ԡ' => 'ԡ',
428
+ 'Ԣ' => 'ԣ',
429
+ 'Ԥ' => 'ԥ',
430
+ 'Ԧ' => 'ԧ',
431
+ 'Ԩ' => 'ԩ',
432
+ 'Ԫ' => 'ԫ',
433
+ 'Ԭ' => 'ԭ',
434
+ 'Ԯ' => 'ԯ',
435
+ 'Ա' => 'ա',
436
+ 'Բ' => 'բ',
437
+ 'Գ' => 'գ',
438
+ 'Դ' => 'դ',
439
+ 'Ե' => 'ե',
440
+ 'Զ' => 'զ',
441
+ 'Է' => 'է',
442
+ 'Ը' => 'ը',
443
+ 'Թ' => 'թ',
444
+ 'Ժ' => 'ժ',
445
+ 'Ի' => 'ի',
446
+ 'Լ' => 'լ',
447
+ 'Խ' => 'խ',
448
+ 'Ծ' => 'ծ',
449
+ 'Կ' => 'կ',
450
+ 'Հ' => 'հ',
451
+ 'Ձ' => 'ձ',
452
+ 'Ղ' => 'ղ',
453
+ 'Ճ' => 'ճ',
454
+ 'Մ' => 'մ',
455
+ 'Յ' => 'յ',
456
+ 'Ն' => 'ն',
457
+ 'Շ' => 'շ',
458
+ 'Ո' => 'ո',
459
+ 'Չ' => 'չ',
460
+ 'Պ' => 'պ',
461
+ 'Ջ' => 'ջ',
462
+ 'Ռ' => 'ռ',
463
+ 'Ս' => 'ս',
464
+ 'Վ' => 'վ',
465
+ 'Տ' => 'տ',
466
+ 'Ր' => 'ր',
467
+ 'Ց' => 'ց',
468
+ 'Ւ' => 'ւ',
469
+ 'Փ' => 'փ',
470
+ 'Ք' => 'ք',
471
+ 'Օ' => 'օ',
472
+ 'Ֆ' => 'ֆ',
473
+ 'Ⴀ' => 'ⴀ',
474
+ 'Ⴁ' => 'ⴁ',
475
+ 'Ⴂ' => 'ⴂ',
476
+ 'Ⴃ' => 'ⴃ',
477
+ 'Ⴄ' => 'ⴄ',
478
+ 'Ⴅ' => 'ⴅ',
479
+ 'Ⴆ' => 'ⴆ',
480
+ 'Ⴇ' => 'ⴇ',
481
+ 'Ⴈ' => 'ⴈ',
482
+ 'Ⴉ' => 'ⴉ',
483
+ 'Ⴊ' => 'ⴊ',
484
+ 'Ⴋ' => 'ⴋ',
485
+ 'Ⴌ' => 'ⴌ',
486
+ 'Ⴍ' => 'ⴍ',
487
+ 'Ⴎ' => 'ⴎ',
488
+ 'Ⴏ' => 'ⴏ',
489
+ 'Ⴐ' => 'ⴐ',
490
+ 'Ⴑ' => 'ⴑ',
491
+ 'Ⴒ' => 'ⴒ',
492
+ 'Ⴓ' => 'ⴓ',
493
+ 'Ⴔ' => 'ⴔ',
494
+ 'Ⴕ' => 'ⴕ',
495
+ 'Ⴖ' => 'ⴖ',
496
+ 'Ⴗ' => 'ⴗ',
497
+ 'Ⴘ' => 'ⴘ',
498
+ 'Ⴙ' => 'ⴙ',
499
+ 'Ⴚ' => 'ⴚ',
500
+ 'Ⴛ' => 'ⴛ',
501
+ 'Ⴜ' => 'ⴜ',
502
+ 'Ⴝ' => 'ⴝ',
503
+ 'Ⴞ' => 'ⴞ',
504
+ 'Ⴟ' => 'ⴟ',
505
+ 'Ⴠ' => 'ⴠ',
506
+ 'Ⴡ' => 'ⴡ',
507
+ 'Ⴢ' => 'ⴢ',
508
+ 'Ⴣ' => 'ⴣ',
509
+ 'Ⴤ' => 'ⴤ',
510
+ 'Ⴥ' => 'ⴥ',
511
+ 'Ⴧ' => 'ⴧ',
512
+ 'Ⴭ' => 'ⴭ',
513
+ 'Ꭰ' => 'ꭰ',
514
+ 'Ꭱ' => 'ꭱ',
515
+ 'Ꭲ' => 'ꭲ',
516
+ 'Ꭳ' => 'ꭳ',
517
+ 'Ꭴ' => 'ꭴ',
518
+ 'Ꭵ' => 'ꭵ',
519
+ 'Ꭶ' => 'ꭶ',
520
+ 'Ꭷ' => 'ꭷ',
521
+ 'Ꭸ' => 'ꭸ',
522
+ 'Ꭹ' => 'ꭹ',
523
+ 'Ꭺ' => 'ꭺ',
524
+ 'Ꭻ' => 'ꭻ',
525
+ 'Ꭼ' => 'ꭼ',
526
+ 'Ꭽ' => 'ꭽ',
527
+ 'Ꭾ' => 'ꭾ',
528
+ 'Ꭿ' => 'ꭿ',
529
+ 'Ꮀ' => 'ꮀ',
530
+ 'Ꮁ' => 'ꮁ',
531
+ 'Ꮂ' => 'ꮂ',
532
+ 'Ꮃ' => 'ꮃ',
533
+ 'Ꮄ' => 'ꮄ',
534
+ 'Ꮅ' => 'ꮅ',
535
+ 'Ꮆ' => 'ꮆ',
536
+ 'Ꮇ' => 'ꮇ',
537
+ 'Ꮈ' => 'ꮈ',
538
+ 'Ꮉ' => 'ꮉ',
539
+ 'Ꮊ' => 'ꮊ',
540
+ 'Ꮋ' => 'ꮋ',
541
+ 'Ꮌ' => 'ꮌ',
542
+ 'Ꮍ' => 'ꮍ',
543
+ 'Ꮎ' => 'ꮎ',
544
+ 'Ꮏ' => 'ꮏ',
545
+ 'Ꮐ' => 'ꮐ',
546
+ 'Ꮑ' => 'ꮑ',
547
+ 'Ꮒ' => 'ꮒ',
548
+ 'Ꮓ' => 'ꮓ',
549
+ 'Ꮔ' => 'ꮔ',
550
+ 'Ꮕ' => 'ꮕ',
551
+ 'Ꮖ' => 'ꮖ',
552
+ 'Ꮗ' => 'ꮗ',
553
+ 'Ꮘ' => 'ꮘ',
554
+ 'Ꮙ' => 'ꮙ',
555
+ 'Ꮚ' => 'ꮚ',
556
+ 'Ꮛ' => 'ꮛ',
557
+ 'Ꮜ' => 'ꮜ',
558
+ 'Ꮝ' => 'ꮝ',
559
+ 'Ꮞ' => 'ꮞ',
560
+ 'Ꮟ' => 'ꮟ',
561
+ 'Ꮠ' => 'ꮠ',
562
+ 'Ꮡ' => 'ꮡ',
563
+ 'Ꮢ' => 'ꮢ',
564
+ 'Ꮣ' => 'ꮣ',
565
+ 'Ꮤ' => 'ꮤ',
566
+ 'Ꮥ' => 'ꮥ',
567
+ 'Ꮦ' => 'ꮦ',
568
+ 'Ꮧ' => 'ꮧ',
569
+ 'Ꮨ' => 'ꮨ',
570
+ 'Ꮩ' => 'ꮩ',
571
+ 'Ꮪ' => 'ꮪ',
572
+ 'Ꮫ' => 'ꮫ',
573
+ 'Ꮬ' => 'ꮬ',
574
+ 'Ꮭ' => 'ꮭ',
575
+ 'Ꮮ' => 'ꮮ',
576
+ 'Ꮯ' => 'ꮯ',
577
+ 'Ꮰ' => 'ꮰ',
578
+ 'Ꮱ' => 'ꮱ',
579
+ 'Ꮲ' => 'ꮲ',
580
+ 'Ꮳ' => 'ꮳ',
581
+ 'Ꮴ' => 'ꮴ',
582
+ 'Ꮵ' => 'ꮵ',
583
+ 'Ꮶ' => 'ꮶ',
584
+ 'Ꮷ' => 'ꮷ',
585
+ 'Ꮸ' => 'ꮸ',
586
+ 'Ꮹ' => 'ꮹ',
587
+ 'Ꮺ' => 'ꮺ',
588
+ 'Ꮻ' => 'ꮻ',
589
+ 'Ꮼ' => 'ꮼ',
590
+ 'Ꮽ' => 'ꮽ',
591
+ 'Ꮾ' => 'ꮾ',
592
+ 'Ꮿ' => 'ꮿ',
593
+ 'Ᏸ' => 'ᏸ',
594
+ 'Ᏹ' => 'ᏹ',
595
+ 'Ᏺ' => 'ᏺ',
596
+ 'Ᏻ' => 'ᏻ',
597
+ 'Ᏼ' => 'ᏼ',
598
+ 'Ᏽ' => 'ᏽ',
599
+ 'Ა' => 'ა',
600
+ 'Ბ' => 'ბ',
601
+ 'Გ' => 'გ',
602
+ 'Დ' => 'დ',
603
+ 'Ე' => 'ე',
604
+ 'Ვ' => 'ვ',
605
+ 'Ზ' => 'ზ',
606
+ 'Თ' => 'თ',
607
+ 'Ი' => 'ი',
608
+ 'Კ' => 'კ',
609
+ 'Ლ' => 'ლ',
610
+ 'Მ' => 'მ',
611
+ 'Ნ' => 'ნ',
612
+ 'Ო' => 'ო',
613
+ 'Პ' => 'პ',
614
+ 'Ჟ' => 'ჟ',
615
+ 'Რ' => 'რ',
616
+ 'Ს' => 'ს',
617
+ 'Ტ' => 'ტ',
618
+ 'Უ' => 'უ',
619
+ 'Ფ' => 'ფ',
620
+ 'Ქ' => 'ქ',
621
+ 'Ღ' => 'ღ',
622
+ 'Ყ' => 'ყ',
623
+ 'Შ' => 'შ',
624
+ 'Ჩ' => 'ჩ',
625
+ 'Ც' => 'ც',
626
+ 'Ძ' => 'ძ',
627
+ 'Წ' => 'წ',
628
+ 'Ჭ' => 'ჭ',
629
+ 'Ხ' => 'ხ',
630
+ 'Ჯ' => 'ჯ',
631
+ 'Ჰ' => 'ჰ',
632
+ 'Ჱ' => 'ჱ',
633
+ 'Ჲ' => 'ჲ',
634
+ 'Ჳ' => 'ჳ',
635
+ 'Ჴ' => 'ჴ',
636
+ 'Ჵ' => 'ჵ',
637
+ 'Ჶ' => 'ჶ',
638
+ 'Ჷ' => 'ჷ',
639
+ 'Ჸ' => 'ჸ',
640
+ 'Ჹ' => 'ჹ',
641
+ 'Ჺ' => 'ჺ',
642
+ 'Ჽ' => 'ჽ',
643
+ 'Ჾ' => 'ჾ',
644
+ 'Ჿ' => 'ჿ',
645
+ 'Ḁ' => 'ḁ',
646
+ 'Ḃ' => 'ḃ',
647
+ 'Ḅ' => 'ḅ',
648
+ 'Ḇ' => 'ḇ',
649
+ 'Ḉ' => 'ḉ',
650
+ 'Ḋ' => 'ḋ',
651
+ 'Ḍ' => 'ḍ',
652
+ 'Ḏ' => 'ḏ',
653
+ 'Ḑ' => 'ḑ',
654
+ 'Ḓ' => 'ḓ',
655
+ 'Ḕ' => 'ḕ',
656
+ 'Ḗ' => 'ḗ',
657
+ 'Ḙ' => 'ḙ',
658
+ 'Ḛ' => 'ḛ',
659
+ 'Ḝ' => 'ḝ',
660
+ 'Ḟ' => 'ḟ',
661
+ 'Ḡ' => 'ḡ',
662
+ 'Ḣ' => 'ḣ',
663
+ 'Ḥ' => 'ḥ',
664
+ 'Ḧ' => 'ḧ',
665
+ 'Ḩ' => 'ḩ',
666
+ 'Ḫ' => 'ḫ',
667
+ 'Ḭ' => 'ḭ',
668
+ 'Ḯ' => 'ḯ',
669
+ 'Ḱ' => 'ḱ',
670
+ 'Ḳ' => 'ḳ',
671
+ 'Ḵ' => 'ḵ',
672
+ 'Ḷ' => 'ḷ',
673
+ 'Ḹ' => 'ḹ',
674
+ 'Ḻ' => 'ḻ',
675
+ 'Ḽ' => 'ḽ',
676
+ 'Ḿ' => 'ḿ',
677
+ 'Ṁ' => 'ṁ',
678
+ 'Ṃ' => 'ṃ',
679
+ 'Ṅ' => 'ṅ',
680
+ 'Ṇ' => 'ṇ',
681
+ 'Ṉ' => 'ṉ',
682
+ 'Ṋ' => 'ṋ',
683
+ 'Ṍ' => 'ṍ',
684
+ 'Ṏ' => 'ṏ',
685
+ 'Ṑ' => 'ṑ',
686
+ 'Ṓ' => 'ṓ',
687
+ 'Ṕ' => 'ṕ',
688
+ 'Ṗ' => 'ṗ',
689
+ 'Ṙ' => 'ṙ',
690
+ 'Ṛ' => 'ṛ',
691
+ 'Ṝ' => 'ṝ',
692
+ 'Ṟ' => 'ṟ',
693
+ 'Ṡ' => 'ṡ',
694
+ 'Ṣ' => 'ṣ',
695
+ 'Ṥ' => 'ṥ',
696
+ 'Ṧ' => 'ṧ',
697
+ 'Ṩ' => 'ṩ',
698
+ 'Ṫ' => 'ṫ',
699
+ 'Ṭ' => 'ṭ',
700
+ 'Ṯ' => 'ṯ',
701
+ 'Ṱ' => 'ṱ',
702
+ 'Ṳ' => 'ṳ',
703
+ 'Ṵ' => 'ṵ',
704
+ 'Ṷ' => 'ṷ',
705
+ 'Ṹ' => 'ṹ',
706
+ 'Ṻ' => 'ṻ',
707
+ 'Ṽ' => 'ṽ',
708
+ 'Ṿ' => 'ṿ',
709
+ 'Ẁ' => 'ẁ',
710
+ 'Ẃ' => 'ẃ',
711
+ 'Ẅ' => 'ẅ',
712
+ 'Ẇ' => 'ẇ',
713
+ 'Ẉ' => 'ẉ',
714
+ 'Ẋ' => 'ẋ',
715
+ 'Ẍ' => 'ẍ',
716
+ 'Ẏ' => 'ẏ',
717
+ 'Ẑ' => 'ẑ',
718
+ 'Ẓ' => 'ẓ',
719
+ 'Ẕ' => 'ẕ',
720
+ 'ẞ' => 'ß',
721
+ 'Ạ' => 'ạ',
722
+ 'Ả' => 'ả',
723
+ 'Ấ' => 'ấ',
724
+ 'Ầ' => 'ầ',
725
+ 'Ẩ' => 'ẩ',
726
+ 'Ẫ' => 'ẫ',
727
+ 'Ậ' => 'ậ',
728
+ 'Ắ' => 'ắ',
729
+ 'Ằ' => 'ằ',
730
+ 'Ẳ' => 'ẳ',
731
+ 'Ẵ' => 'ẵ',
732
+ 'Ặ' => 'ặ',
733
+ 'Ẹ' => 'ẹ',
734
+ 'Ẻ' => 'ẻ',
735
+ 'Ẽ' => 'ẽ',
736
+ 'Ế' => 'ế',
737
+ 'Ề' => 'ề',
738
+ 'Ể' => 'ể',
739
+ 'Ễ' => 'ễ',
740
+ 'Ệ' => 'ệ',
741
+ 'Ỉ' => 'ỉ',
742
+ 'Ị' => 'ị',
743
+ 'Ọ' => 'ọ',
744
+ 'Ỏ' => 'ỏ',
745
+ 'Ố' => 'ố',
746
+ 'Ồ' => 'ồ',
747
+ 'Ổ' => 'ổ',
748
+ 'Ỗ' => 'ỗ',
749
+ 'Ộ' => 'ộ',
750
+ 'Ớ' => 'ớ',
751
+ 'Ờ' => 'ờ',
752
+ 'Ở' => 'ở',
753
+ 'Ỡ' => 'ỡ',
754
+ 'Ợ' => 'ợ',
755
+ 'Ụ' => 'ụ',
756
+ 'Ủ' => 'ủ',
757
+ 'Ứ' => 'ứ',
758
+ 'Ừ' => 'ừ',
759
+ 'Ử' => 'ử',
760
+ 'Ữ' => 'ữ',
761
+ 'Ự' => 'ự',
762
+ 'Ỳ' => 'ỳ',
763
+ 'Ỵ' => 'ỵ',
764
+ 'Ỷ' => 'ỷ',
765
+ 'Ỹ' => 'ỹ',
766
+ 'Ỻ' => 'ỻ',
767
+ 'Ỽ' => 'ỽ',
768
+ 'Ỿ' => 'ỿ',
769
+ 'Ἀ' => 'ἀ',
770
+ 'Ἁ' => 'ἁ',
771
+ 'Ἂ' => 'ἂ',
772
+ 'Ἃ' => 'ἃ',
773
+ 'Ἄ' => 'ἄ',
774
+ 'Ἅ' => 'ἅ',
775
+ 'Ἆ' => 'ἆ',
776
+ 'Ἇ' => 'ἇ',
777
+ 'Ἐ' => 'ἐ',
778
+ 'Ἑ' => 'ἑ',
779
+ 'Ἒ' => 'ἒ',
780
+ 'Ἓ' => 'ἓ',
781
+ 'Ἔ' => 'ἔ',
782
+ 'Ἕ' => 'ἕ',
783
+ 'Ἠ' => 'ἠ',
784
+ 'Ἡ' => 'ἡ',
785
+ 'Ἢ' => 'ἢ',
786
+ 'Ἣ' => 'ἣ',
787
+ 'Ἤ' => 'ἤ',
788
+ 'Ἥ' => 'ἥ',
789
+ 'Ἦ' => 'ἦ',
790
+ 'Ἧ' => 'ἧ',
791
+ 'Ἰ' => 'ἰ',
792
+ 'Ἱ' => 'ἱ',
793
+ 'Ἲ' => 'ἲ',
794
+ 'Ἳ' => 'ἳ',
795
+ 'Ἴ' => 'ἴ',
796
+ 'Ἵ' => 'ἵ',
797
+ 'Ἶ' => 'ἶ',
798
+ 'Ἷ' => 'ἷ',
799
+ 'Ὀ' => 'ὀ',
800
+ 'Ὁ' => 'ὁ',
801
+ 'Ὂ' => 'ὂ',
802
+ 'Ὃ' => 'ὃ',
803
+ 'Ὄ' => 'ὄ',
804
+ 'Ὅ' => 'ὅ',
805
+ 'Ὑ' => 'ὑ',
806
+ 'Ὓ' => 'ὓ',
807
+ 'Ὕ' => 'ὕ',
808
+ 'Ὗ' => 'ὗ',
809
+ 'Ὠ' => 'ὠ',
810
+ 'Ὡ' => 'ὡ',
811
+ 'Ὢ' => 'ὢ',
812
+ 'Ὣ' => 'ὣ',
813
+ 'Ὤ' => 'ὤ',
814
+ 'Ὥ' => 'ὥ',
815
+ 'Ὦ' => 'ὦ',
816
+ 'Ὧ' => 'ὧ',
817
+ 'ᾈ' => 'ᾀ',
818
+ 'ᾉ' => 'ᾁ',
819
+ 'ᾊ' => 'ᾂ',
820
+ 'ᾋ' => 'ᾃ',
821
+ 'ᾌ' => 'ᾄ',
822
+ 'ᾍ' => 'ᾅ',
823
+ 'ᾎ' => 'ᾆ',
824
+ 'ᾏ' => 'ᾇ',
825
+ 'ᾘ' => 'ᾐ',
826
+ 'ᾙ' => 'ᾑ',
827
+ 'ᾚ' => 'ᾒ',
828
+ 'ᾛ' => 'ᾓ',
829
+ 'ᾜ' => 'ᾔ',
830
+ 'ᾝ' => 'ᾕ',
831
+ 'ᾞ' => 'ᾖ',
832
+ 'ᾟ' => 'ᾗ',
833
+ 'ᾨ' => 'ᾠ',
834
+ 'ᾩ' => 'ᾡ',
835
+ 'ᾪ' => 'ᾢ',
836
+ 'ᾫ' => 'ᾣ',
837
+ 'ᾬ' => 'ᾤ',
838
+ 'ᾭ' => 'ᾥ',
839
+ 'ᾮ' => 'ᾦ',
840
+ 'ᾯ' => 'ᾧ',
841
+ 'Ᾰ' => 'ᾰ',
842
+ 'Ᾱ' => 'ᾱ',
843
+ 'Ὰ' => 'ὰ',
844
+ 'Ά' => 'ά',
845
+ 'ᾼ' => 'ᾳ',
846
+ 'Ὲ' => 'ὲ',
847
+ 'Έ' => 'έ',
848
+ 'Ὴ' => 'ὴ',
849
+ 'Ή' => 'ή',
850
+ 'ῌ' => 'ῃ',
851
+ 'Ῐ' => 'ῐ',
852
+ 'Ῑ' => 'ῑ',
853
+ 'Ὶ' => 'ὶ',
854
+ 'Ί' => 'ί',
855
+ 'Ῠ' => 'ῠ',
856
+ 'Ῡ' => 'ῡ',
857
+ 'Ὺ' => 'ὺ',
858
+ 'Ύ' => 'ύ',
859
+ 'Ῥ' => 'ῥ',
860
+ 'Ὸ' => 'ὸ',
861
+ 'Ό' => 'ό',
862
+ 'Ὼ' => 'ὼ',
863
+ 'Ώ' => 'ώ',
864
+ 'ῼ' => 'ῳ',
865
+ 'Ω' => 'ω',
866
+ 'K' => 'k',
867
+ 'Å' => 'å',
868
+ 'Ⅎ' => 'ⅎ',
869
+ 'Ⅰ' => 'ⅰ',
870
+ 'Ⅱ' => 'ⅱ',
871
+ 'Ⅲ' => 'ⅲ',
872
+ 'Ⅳ' => 'ⅳ',
873
+ 'Ⅴ' => 'ⅴ',
874
+ 'Ⅵ' => 'ⅵ',
875
+ 'Ⅶ' => 'ⅶ',
876
+ 'Ⅷ' => 'ⅷ',
877
+ 'Ⅸ' => 'ⅸ',
878
+ 'Ⅹ' => 'ⅹ',
879
+ 'Ⅺ' => 'ⅺ',
880
+ 'Ⅻ' => 'ⅻ',
881
+ 'Ⅼ' => 'ⅼ',
882
+ 'Ⅽ' => 'ⅽ',
883
+ 'Ⅾ' => 'ⅾ',
884
+ 'Ⅿ' => 'ⅿ',
885
+ 'Ↄ' => 'ↄ',
886
+ 'Ⓐ' => 'ⓐ',
887
+ 'Ⓑ' => 'ⓑ',
888
+ 'Ⓒ' => 'ⓒ',
889
+ 'Ⓓ' => 'ⓓ',
890
+ 'Ⓔ' => 'ⓔ',
891
+ 'Ⓕ' => 'ⓕ',
892
+ 'Ⓖ' => 'ⓖ',
893
+ 'Ⓗ' => 'ⓗ',
894
+ 'Ⓘ' => 'ⓘ',
895
+ 'Ⓙ' => 'ⓙ',
896
+ 'Ⓚ' => 'ⓚ',
897
+ 'Ⓛ' => 'ⓛ',
898
+ 'Ⓜ' => 'ⓜ',
899
+ 'Ⓝ' => 'ⓝ',
900
+ 'Ⓞ' => 'ⓞ',
901
+ 'Ⓟ' => 'ⓟ',
902
+ 'Ⓠ' => 'ⓠ',
903
+ 'Ⓡ' => 'ⓡ',
904
+ 'Ⓢ' => 'ⓢ',
905
+ 'Ⓣ' => 'ⓣ',
906
+ 'Ⓤ' => 'ⓤ',
907
+ 'Ⓥ' => 'ⓥ',
908
+ 'Ⓦ' => 'ⓦ',
909
+ 'Ⓧ' => 'ⓧ',
910
+ 'Ⓨ' => 'ⓨ',
911
+ 'Ⓩ' => 'ⓩ',
912
+ 'Ⰰ' => 'ⰰ',
913
+ 'Ⰱ' => 'ⰱ',
914
+ 'Ⰲ' => 'ⰲ',
915
+ 'Ⰳ' => 'ⰳ',
916
+ 'Ⰴ' => 'ⰴ',
917
+ 'Ⰵ' => 'ⰵ',
918
+ 'Ⰶ' => 'ⰶ',
919
+ 'Ⰷ' => 'ⰷ',
920
+ 'Ⰸ' => 'ⰸ',
921
+ 'Ⰹ' => 'ⰹ',
922
+ 'Ⰺ' => 'ⰺ',
923
+ 'Ⰻ' => 'ⰻ',
924
+ 'Ⰼ' => 'ⰼ',
925
+ 'Ⰽ' => 'ⰽ',
926
+ 'Ⰾ' => 'ⰾ',
927
+ 'Ⰿ' => 'ⰿ',
928
+ 'Ⱀ' => 'ⱀ',
929
+ 'Ⱁ' => 'ⱁ',
930
+ 'Ⱂ' => 'ⱂ',
931
+ 'Ⱃ' => 'ⱃ',
932
+ 'Ⱄ' => 'ⱄ',
933
+ 'Ⱅ' => 'ⱅ',
934
+ 'Ⱆ' => 'ⱆ',
935
+ 'Ⱇ' => 'ⱇ',
936
+ 'Ⱈ' => 'ⱈ',
937
+ 'Ⱉ' => 'ⱉ',
938
+ 'Ⱊ' => 'ⱊ',
939
+ 'Ⱋ' => 'ⱋ',
940
+ 'Ⱌ' => 'ⱌ',
941
+ 'Ⱍ' => 'ⱍ',
942
+ 'Ⱎ' => 'ⱎ',
943
+ 'Ⱏ' => 'ⱏ',
944
+ 'Ⱐ' => 'ⱐ',
945
+ 'Ⱑ' => 'ⱑ',
946
+ 'Ⱒ' => 'ⱒ',
947
+ 'Ⱓ' => 'ⱓ',
948
+ 'Ⱔ' => 'ⱔ',
949
+ 'Ⱕ' => 'ⱕ',
950
+ 'Ⱖ' => 'ⱖ',
951
+ 'Ⱗ' => 'ⱗ',
952
+ 'Ⱘ' => 'ⱘ',
953
+ 'Ⱙ' => 'ⱙ',
954
+ 'Ⱚ' => 'ⱚ',
955
+ 'Ⱛ' => 'ⱛ',
956
+ 'Ⱜ' => 'ⱜ',
957
+ 'Ⱝ' => 'ⱝ',
958
+ 'Ⱞ' => 'ⱞ',
959
+ 'Ⱡ' => 'ⱡ',
960
+ 'Ɫ' => 'ɫ',
961
+ 'Ᵽ' => 'ᵽ',
962
+ 'Ɽ' => 'ɽ',
963
+ 'Ⱨ' => 'ⱨ',
964
+ 'Ⱪ' => 'ⱪ',
965
+ 'Ⱬ' => 'ⱬ',
966
+ 'Ɑ' => 'ɑ',
967
+ 'Ɱ' => 'ɱ',
968
+ 'Ɐ' => 'ɐ',
969
+ 'Ɒ' => 'ɒ',
970
+ 'Ⱳ' => 'ⱳ',
971
+ 'Ⱶ' => 'ⱶ',
972
+ 'Ȿ' => 'ȿ',
973
+ 'Ɀ' => 'ɀ',
974
+ 'Ⲁ' => 'ⲁ',
975
+ 'Ⲃ' => 'ⲃ',
976
+ 'Ⲅ' => 'ⲅ',
977
+ 'Ⲇ' => 'ⲇ',
978
+ 'Ⲉ' => 'ⲉ',
979
+ 'Ⲋ' => 'ⲋ',
980
+ 'Ⲍ' => 'ⲍ',
981
+ 'Ⲏ' => 'ⲏ',
982
+ 'Ⲑ' => 'ⲑ',
983
+ 'Ⲓ' => 'ⲓ',
984
+ 'Ⲕ' => 'ⲕ',
985
+ 'Ⲗ' => 'ⲗ',
986
+ 'Ⲙ' => 'ⲙ',
987
+ 'Ⲛ' => 'ⲛ',
988
+ 'Ⲝ' => 'ⲝ',
989
+ 'Ⲟ' => 'ⲟ',
990
+ 'Ⲡ' => 'ⲡ',
991
+ 'Ⲣ' => 'ⲣ',
992
+ 'Ⲥ' => 'ⲥ',
993
+ 'Ⲧ' => 'ⲧ',
994
+ 'Ⲩ' => 'ⲩ',
995
+ 'Ⲫ' => 'ⲫ',
996
+ 'Ⲭ' => 'ⲭ',
997
+ 'Ⲯ' => 'ⲯ',
998
+ 'Ⲱ' => 'ⲱ',
999
+ 'Ⲳ' => 'ⲳ',
1000
+ 'Ⲵ' => 'ⲵ',
1001
+ 'Ⲷ' => 'ⲷ',
1002
+ 'Ⲹ' => 'ⲹ',
1003
+ 'Ⲻ' => 'ⲻ',
1004
+ 'Ⲽ' => 'ⲽ',
1005
+ 'Ⲿ' => 'ⲿ',
1006
+ 'Ⳁ' => 'ⳁ',
1007
+ 'Ⳃ' => 'ⳃ',
1008
+ 'Ⳅ' => 'ⳅ',
1009
+ 'Ⳇ' => 'ⳇ',
1010
+ 'Ⳉ' => 'ⳉ',
1011
+ 'Ⳋ' => 'ⳋ',
1012
+ 'Ⳍ' => 'ⳍ',
1013
+ 'Ⳏ' => 'ⳏ',
1014
+ 'Ⳑ' => 'ⳑ',
1015
+ 'Ⳓ' => 'ⳓ',
1016
+ 'Ⳕ' => 'ⳕ',
1017
+ 'Ⳗ' => 'ⳗ',
1018
+ 'Ⳙ' => 'ⳙ',
1019
+ 'Ⳛ' => 'ⳛ',
1020
+ 'Ⳝ' => 'ⳝ',
1021
+ 'Ⳟ' => 'ⳟ',
1022
+ 'Ⳡ' => 'ⳡ',
1023
+ 'Ⳣ' => 'ⳣ',
1024
+ 'Ⳬ' => 'ⳬ',
1025
+ 'Ⳮ' => 'ⳮ',
1026
+ 'Ⳳ' => 'ⳳ',
1027
+ 'Ꙁ' => 'ꙁ',
1028
+ 'Ꙃ' => 'ꙃ',
1029
+ 'Ꙅ' => 'ꙅ',
1030
+ 'Ꙇ' => 'ꙇ',
1031
+ 'Ꙉ' => 'ꙉ',
1032
+ 'Ꙋ' => 'ꙋ',
1033
+ 'Ꙍ' => 'ꙍ',
1034
+ 'Ꙏ' => 'ꙏ',
1035
+ 'Ꙑ' => 'ꙑ',
1036
+ 'Ꙓ' => 'ꙓ',
1037
+ 'Ꙕ' => 'ꙕ',
1038
+ 'Ꙗ' => 'ꙗ',
1039
+ 'Ꙙ' => 'ꙙ',
1040
+ 'Ꙛ' => 'ꙛ',
1041
+ 'Ꙝ' => 'ꙝ',
1042
+ 'Ꙟ' => 'ꙟ',
1043
+ 'Ꙡ' => 'ꙡ',
1044
+ 'Ꙣ' => 'ꙣ',
1045
+ 'Ꙥ' => 'ꙥ',
1046
+ 'Ꙧ' => 'ꙧ',
1047
+ 'Ꙩ' => 'ꙩ',
1048
+ 'Ꙫ' => 'ꙫ',
1049
+ 'Ꙭ' => 'ꙭ',
1050
+ 'Ꚁ' => 'ꚁ',
1051
+ 'Ꚃ' => 'ꚃ',
1052
+ 'Ꚅ' => 'ꚅ',
1053
+ 'Ꚇ' => 'ꚇ',
1054
+ 'Ꚉ' => 'ꚉ',
1055
+ 'Ꚋ' => 'ꚋ',
1056
+ 'Ꚍ' => 'ꚍ',
1057
+ 'Ꚏ' => 'ꚏ',
1058
+ 'Ꚑ' => 'ꚑ',
1059
+ 'Ꚓ' => 'ꚓ',
1060
+ 'Ꚕ' => 'ꚕ',
1061
+ 'Ꚗ' => 'ꚗ',
1062
+ 'Ꚙ' => 'ꚙ',
1063
+ 'Ꚛ' => 'ꚛ',
1064
+ 'Ꜣ' => 'ꜣ',
1065
+ 'Ꜥ' => 'ꜥ',
1066
+ 'Ꜧ' => 'ꜧ',
1067
+ 'Ꜩ' => 'ꜩ',
1068
+ 'Ꜫ' => 'ꜫ',
1069
+ 'Ꜭ' => 'ꜭ',
1070
+ 'Ꜯ' => 'ꜯ',
1071
+ 'Ꜳ' => 'ꜳ',
1072
+ 'Ꜵ' => 'ꜵ',
1073
+ 'Ꜷ' => 'ꜷ',
1074
+ 'Ꜹ' => 'ꜹ',
1075
+ 'Ꜻ' => 'ꜻ',
1076
+ 'Ꜽ' => 'ꜽ',
1077
+ 'Ꜿ' => 'ꜿ',
1078
+ 'Ꝁ' => 'ꝁ',
1079
+ 'Ꝃ' => 'ꝃ',
1080
+ 'Ꝅ' => 'ꝅ',
1081
+ 'Ꝇ' => 'ꝇ',
1082
+ 'Ꝉ' => 'ꝉ',
1083
+ 'Ꝋ' => 'ꝋ',
1084
+ 'Ꝍ' => 'ꝍ',
1085
+ 'Ꝏ' => 'ꝏ',
1086
+ 'Ꝑ' => 'ꝑ',
1087
+ 'Ꝓ' => 'ꝓ',
1088
+ 'Ꝕ' => 'ꝕ',
1089
+ 'Ꝗ' => 'ꝗ',
1090
+ 'Ꝙ' => 'ꝙ',
1091
+ 'Ꝛ' => 'ꝛ',
1092
+ 'Ꝝ' => 'ꝝ',
1093
+ 'Ꝟ' => 'ꝟ',
1094
+ 'Ꝡ' => 'ꝡ',
1095
+ 'Ꝣ' => 'ꝣ',
1096
+ 'Ꝥ' => 'ꝥ',
1097
+ 'Ꝧ' => 'ꝧ',
1098
+ 'Ꝩ' => 'ꝩ',
1099
+ 'Ꝫ' => 'ꝫ',
1100
+ 'Ꝭ' => 'ꝭ',
1101
+ 'Ꝯ' => 'ꝯ',
1102
+ 'Ꝺ' => 'ꝺ',
1103
+ 'Ꝼ' => 'ꝼ',
1104
+ 'Ᵹ' => 'ᵹ',
1105
+ 'Ꝿ' => 'ꝿ',
1106
+ 'Ꞁ' => 'ꞁ',
1107
+ 'Ꞃ' => 'ꞃ',
1108
+ 'Ꞅ' => 'ꞅ',
1109
+ 'Ꞇ' => 'ꞇ',
1110
+ 'Ꞌ' => 'ꞌ',
1111
+ 'Ɥ' => 'ɥ',
1112
+ 'Ꞑ' => 'ꞑ',
1113
+ 'Ꞓ' => 'ꞓ',
1114
+ 'Ꞗ' => 'ꞗ',
1115
+ 'Ꞙ' => 'ꞙ',
1116
+ 'Ꞛ' => 'ꞛ',
1117
+ 'Ꞝ' => 'ꞝ',
1118
+ 'Ꞟ' => 'ꞟ',
1119
+ 'Ꞡ' => 'ꞡ',
1120
+ 'Ꞣ' => 'ꞣ',
1121
+ 'Ꞥ' => 'ꞥ',
1122
+ 'Ꞧ' => 'ꞧ',
1123
+ 'Ꞩ' => 'ꞩ',
1124
+ 'Ɦ' => 'ɦ',
1125
+ 'Ɜ' => 'ɜ',
1126
+ 'Ɡ' => 'ɡ',
1127
+ 'Ɬ' => 'ɬ',
1128
+ 'Ɪ' => 'ɪ',
1129
+ 'Ʞ' => 'ʞ',
1130
+ 'Ʇ' => 'ʇ',
1131
+ 'Ʝ' => 'ʝ',
1132
+ 'Ꭓ' => 'ꭓ',
1133
+ 'Ꞵ' => 'ꞵ',
1134
+ 'Ꞷ' => 'ꞷ',
1135
+ 'Ꞹ' => 'ꞹ',
1136
+ 'Ꞻ' => 'ꞻ',
1137
+ 'Ꞽ' => 'ꞽ',
1138
+ 'Ꞿ' => 'ꞿ',
1139
+ 'Ꟃ' => 'ꟃ',
1140
+ 'Ꞔ' => 'ꞔ',
1141
+ 'Ʂ' => 'ʂ',
1142
+ 'Ᶎ' => 'ᶎ',
1143
+ 'Ꟈ' => 'ꟈ',
1144
+ 'Ꟊ' => 'ꟊ',
1145
+ 'Ꟶ' => 'ꟶ',
1146
+ 'A' => 'a',
1147
+ 'B' => 'b',
1148
+ 'C' => 'c',
1149
+ 'D' => 'd',
1150
+ 'E' => 'e',
1151
+ 'F' => 'f',
1152
+ 'G' => 'g',
1153
+ 'H' => 'h',
1154
+ 'I' => 'i',
1155
+ 'J' => 'j',
1156
+ 'K' => 'k',
1157
+ 'L' => 'l',
1158
+ 'M' => 'm',
1159
+ 'N' => 'n',
1160
+ 'O' => 'o',
1161
+ 'P' => 'p',
1162
+ 'Q' => 'q',
1163
+ 'R' => 'r',
1164
+ 'S' => 's',
1165
+ 'T' => 't',
1166
+ 'U' => 'u',
1167
+ 'V' => 'v',
1168
+ 'W' => 'w',
1169
+ 'X' => 'x',
1170
+ 'Y' => 'y',
1171
+ 'Z' => 'z',
1172
+ '𐐀' => '𐐨',
1173
+ '𐐁' => '𐐩',
1174
+ '𐐂' => '𐐪',
1175
+ '𐐃' => '𐐫',
1176
+ '𐐄' => '𐐬',
1177
+ '𐐅' => '𐐭',
1178
+ '𐐆' => '𐐮',
1179
+ '𐐇' => '𐐯',
1180
+ '𐐈' => '𐐰',
1181
+ '𐐉' => '𐐱',
1182
+ '𐐊' => '𐐲',
1183
+ '𐐋' => '𐐳',
1184
+ '𐐌' => '𐐴',
1185
+ '𐐍' => '𐐵',
1186
+ '𐐎' => '𐐶',
1187
+ '𐐏' => '𐐷',
1188
+ '𐐐' => '𐐸',
1189
+ '𐐑' => '𐐹',
1190
+ '𐐒' => '𐐺',
1191
+ '𐐓' => '𐐻',
1192
+ '𐐔' => '𐐼',
1193
+ '𐐕' => '𐐽',
1194
+ '𐐖' => '𐐾',
1195
+ '𐐗' => '𐐿',
1196
+ '𐐘' => '𐑀',
1197
+ '𐐙' => '𐑁',
1198
+ '𐐚' => '𐑂',
1199
+ '𐐛' => '𐑃',
1200
+ '𐐜' => '𐑄',
1201
+ '𐐝' => '𐑅',
1202
+ '𐐞' => '𐑆',
1203
+ '𐐟' => '𐑇',
1204
+ '𐐠' => '𐑈',
1205
+ '𐐡' => '𐑉',
1206
+ '𐐢' => '𐑊',
1207
+ '𐐣' => '𐑋',
1208
+ '𐐤' => '𐑌',
1209
+ '𐐥' => '𐑍',
1210
+ '𐐦' => '𐑎',
1211
+ '𐐧' => '𐑏',
1212
+ '𐒰' => '𐓘',
1213
+ '𐒱' => '𐓙',
1214
+ '𐒲' => '𐓚',
1215
+ '𐒳' => '𐓛',
1216
+ '𐒴' => '𐓜',
1217
+ '𐒵' => '𐓝',
1218
+ '𐒶' => '𐓞',
1219
+ '𐒷' => '𐓟',
1220
+ '𐒸' => '𐓠',
1221
+ '𐒹' => '𐓡',
1222
+ '𐒺' => '𐓢',
1223
+ '𐒻' => '𐓣',
1224
+ '𐒼' => '𐓤',
1225
+ '𐒽' => '𐓥',
1226
+ '𐒾' => '𐓦',
1227
+ '𐒿' => '𐓧',
1228
+ '𐓀' => '𐓨',
1229
+ '𐓁' => '𐓩',
1230
+ '𐓂' => '𐓪',
1231
+ '𐓃' => '𐓫',
1232
+ '𐓄' => '𐓬',
1233
+ '𐓅' => '𐓭',
1234
+ '𐓆' => '𐓮',
1235
+ '𐓇' => '𐓯',
1236
+ '𐓈' => '𐓰',
1237
+ '𐓉' => '𐓱',
1238
+ '𐓊' => '𐓲',
1239
+ '𐓋' => '𐓳',
1240
+ '𐓌' => '𐓴',
1241
+ '𐓍' => '𐓵',
1242
+ '𐓎' => '𐓶',
1243
+ '𐓏' => '𐓷',
1244
+ '𐓐' => '𐓸',
1245
+ '𐓑' => '𐓹',
1246
+ '𐓒' => '𐓺',
1247
+ '𐓓' => '𐓻',
1248
+ '𐲀' => '𐳀',
1249
+ '𐲁' => '𐳁',
1250
+ '𐲂' => '𐳂',
1251
+ '𐲃' => '𐳃',
1252
+ '𐲄' => '𐳄',
1253
+ '𐲅' => '𐳅',
1254
+ '𐲆' => '𐳆',
1255
+ '𐲇' => '𐳇',
1256
+ '𐲈' => '𐳈',
1257
+ '𐲉' => '𐳉',
1258
+ '𐲊' => '𐳊',
1259
+ '𐲋' => '𐳋',
1260
+ '𐲌' => '𐳌',
1261
+ '𐲍' => '𐳍',
1262
+ '𐲎' => '𐳎',
1263
+ '𐲏' => '𐳏',
1264
+ '𐲐' => '𐳐',
1265
+ '𐲑' => '𐳑',
1266
+ '𐲒' => '𐳒',
1267
+ '𐲓' => '𐳓',
1268
+ '𐲔' => '𐳔',
1269
+ '𐲕' => '𐳕',
1270
+ '𐲖' => '𐳖',
1271
+ '𐲗' => '𐳗',
1272
+ '𐲘' => '𐳘',
1273
+ '𐲙' => '𐳙',
1274
+ '𐲚' => '𐳚',
1275
+ '𐲛' => '𐳛',
1276
+ '𐲜' => '𐳜',
1277
+ '𐲝' => '𐳝',
1278
+ '𐲞' => '𐳞',
1279
+ '𐲟' => '𐳟',
1280
+ '𐲠' => '𐳠',
1281
+ '𐲡' => '𐳡',
1282
+ '𐲢' => '𐳢',
1283
+ '𐲣' => '𐳣',
1284
+ '𐲤' => '𐳤',
1285
+ '𐲥' => '𐳥',
1286
+ '𐲦' => '𐳦',
1287
+ '𐲧' => '𐳧',
1288
+ '𐲨' => '𐳨',
1289
+ '𐲩' => '𐳩',
1290
+ '𐲪' => '𐳪',
1291
+ '𐲫' => '𐳫',
1292
+ '𐲬' => '𐳬',
1293
+ '𐲭' => '𐳭',
1294
+ '𐲮' => '𐳮',
1295
+ '𐲯' => '𐳯',
1296
+ '𐲰' => '𐳰',
1297
+ '𐲱' => '𐳱',
1298
+ '𐲲' => '𐳲',
1299
+ '𑢠' => '𑣀',
1300
+ '𑢡' => '𑣁',
1301
+ '𑢢' => '𑣂',
1302
+ '𑢣' => '𑣃',
1303
+ '𑢤' => '𑣄',
1304
+ '𑢥' => '𑣅',
1305
+ '𑢦' => '𑣆',
1306
+ '𑢧' => '𑣇',
1307
+ '𑢨' => '𑣈',
1308
+ '𑢩' => '𑣉',
1309
+ '𑢪' => '𑣊',
1310
+ '𑢫' => '𑣋',
1311
+ '𑢬' => '𑣌',
1312
+ '𑢭' => '𑣍',
1313
+ '𑢮' => '𑣎',
1314
+ '𑢯' => '𑣏',
1315
+ '𑢰' => '𑣐',
1316
+ '𑢱' => '𑣑',
1317
+ '𑢲' => '𑣒',
1318
+ '𑢳' => '𑣓',
1319
+ '𑢴' => '𑣔',
1320
+ '𑢵' => '𑣕',
1321
+ '𑢶' => '𑣖',
1322
+ '𑢷' => '𑣗',
1323
+ '𑢸' => '𑣘',
1324
+ '𑢹' => '𑣙',
1325
+ '𑢺' => '𑣚',
1326
+ '𑢻' => '𑣛',
1327
+ '𑢼' => '𑣜',
1328
+ '𑢽' => '𑣝',
1329
+ '𑢾' => '𑣞',
1330
+ '𑢿' => '𑣟',
1331
+ '𖹀' => '𖹠',
1332
+ '𖹁' => '𖹡',
1333
+ '𖹂' => '𖹢',
1334
+ '𖹃' => '𖹣',
1335
+ '𖹄' => '𖹤',
1336
+ '𖹅' => '𖹥',
1337
+ '𖹆' => '𖹦',
1338
+ '𖹇' => '𖹧',
1339
+ '𖹈' => '𖹨',
1340
+ '𖹉' => '𖹩',
1341
+ '𖹊' => '𖹪',
1342
+ '𖹋' => '𖹫',
1343
+ '𖹌' => '𖹬',
1344
+ '𖹍' => '𖹭',
1345
+ '𖹎' => '𖹮',
1346
+ '𖹏' => '𖹯',
1347
+ '𖹐' => '𖹰',
1348
+ '𖹑' => '𖹱',
1349
+ '𖹒' => '𖹲',
1350
+ '𖹓' => '𖹳',
1351
+ '𖹔' => '𖹴',
1352
+ '𖹕' => '𖹵',
1353
+ '𖹖' => '𖹶',
1354
+ '𖹗' => '𖹷',
1355
+ '𖹘' => '𖹸',
1356
+ '𖹙' => '𖹹',
1357
+ '𖹚' => '𖹺',
1358
+ '𖹛' => '𖹻',
1359
+ '𖹜' => '𖹼',
1360
+ '𖹝' => '𖹽',
1361
+ '𖹞' => '𖹾',
1362
+ '𖹟' => '𖹿',
1363
+ '𞤀' => '𞤢',
1364
+ '𞤁' => '𞤣',
1365
+ '𞤂' => '𞤤',
1366
+ '𞤃' => '𞤥',
1367
+ '𞤄' => '𞤦',
1368
+ '𞤅' => '𞤧',
1369
+ '𞤆' => '𞤨',
1370
+ '𞤇' => '𞤩',
1371
+ '𞤈' => '𞤪',
1372
+ '𞤉' => '𞤫',
1373
+ '𞤊' => '𞤬',
1374
+ '𞤋' => '𞤭',
1375
+ '𞤌' => '𞤮',
1376
+ '𞤍' => '𞤯',
1377
+ '𞤎' => '𞤰',
1378
+ '𞤏' => '𞤱',
1379
+ '𞤐' => '𞤲',
1380
+ '𞤑' => '𞤳',
1381
+ '𞤒' => '𞤴',
1382
+ '𞤓' => '𞤵',
1383
+ '𞤔' => '𞤶',
1384
+ '𞤕' => '𞤷',
1385
+ '𞤖' => '𞤸',
1386
+ '𞤗' => '𞤹',
1387
+ '𞤘' => '𞤺',
1388
+ '𞤙' => '𞤻',
1389
+ '𞤚' => '𞤼',
1390
+ '𞤛' => '𞤽',
1391
+ '𞤜' => '𞤾',
1392
+ '𞤝' => '𞤿',
1393
+ '𞤞' => '𞥀',
1394
+ '𞤟' => '𞥁',
1395
+ '𞤠' => '𞥂',
1396
+ '𞤡' => '𞥃',
1397
+ );
vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+
3
+ // from Case_Ignorable in https://unicode.org/Public/UNIDATA/DerivedCoreProperties.txt
4
+
5
+ return '/(?<![\x{0027}\x{002E}\x{003A}\x{005E}\x{0060}\x{00A8}\x{00AD}\x{00AF}\x{00B4}\x{00B7}\x{00B8}\x{02B0}-\x{02C1}\x{02C2}-\x{02C5}\x{02C6}-\x{02D1}\x{02D2}-\x{02DF}\x{02E0}-\x{02E4}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EE}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037A}\x{0384}-\x{0385}\x{0387}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0559}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{05F4}\x{0600}-\x{0605}\x{0610}-\x{061A}\x{061C}\x{0640}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DD}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{070F}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07FA}\x{07FD}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0971}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CBF}\x{0CC6}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E46}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EB9}\x{0EBB}-\x{0EBC}\x{0EC6}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{10FC}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17D7}\x{17DD}\x{180B}-\x{180D}\x{180E}\x{1843}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AA7}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1C78}-\x{1C7D}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1D2C}-\x{1D6A}\x{1D78}\x{1D9B}-\x{1DBF}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{200B}-\x{200F}\x{2018}\x{2019}\x{2024}\x{2027}\x{202A}-\x{202E}\x{2060}-\x{2064}\x{2066}-\x{206F}\x{2071}\x{207F}\x{2090}-\x{209C}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2C7C}-\x{2C7D}\x{2CEF}-\x{2CF1}\x{2D6F}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E2F}\x{3005}\x{302A}-\x{302D}\x{3031}-\x{3035}\x{303B}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{309D}-\x{309E}\x{30FC}-\x{30FE}\x{A015}\x{A4F8}-\x{A4FD}\x{A60C}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A67F}\x{A69C}-\x{A69D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A770}\x{A788}\x{A789}-\x{A78A}\x{A7F8}-\x{A7F9}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}\x{A9CF}\x{A9E5}\x{A9E6}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA70}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AADD}\x{AAEC}-\x{AAED}\x{AAF3}-\x{AAF4}\x{AAF6}\x{AB5B}\x{AB5C}-\x{AB5F}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FBB2}-\x{FBC1}\x{FE00}-\x{FE0F}\x{FE13}\x{FE20}-\x{FE2F}\x{FE52}\x{FE55}\x{FEFF}\x{FF07}\x{FF0E}\x{FF1A}\x{FF3E}\x{FF40}\x{FF70}\x{FF9E}-\x{FF9F}\x{FFE3}\x{FFF9}-\x{FFFB}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{110BD}\x{110CD}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16B40}-\x{16B43}\x{16F8F}-\x{16F92}\x{16F93}-\x{16F9F}\x{16FE0}-\x{16FE1}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{1F3FB}-\x{1F3FF}\x{E0001}\x{E0020}-\x{E007F}\x{E0100}-\x{E01EF}])(\pL)(\pL*+)/u';
vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php ADDED
@@ -0,0 +1,1489 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ return array (
4
+ 'a' => 'A',
5
+ 'b' => 'B',
6
+ 'c' => 'C',
7
+ 'd' => 'D',
8
+ 'e' => 'E',
9
+ 'f' => 'F',
10
+ 'g' => 'G',
11
+ 'h' => 'H',
12
+ 'i' => 'I',
13
+ 'j' => 'J',
14
+ 'k' => 'K',
15
+ 'l' => 'L',
16
+ 'm' => 'M',
17
+ 'n' => 'N',
18
+ 'o' => 'O',
19
+ 'p' => 'P',
20
+ 'q' => 'Q',
21
+ 'r' => 'R',
22
+ 's' => 'S',
23
+ 't' => 'T',
24
+ 'u' => 'U',
25
+ 'v' => 'V',
26
+ 'w' => 'W',
27
+ 'x' => 'X',
28
+ 'y' => 'Y',
29
+ 'z' => 'Z',
30
+ 'µ' => 'Μ',
31
+ 'à' => 'À',
32
+ 'á' => 'Á',
33
+ 'â' => 'Â',
34
+ 'ã' => 'Ã',
35
+ 'ä' => 'Ä',
36
+ 'å' => 'Å',
37
+ 'æ' => 'Æ',
38
+ 'ç' => 'Ç',
39
+ 'è' => 'È',
40
+ 'é' => 'É',
41
+ 'ê' => 'Ê',
42
+ 'ë' => 'Ë',
43
+ 'ì' => 'Ì',
44
+ 'í' => 'Í',
45
+ 'î' => 'Î',
46
+ 'ï' => 'Ï',
47
+ 'ð' => 'Ð',
48
+ 'ñ' => 'Ñ',
49
+ 'ò' => 'Ò',
50
+ 'ó' => 'Ó',
51
+ 'ô' => 'Ô',
52
+ 'õ' => 'Õ',
53
+ 'ö' => 'Ö',
54
+ 'ø' => 'Ø',
55
+ 'ù' => 'Ù',
56
+ 'ú' => 'Ú',
57
+ 'û' => 'Û',
58
+ 'ü' => 'Ü',
59
+ 'ý' => 'Ý',
60
+ 'þ' => 'Þ',
61
+ 'ÿ' => 'Ÿ',
62
+ 'ā' => 'Ā',
63
+ 'ă' => 'Ă',
64
+ 'ą' => 'Ą',
65
+ 'ć' => 'Ć',
66
+ 'ĉ' => 'Ĉ',
67
+ 'ċ' => 'Ċ',
68
+ 'č' => 'Č',
69
+ 'ď' => 'Ď',
70
+ 'đ' => 'Đ',
71
+ 'ē' => 'Ē',
72
+ 'ĕ' => 'Ĕ',
73
+ 'ė' => 'Ė',
74
+ 'ę' => 'Ę',
75
+ 'ě' => 'Ě',
76
+ 'ĝ' => 'Ĝ',
77
+ 'ğ' => 'Ğ',
78
+ 'ġ' => 'Ġ',
79
+ 'ģ' => 'Ģ',
80
+ 'ĥ' => 'Ĥ',
81
+ 'ħ' => 'Ħ',
82
+ 'ĩ' => 'Ĩ',
83
+ 'ī' => 'Ī',
84
+ 'ĭ' => 'Ĭ',
85
+ 'į' => 'Į',
86
+ 'ı' => 'I',
87
+ 'ij' => 'IJ',
88
+ 'ĵ' => 'Ĵ',
89
+ 'ķ' => 'Ķ',
90
+ 'ĺ' => 'Ĺ',
91
+ 'ļ' => 'Ļ',
92
+ 'ľ' => 'Ľ',
93
+ 'ŀ' => 'Ŀ',
94
+ 'ł' => 'Ł',
95
+ 'ń' => 'Ń',
96
+ 'ņ' => 'Ņ',
97
+ 'ň' => 'Ň',
98
+ 'ŋ' => 'Ŋ',
99
+ 'ō' => 'Ō',
100
+ 'ŏ' => 'Ŏ',
101
+ 'ő' => 'Ő',
102
+ 'œ' => 'Œ',
103
+ 'ŕ' => 'Ŕ',
104
+ 'ŗ' => 'Ŗ',
105
+ 'ř' => 'Ř',
106
+ 'ś' => 'Ś',
107
+ 'ŝ' => 'Ŝ',
108
+ 'ş' => 'Ş',
109
+ 'š' => 'Š',
110
+ 'ţ' => 'Ţ',
111
+ 'ť' => 'Ť',
112
+ 'ŧ' => 'Ŧ',
113
+ 'ũ' => 'Ũ',
114
+ 'ū' => 'Ū',
115
+ 'ŭ' => 'Ŭ',
116
+ 'ů' => 'Ů',
117
+ 'ű' => 'Ű',
118
+ 'ų' => 'Ų',
119
+ 'ŵ' => 'Ŵ',
120
+ 'ŷ' => 'Ŷ',
121
+ 'ź' => 'Ź',
122
+ 'ż' => 'Ż',
123
+ 'ž' => 'Ž',
124
+ 'ſ' => 'S',
125
+ 'ƀ' => 'Ƀ',
126
+ 'ƃ' => 'Ƃ',
127
+ 'ƅ' => 'Ƅ',
128
+ 'ƈ' => 'Ƈ',
129
+ 'ƌ' => 'Ƌ',
130
+ 'ƒ' => 'Ƒ',
131
+ 'ƕ' => 'Ƕ',
132
+ 'ƙ' => 'Ƙ',
133
+ 'ƚ' => 'Ƚ',
134
+ 'ƞ' => 'Ƞ',
135
+ 'ơ' => 'Ơ',
136
+ 'ƣ' => 'Ƣ',
137
+ 'ƥ' => 'Ƥ',
138
+ 'ƨ' => 'Ƨ',
139
+ 'ƭ' => 'Ƭ',
140
+ 'ư' => 'Ư',
141
+ 'ƴ' => 'Ƴ',
142
+ 'ƶ' => 'Ƶ',
143
+ 'ƹ' => 'Ƹ',
144
+ 'ƽ' => 'Ƽ',
145
+ 'ƿ' => 'Ƿ',
146
+ 'Dž' => 'DŽ',
147
+ 'dž' => 'DŽ',
148
+ 'Lj' => 'LJ',
149
+ 'lj' => 'LJ',
150
+ 'Nj' => 'NJ',
151
+ 'nj' => 'NJ',
152
+ 'ǎ' => 'Ǎ',
153
+ 'ǐ' => 'Ǐ',
154
+ 'ǒ' => 'Ǒ',
155
+ 'ǔ' => 'Ǔ',
156
+ 'ǖ' => 'Ǖ',
157
+ 'ǘ' => 'Ǘ',
158
+ 'ǚ' => 'Ǚ',
159
+ 'ǜ' => 'Ǜ',
160
+ 'ǝ' => 'Ǝ',
161
+ 'ǟ' => 'Ǟ',
162
+ 'ǡ' => 'Ǡ',
163
+ 'ǣ' => 'Ǣ',
164
+ 'ǥ' => 'Ǥ',
165
+ 'ǧ' => 'Ǧ',
166
+ 'ǩ' => 'Ǩ',
167
+ 'ǫ' => 'Ǫ',
168
+ 'ǭ' => 'Ǭ',
169
+ 'ǯ' => 'Ǯ',
170
+ 'Dz' => 'DZ',
171
+ 'dz' => 'DZ',
172
+ 'ǵ' => 'Ǵ',
173
+ 'ǹ' => 'Ǹ',
174
+ 'ǻ' => 'Ǻ',
175
+ 'ǽ' => 'Ǽ',
176
+ 'ǿ' => 'Ǿ',
177
+ 'ȁ' => 'Ȁ',
178
+ 'ȃ' => 'Ȃ',
179
+ 'ȅ' => 'Ȅ',
180
+ 'ȇ' => 'Ȇ',
181
+ 'ȉ' => 'Ȉ',
182
+ 'ȋ' => 'Ȋ',
183
+ 'ȍ' => 'Ȍ',
184
+ 'ȏ' => 'Ȏ',
185
+ 'ȑ' => 'Ȑ',
186
+ 'ȓ' => 'Ȓ',
187
+ 'ȕ' => 'Ȕ',
188
+ 'ȗ' => 'Ȗ',
189
+ 'ș' => 'Ș',
190
+ 'ț' => 'Ț',
191
+ 'ȝ' => 'Ȝ',
192
+ 'ȟ' => 'Ȟ',
193
+ 'ȣ' => 'Ȣ',
194
+ 'ȥ' => 'Ȥ',
195
+ 'ȧ' => 'Ȧ',
196
+ 'ȩ' => 'Ȩ',
197
+ 'ȫ' => 'Ȫ',
198
+ 'ȭ' => 'Ȭ',
199
+ 'ȯ' => 'Ȯ',
200
+ 'ȱ' => 'Ȱ',
201
+ 'ȳ' => 'Ȳ',
202
+ 'ȼ' => 'Ȼ',
203
+ 'ȿ' => 'Ȿ',
204
+ 'ɀ' => 'Ɀ',
205
+ 'ɂ' => 'Ɂ',
206
+ 'ɇ' => 'Ɇ',
207
+ 'ɉ' => 'Ɉ',
208
+ 'ɋ' => 'Ɋ',
209
+ 'ɍ' => 'Ɍ',
210
+ 'ɏ' => 'Ɏ',
211
+ 'ɐ' => 'Ɐ',
212
+ 'ɑ' => 'Ɑ',
213
+ 'ɒ' => 'Ɒ',
214
+ 'ɓ' => 'Ɓ',
215
+ 'ɔ' => 'Ɔ',
216
+ 'ɖ' => 'Ɖ',
217
+ 'ɗ' => 'Ɗ',
218
+ 'ə' => 'Ə',
219
+ 'ɛ' => 'Ɛ',
220
+ 'ɜ' => 'Ɜ',
221
+ 'ɠ' => 'Ɠ',
222
+ 'ɡ' => 'Ɡ',
223
+ 'ɣ' => 'Ɣ',
224
+ 'ɥ' => 'Ɥ',
225
+ 'ɦ' => 'Ɦ',
226
+ 'ɨ' => 'Ɨ',
227
+ 'ɩ' => 'Ɩ',
228
+ 'ɪ' => 'Ɪ',
229
+ 'ɫ' => 'Ɫ',
230
+ 'ɬ' => 'Ɬ',
231
+ 'ɯ' => 'Ɯ',
232
+ 'ɱ' => 'Ɱ',
233
+ 'ɲ' => 'Ɲ',
234
+ 'ɵ' => 'Ɵ',
235
+ 'ɽ' => 'Ɽ',
236
+ 'ʀ' => 'Ʀ',
237
+ 'ʂ' => 'Ʂ',
238
+ 'ʃ' => 'Ʃ',
239
+ 'ʇ' => 'Ʇ',
240
+ 'ʈ' => 'Ʈ',
241
+ 'ʉ' => 'Ʉ',
242
+ 'ʊ' => 'Ʊ',
243
+ 'ʋ' => 'Ʋ',
244
+ 'ʌ' => 'Ʌ',
245
+ 'ʒ' => 'Ʒ',
246
+ 'ʝ' => 'Ʝ',
247
+ 'ʞ' => 'Ʞ',
248
+ 'ͅ' => 'Ι',
249
+ 'ͱ' => 'Ͱ',
250
+ 'ͳ' => 'Ͳ',
251
+ 'ͷ' => 'Ͷ',
252
+ 'ͻ' => 'Ͻ',
253
+ 'ͼ' => 'Ͼ',
254
+ 'ͽ' => 'Ͽ',
255
+ 'ά' => 'Ά',
256
+ 'έ' => 'Έ',
257
+ 'ή' => 'Ή',
258
+ 'ί' => 'Ί',
259
+ 'α' => 'Α',
260
+ 'β' => 'Β',
261
+ 'γ' => 'Γ',
262
+ 'δ' => 'Δ',
263
+ 'ε' => 'Ε',
264
+ 'ζ' => 'Ζ',
265
+ 'η' => 'Η',
266
+ 'θ' => 'Θ',
267
+ 'ι' => 'Ι',
268
+ 'κ' => 'Κ',
269
+ 'λ' => 'Λ',
270
+ 'μ' => 'Μ',
271
+ 'ν' => 'Ν',
272
+ 'ξ' => 'Ξ',
273
+ 'ο' => 'Ο',
274
+ 'π' => 'Π',
275
+ 'ρ' => 'Ρ',
276
+ 'ς' => 'Σ',
277
+ 'σ' => 'Σ',
278
+ 'τ' => 'Τ',
279
+ 'υ' => 'Υ',
280
+ 'φ' => 'Φ',
281
+ 'χ' => 'Χ',
282
+ 'ψ' => 'Ψ',
283
+ 'ω' => 'Ω',
284
+ 'ϊ' => 'Ϊ',
285
+ 'ϋ' => 'Ϋ',
286
+ 'ό' => 'Ό',
287
+ 'ύ' => 'Ύ',
288
+ 'ώ' => 'Ώ',
289
+ 'ϐ' => 'Β',
290
+ 'ϑ' => 'Θ',
291
+ 'ϕ' => 'Φ',
292
+ 'ϖ' => 'Π',
293
+ 'ϗ' => 'Ϗ',
294
+ 'ϙ' => 'Ϙ',
295
+ 'ϛ' => 'Ϛ',
296
+ 'ϝ' => 'Ϝ',
297
+ 'ϟ' => 'Ϟ',
298
+ 'ϡ' => 'Ϡ',
299
+ 'ϣ' => 'Ϣ',
300
+ 'ϥ' => 'Ϥ',
301
+ 'ϧ' => 'Ϧ',
302
+ 'ϩ' => 'Ϩ',
303
+ 'ϫ' => 'Ϫ',
304
+ 'ϭ' => 'Ϭ',
305
+ 'ϯ' => 'Ϯ',
306
+ 'ϰ' => 'Κ',
307
+ 'ϱ' => 'Ρ',
308
+ 'ϲ' => 'Ϲ',
309
+ 'ϳ' => 'Ϳ',
310
+ 'ϵ' => 'Ε',
311
+ 'ϸ' => 'Ϸ',
312
+ 'ϻ' => 'Ϻ',
313
+ 'а' => 'А',
314
+ 'б' => 'Б',
315
+ 'в' => 'В',
316
+ 'г' => 'Г',
317
+ 'д' => 'Д',
318
+ 'е' => 'Е',
319
+ 'ж' => 'Ж',
320
+ 'з' => 'З',
321
+ 'и' => 'И',
322
+ 'й' => 'Й',
323
+ 'к' => 'К',
324
+ 'л' => 'Л',
325
+ 'м' => 'М',
326
+ 'н' => 'Н',
327
+ 'о' => 'О',
328
+ 'п' => 'П',
329
+ 'р' => 'Р',
330
+ 'с' => 'С',
331
+ 'т' => 'Т',
332
+ 'у' => 'У',
333
+ 'ф' => 'Ф',
334
+ 'х' => 'Х',
335
+ 'ц' => 'Ц',
336
+ 'ч' => 'Ч',
337
+ 'ш' => 'Ш',
338
+ 'щ' => 'Щ',
339
+ 'ъ' => 'Ъ',
340
+ 'ы' => 'Ы',
341
+ 'ь' => 'Ь',
342
+ 'э' => 'Э',
343
+ 'ю' => 'Ю',
344
+ 'я' => 'Я',
345
+ 'ѐ' => 'Ѐ',
346
+ 'ё' => 'Ё',
347
+ 'ђ' => 'Ђ',
348
+ 'ѓ' => 'Ѓ',
349
+ 'є' => 'Є',
350
+ 'ѕ' => 'Ѕ',
351
+ 'і' => 'І',
352
+ 'ї' => 'Ї',
353
+ 'ј' => 'Ј',
354
+ 'љ' => 'Љ',
355
+ 'њ' => 'Њ',
356
+ 'ћ' => 'Ћ',
357
+ 'ќ' => 'Ќ',
358
+ 'ѝ' => 'Ѝ',
359
+ 'ў' => 'Ў',
360
+ 'џ' => 'Џ',
361
+ 'ѡ' => 'Ѡ',
362
+ 'ѣ' => 'Ѣ',
363
+ 'ѥ' => 'Ѥ',
364
+ 'ѧ' => 'Ѧ',
365
+ 'ѩ' => 'Ѩ',
366
+ 'ѫ' => 'Ѫ',
367
+ 'ѭ' => 'Ѭ',
368
+ 'ѯ' => 'Ѯ',
369
+ 'ѱ' => 'Ѱ',
370
+ 'ѳ' => 'Ѳ',
371
+ 'ѵ' => 'Ѵ',
372
+ 'ѷ' => 'Ѷ',
373
+ 'ѹ' => 'Ѹ',
374
+ 'ѻ' => 'Ѻ',
375
+ 'ѽ' => 'Ѽ',
376
+ 'ѿ' => 'Ѿ',
377
+ 'ҁ' => 'Ҁ',
378
+ 'ҋ' => 'Ҋ',
379
+ 'ҍ' => 'Ҍ',
380
+ 'ҏ' => 'Ҏ',
381
+ 'ґ' => 'Ґ',
382
+ 'ғ' => 'Ғ',
383
+ 'ҕ' => 'Ҕ',
384
+ 'җ' => 'Җ',
385
+ 'ҙ' => 'Ҙ',
386
+ 'қ' => 'Қ',
387
+ 'ҝ' => 'Ҝ',
388
+ 'ҟ' => 'Ҟ',
389
+ 'ҡ' => 'Ҡ',
390
+ 'ң' => 'Ң',
391
+ 'ҥ' => 'Ҥ',
392
+ 'ҧ' => 'Ҧ',
393
+ 'ҩ' => 'Ҩ',
394
+ 'ҫ' => 'Ҫ',
395
+ 'ҭ' => 'Ҭ',
396
+ 'ү' => 'Ү',
397
+ 'ұ' => 'Ұ',
398
+ 'ҳ' => 'Ҳ',
399
+ 'ҵ' => 'Ҵ',
400
+ 'ҷ' => 'Ҷ',
401
+ 'ҹ' => 'Ҹ',
402
+ 'һ' => 'Һ',
403
+ 'ҽ' => 'Ҽ',
404
+ 'ҿ' => 'Ҿ',
405
+ 'ӂ' => 'Ӂ',
406
+ 'ӄ' => 'Ӄ',
407
+ 'ӆ' => 'Ӆ',
408
+ 'ӈ' => 'Ӈ',
409
+ 'ӊ' => 'Ӊ',
410
+ 'ӌ' => 'Ӌ',
411
+ 'ӎ' => 'Ӎ',
412
+ 'ӏ' => 'Ӏ',
413
+ 'ӑ' => 'Ӑ',
414
+ 'ӓ' => 'Ӓ',
415
+ 'ӕ' => 'Ӕ',
416
+ 'ӗ' => 'Ӗ',
417
+ 'ә' => 'Ә',
418
+ 'ӛ' => 'Ӛ',
419
+ 'ӝ' => 'Ӝ',
420
+ 'ӟ' => 'Ӟ',
421
+ 'ӡ' => 'Ӡ',
422
+ 'ӣ' => 'Ӣ',
423
+ 'ӥ' => 'Ӥ',
424
+ 'ӧ' => 'Ӧ',
425
+ 'ө' => 'Ө',
426
+ 'ӫ' => 'Ӫ',
427
+ 'ӭ' => 'Ӭ',
428
+ 'ӯ' => 'Ӯ',
429
+ 'ӱ' => 'Ӱ',
430
+ 'ӳ' => 'Ӳ',
431
+ 'ӵ' => 'Ӵ',
432
+ 'ӷ' => 'Ӷ',
433
+ 'ӹ' => 'Ӹ',
434
+ 'ӻ' => 'Ӻ',
435
+ 'ӽ' => 'Ӽ',
436
+ 'ӿ' => 'Ӿ',
437
+ 'ԁ' => 'Ԁ',
438
+ 'ԃ' => 'Ԃ',
439
+ 'ԅ' => 'Ԅ',
440
+ 'ԇ' => 'Ԇ',
441
+ 'ԉ' => 'Ԉ',
442
+ 'ԋ' => 'Ԋ',
443
+ 'ԍ' => 'Ԍ',
444
+ 'ԏ' => 'Ԏ',
445
+ 'ԑ' => 'Ԑ',
446
+ 'ԓ' => 'Ԓ',
447
+ 'ԕ' => 'Ԕ',
448
+ 'ԗ' => 'Ԗ',
449
+ 'ԙ' => 'Ԙ',
450
+ 'ԛ' => 'Ԛ',
451
+ 'ԝ' => 'Ԝ',
452
+ 'ԟ' => 'Ԟ',
453
+ 'ԡ' => 'Ԡ',
454
+ 'ԣ' => 'Ԣ',
455
+ 'ԥ' => 'Ԥ',
456
+ 'ԧ' => 'Ԧ',
457
+ 'ԩ' => 'Ԩ',
458
+ 'ԫ' => 'Ԫ',
459
+ 'ԭ' => 'Ԭ',
460
+ 'ԯ' => 'Ԯ',
461
+ 'ա' => 'Ա',
462
+ 'բ' => 'Բ',
463
+ 'գ' => 'Գ',
464
+ 'դ' => 'Դ',
465
+ 'ե' => 'Ե',
466
+ 'զ' => 'Զ',
467
+ 'է' => 'Է',
468
+ 'ը' => 'Ը',
469
+ 'թ' => 'Թ',
470
+ 'ժ' => 'Ժ',
471
+ 'ի' => 'Ի',
472
+ 'լ' => 'Լ',
473
+ 'խ' => 'Խ',
474
+ 'ծ' => 'Ծ',
475
+ 'կ' => 'Կ',
476
+ 'հ' => 'Հ',
477
+ 'ձ' => 'Ձ',
478
+ 'ղ' => 'Ղ',
479
+ 'ճ' => 'Ճ',
480
+ 'մ' => 'Մ',
481
+ 'յ' => 'Յ',
482
+ 'ն' => 'Ն',
483
+ 'շ' => 'Շ',
484
+ 'ո' => 'Ո',
485
+ 'չ' => 'Չ',
486
+ 'պ' => 'Պ',
487
+ 'ջ' => 'Ջ',
488
+ 'ռ' => 'Ռ',
489
+ 'ս' => 'Ս',
490
+ 'վ' => 'Վ',
491
+ 'տ' => 'Տ',
492
+ 'ր' => 'Ր',
493
+ 'ց' => 'Ց',
494
+ 'ւ' => 'Ւ',
495
+ 'փ' => 'Փ',
496
+ 'ք' => 'Ք',
497
+ 'օ' => 'Օ',
498
+ 'ֆ' => 'Ֆ',
499
+ 'ა' => 'Ა',
500
+ 'ბ' => 'Ბ',
501
+ 'გ' => 'Გ',
502
+ 'დ' => 'Დ',
503
+ 'ე' => 'Ე',
504
+ 'ვ' => 'Ვ',
505
+ 'ზ' => 'Ზ',
506
+ 'თ' => 'Თ',
507
+ 'ი' => 'Ი',
508
+ 'კ' => 'Კ',
509
+ 'ლ' => 'Ლ',
510
+ 'მ' => 'Მ',
511
+ 'ნ' => 'Ნ',
512
+ 'ო' => 'Ო',
513
+ 'პ' => 'Პ',
514
+ 'ჟ' => 'Ჟ',
515
+ 'რ' => 'Რ',
516
+ 'ს' => 'Ს',
517
+ 'ტ' => 'Ტ',
518
+ 'უ' => 'Უ',
519
+ 'ფ' => 'Ფ',
520
+ 'ქ' => 'Ქ',
521
+ 'ღ' => 'Ღ',
522
+ 'ყ' => 'Ყ',
523
+ 'შ' => 'Შ',
524
+ 'ჩ' => 'Ჩ',
525
+ 'ც' => 'Ც',
526
+ 'ძ' => 'Ძ',
527
+ 'წ' => 'Წ',
528
+ 'ჭ' => 'Ჭ',
529
+ 'ხ' => 'Ხ',
530
+ 'ჯ' => 'Ჯ',
531
+ 'ჰ' => 'Ჰ',
532
+ 'ჱ' => 'Ჱ',
533
+ 'ჲ' => 'Ჲ',
534
+ 'ჳ' => 'Ჳ',
535
+ 'ჴ' => 'Ჴ',
536
+ 'ჵ' => 'Ჵ',
537
+ 'ჶ' => 'Ჶ',
538
+ 'ჷ' => 'Ჷ',
539
+ 'ჸ' => 'Ჸ',
540
+ 'ჹ' => 'Ჹ',
541
+ 'ჺ' => 'Ჺ',
542
+ 'ჽ' => 'Ჽ',
543
+ 'ჾ' => 'Ჾ',
544
+ 'ჿ' => 'Ჿ',
545
+ 'ᏸ' => 'Ᏸ',
546
+ 'ᏹ' => 'Ᏹ',
547
+ 'ᏺ' => 'Ᏺ',
548
+ 'ᏻ' => 'Ᏻ',
549
+ 'ᏼ' => 'Ᏼ',
550
+ 'ᏽ' => 'Ᏽ',
551
+ 'ᲀ' => 'В',
552
+ 'ᲁ' => 'Д',
553
+ 'ᲂ' => 'О',
554
+ 'ᲃ' => 'С',
555
+ 'ᲄ' => 'Т',
556
+ 'ᲅ' => 'Т',
557
+ 'ᲆ' => 'Ъ',
558
+ 'ᲇ' => 'Ѣ',
559
+ 'ᲈ' => 'Ꙋ',
560
+ 'ᵹ' => 'Ᵹ',
561
+ 'ᵽ' => 'Ᵽ',
562
+ 'ᶎ' => 'Ᶎ',
563
+ 'ḁ' => 'Ḁ',
564
+ 'ḃ' => 'Ḃ',
565
+ 'ḅ' => 'Ḅ',
566
+ 'ḇ' => 'Ḇ',
567
+ 'ḉ' => 'Ḉ',
568
+ 'ḋ' => 'Ḋ',
569
+ 'ḍ' => 'Ḍ',
570
+ 'ḏ' => 'Ḏ',
571
+ 'ḑ' => 'Ḑ',
572
+ 'ḓ' => 'Ḓ',
573
+ 'ḕ' => 'Ḕ',
574
+ 'ḗ' => 'Ḗ',
575
+ 'ḙ' => 'Ḙ',
576
+ 'ḛ' => 'Ḛ',
577
+ 'ḝ' => 'Ḝ',
578
+ 'ḟ' => 'Ḟ',
579
+ 'ḡ' => 'Ḡ',
580
+ 'ḣ' => 'Ḣ',
581
+ 'ḥ' => 'Ḥ',
582
+ 'ḧ' => 'Ḧ',
583
+ 'ḩ' => 'Ḩ',
584
+ 'ḫ' => 'Ḫ',
585
+ 'ḭ' => 'Ḭ',
586
+ 'ḯ' => 'Ḯ',
587
+ 'ḱ' => 'Ḱ',
588
+ 'ḳ' => 'Ḳ',
589
+ 'ḵ' => 'Ḵ',
590
+ 'ḷ' => 'Ḷ',
591
+ 'ḹ' => 'Ḹ',
592
+ 'ḻ' => 'Ḻ',
593
+ 'ḽ' => 'Ḽ',
594
+ 'ḿ' => 'Ḿ',
595
+ 'ṁ' => 'Ṁ',
596
+ 'ṃ' => 'Ṃ',
597
+ 'ṅ' => 'Ṅ',
598
+ 'ṇ' => 'Ṇ',
599
+ 'ṉ' => 'Ṉ',
600
+ 'ṋ' => 'Ṋ',
601
+ 'ṍ' => 'Ṍ',
602
+ 'ṏ' => 'Ṏ',
603
+ 'ṑ' => 'Ṑ',
604
+ 'ṓ' => 'Ṓ',
605
+ 'ṕ' => 'Ṕ',
606
+ 'ṗ' => 'Ṗ',
607
+ 'ṙ' => 'Ṙ',
608
+ 'ṛ' => 'Ṛ',
609
+ 'ṝ' => 'Ṝ',
610
+ 'ṟ' => 'Ṟ',
611
+ 'ṡ' => 'Ṡ',
612
+ 'ṣ' => 'Ṣ',
613
+ 'ṥ' => 'Ṥ',
614
+ 'ṧ' => 'Ṧ',
615
+ 'ṩ' => 'Ṩ',
616
+ 'ṫ' => 'Ṫ',
617
+ 'ṭ' => 'Ṭ',
618
+ 'ṯ' => 'Ṯ',
619
+ 'ṱ' => 'Ṱ',
620
+ 'ṳ' => 'Ṳ',
621
+ 'ṵ' => 'Ṵ',
622
+ 'ṷ' => 'Ṷ',
623
+ 'ṹ' => 'Ṹ',
624
+ 'ṻ' => 'Ṻ',
625
+ 'ṽ' => 'Ṽ',
626
+ 'ṿ' => 'Ṿ',
627
+ 'ẁ' => 'Ẁ',
628
+ 'ẃ' => 'Ẃ',
629
+ 'ẅ' => 'Ẅ',
630
+ 'ẇ' => 'Ẇ',
631
+ 'ẉ' => 'Ẉ',
632
+ 'ẋ' => 'Ẋ',
633
+ 'ẍ' => 'Ẍ',
634
+ 'ẏ' => 'Ẏ',
635
+ 'ẑ' => 'Ẑ',
636
+ 'ẓ' => 'Ẓ',
637
+ 'ẕ' => 'Ẕ',
638
+ 'ẛ' => 'Ṡ',
639
+ 'ạ' => 'Ạ',
640
+ 'ả' => 'Ả',
641
+ 'ấ' => 'Ấ',
642
+ 'ầ' => 'Ầ',
643
+ 'ẩ' => 'Ẩ',
644
+ 'ẫ' => 'Ẫ',
645
+ 'ậ' => 'Ậ',
646
+ 'ắ' => 'Ắ',
647
+ 'ằ' => 'Ằ',
648
+ 'ẳ' => 'Ẳ',
649
+ 'ẵ' => 'Ẵ',
650
+ 'ặ' => 'Ặ',
651
+ 'ẹ' => 'Ẹ',
652
+ 'ẻ' => 'Ẻ',
653
+ 'ẽ' => 'Ẽ',
654
+ 'ế' => 'Ế',
655
+ 'ề' => 'Ề',
656
+ 'ể' => 'Ể',
657
+ 'ễ' => 'Ễ',
658
+ 'ệ' => 'Ệ',
659
+ 'ỉ' => 'Ỉ',
660
+ 'ị' => 'Ị',
661
+ 'ọ' => 'Ọ',
662
+ 'ỏ' => 'Ỏ',
663
+ 'ố' => 'Ố',
664
+ 'ồ' => 'Ồ',
665
+ 'ổ' => 'Ổ',
666
+ 'ỗ' => 'Ỗ',
667
+ 'ộ' => 'Ộ',
668
+ 'ớ' => 'Ớ',
669
+ 'ờ' => 'Ờ',
670
+ 'ở' => 'Ở',
671
+ 'ỡ' => 'Ỡ',
672
+ 'ợ' => 'Ợ',
673
+ 'ụ' => 'Ụ',
674
+ 'ủ' => 'Ủ',
675
+ 'ứ' => 'Ứ',
676
+ 'ừ' => 'Ừ',
677
+ 'ử' => 'Ử',
678
+ 'ữ' => 'Ữ',
679
+ 'ự' => 'Ự',
680
+ 'ỳ' => 'Ỳ',
681
+ 'ỵ' => 'Ỵ',
682
+ 'ỷ' => 'Ỷ',
683
+ 'ỹ' => 'Ỹ',
684
+ 'ỻ' => 'Ỻ',
685
+ 'ỽ' => 'Ỽ',
686
+ 'ỿ' => 'Ỿ',
687
+ 'ἀ' => 'Ἀ',
688
+ 'ἁ' => 'Ἁ',
689
+ 'ἂ' => 'Ἂ',
690
+ 'ἃ' => 'Ἃ',
691
+ 'ἄ' => 'Ἄ',
692
+ 'ἅ' => 'Ἅ',
693
+ 'ἆ' => 'Ἆ',
694
+ 'ἇ' => 'Ἇ',
695
+ 'ἐ' => 'Ἐ',
696
+ 'ἑ' => 'Ἑ',
697
+ 'ἒ' => 'Ἒ',
698
+ 'ἓ' => 'Ἓ',
699
+ 'ἔ' => 'Ἔ',
700
+ 'ἕ' => 'Ἕ',
701
+ 'ἠ' => 'Ἠ',
702
+ 'ἡ' => 'Ἡ',
703
+ 'ἢ' => 'Ἢ',
704
+ 'ἣ' => 'Ἣ',
705
+ 'ἤ' => 'Ἤ',
706
+ 'ἥ' => 'Ἥ',
707
+ 'ἦ' => 'Ἦ',
708
+ 'ἧ' => 'Ἧ',
709
+ 'ἰ' => 'Ἰ',
710
+ 'ἱ' => 'Ἱ',
711
+ 'ἲ' => 'Ἲ',
712
+ 'ἳ' => 'Ἳ',
713
+ 'ἴ' => 'Ἴ',
714
+ 'ἵ' => 'Ἵ',
715
+ 'ἶ' => 'Ἶ',
716
+ 'ἷ' => 'Ἷ',
717
+ 'ὀ' => 'Ὀ',
718
+ 'ὁ' => 'Ὁ',
719
+ 'ὂ' => 'Ὂ',
720
+ 'ὃ' => 'Ὃ',
721
+ 'ὄ' => 'Ὄ',
722
+ 'ὅ' => 'Ὅ',
723
+ 'ὑ' => 'Ὑ',
724
+ 'ὓ' => 'Ὓ',
725
+ 'ὕ' => 'Ὕ',
726
+ 'ὗ' => 'Ὗ',
727
+ 'ὠ' => 'Ὠ',
728
+ 'ὡ' => 'Ὡ',
729
+ 'ὢ' => 'Ὢ',
730
+ 'ὣ' => 'Ὣ',
731
+ 'ὤ' => 'Ὤ',
732
+ 'ὥ' => 'Ὥ',
733
+ 'ὦ' => 'Ὦ',
734
+ 'ὧ' => 'Ὧ',
735
+ 'ὰ' => 'Ὰ',
736
+ 'ά' => 'Ά',
737
+ 'ὲ' => 'Ὲ',
738
+ 'έ' => 'Έ',
739
+ 'ὴ' => 'Ὴ',
740
+ 'ή' => 'Ή',
741
+ 'ὶ' => 'Ὶ',
742
+ 'ί' => 'Ί',
743
+ 'ὸ' => 'Ὸ',
744
+ 'ό' => 'Ό',
745
+ 'ὺ' => 'Ὺ',
746
+ 'ύ' => 'Ύ',
747
+ 'ὼ' => 'Ὼ',
748
+ 'ώ' => 'Ώ',
749
+ 'ᾀ' => 'ἈΙ',
750
+ 'ᾁ' => 'ἉΙ',
751
+ 'ᾂ' => 'ἊΙ',
752
+ 'ᾃ' => 'ἋΙ',
753
+ 'ᾄ' => 'ἌΙ',
754
+ 'ᾅ' => 'ἍΙ',
755
+ 'ᾆ' => 'ἎΙ',
756
+ 'ᾇ' => 'ἏΙ',
757
+ 'ᾐ' => 'ἨΙ',
758
+ 'ᾑ' => 'ἩΙ',
759
+ 'ᾒ' => 'ἪΙ',
760
+ 'ᾓ' => 'ἫΙ',
761
+ 'ᾔ' => 'ἬΙ',
762
+ 'ᾕ' => 'ἭΙ',
763
+ 'ᾖ' => 'ἮΙ',
764
+ 'ᾗ' => 'ἯΙ',
765
+ 'ᾠ' => 'ὨΙ',
766
+ 'ᾡ' => 'ὩΙ',
767
+ 'ᾢ' => 'ὪΙ',
768
+ 'ᾣ' => 'ὫΙ',
769
+ 'ᾤ' => 'ὬΙ',
770
+ 'ᾥ' => 'ὭΙ',
771
+ 'ᾦ' => 'ὮΙ',
772
+ 'ᾧ' => 'ὯΙ',
773
+ 'ᾰ' => 'Ᾰ',
774
+ 'ᾱ' => 'Ᾱ',
775
+ 'ᾳ' => 'ΑΙ',
776
+ 'ι' => 'Ι',
777
+ 'ῃ' => 'ΗΙ',
778
+ 'ῐ' => 'Ῐ',
779
+ 'ῑ' => 'Ῑ',
780
+ 'ῠ' => 'Ῠ',
781
+ 'ῡ' => 'Ῡ',
782
+ 'ῥ' => 'Ῥ',
783
+ 'ῳ' => 'ΩΙ',
784
+ 'ⅎ' => 'Ⅎ',
785
+ 'ⅰ' => 'Ⅰ',
786
+ 'ⅱ' => 'Ⅱ',
787
+ 'ⅲ' => 'Ⅲ',
788
+ 'ⅳ' => 'Ⅳ',
789
+ 'ⅴ' => 'Ⅴ',
790
+ 'ⅵ' => 'Ⅵ',
791
+ 'ⅶ' => 'Ⅶ',
792
+ 'ⅷ' => 'Ⅷ',
793
+ 'ⅸ' => 'Ⅸ',
794
+ 'ⅹ' => 'Ⅹ',
795
+ 'ⅺ' => 'Ⅺ',
796
+ 'ⅻ' => 'Ⅻ',
797
+ 'ⅼ' => 'Ⅼ',
798
+ 'ⅽ' => 'Ⅽ',
799
+ 'ⅾ' => 'Ⅾ',
800
+ 'ⅿ' => 'Ⅿ',
801
+ 'ↄ' => 'Ↄ',
802
+ 'ⓐ' => 'Ⓐ',
803
+ 'ⓑ' => 'Ⓑ',
804
+ 'ⓒ' => 'Ⓒ',
805
+ 'ⓓ' => 'Ⓓ',
806
+ 'ⓔ' => 'Ⓔ',
807
+ 'ⓕ' => 'Ⓕ',
808
+ 'ⓖ' => 'Ⓖ',
809
+ 'ⓗ' => 'Ⓗ',
810
+ 'ⓘ' => 'Ⓘ',
811
+ 'ⓙ' => 'Ⓙ',
812
+ 'ⓚ' => 'Ⓚ',
813
+ 'ⓛ' => 'Ⓛ',
814
+ 'ⓜ' => 'Ⓜ',
815
+ 'ⓝ' => 'Ⓝ',
816
+ 'ⓞ' => 'Ⓞ',
817
+ 'ⓟ' => 'Ⓟ',
818
+ 'ⓠ' => 'Ⓠ',
819
+ 'ⓡ' => 'Ⓡ',
820
+ 'ⓢ' => 'Ⓢ',
821
+ 'ⓣ' => 'Ⓣ',
822
+ 'ⓤ' => 'Ⓤ',
823
+ 'ⓥ' => 'Ⓥ',
824
+ 'ⓦ' => 'Ⓦ',
825
+ 'ⓧ' => 'Ⓧ',
826
+ 'ⓨ' => 'Ⓨ',
827
+ 'ⓩ' => 'Ⓩ',
828
+ 'ⰰ' => 'Ⰰ',
829
+ 'ⰱ' => 'Ⰱ',
830
+ 'ⰲ' => 'Ⰲ',
831
+ 'ⰳ' => 'Ⰳ',
832
+ 'ⰴ' => 'Ⰴ',
833
+ 'ⰵ' => 'Ⰵ',
834
+ 'ⰶ' => 'Ⰶ',
835
+ 'ⰷ' => 'Ⰷ',
836
+ 'ⰸ' => 'Ⰸ',
837
+ 'ⰹ' => 'Ⰹ',
838
+ 'ⰺ' => 'Ⰺ',
839
+ 'ⰻ' => 'Ⰻ',
840
+ 'ⰼ' => 'Ⰼ',
841
+ 'ⰽ' => 'Ⰽ',
842
+ 'ⰾ' => 'Ⰾ',
843
+ 'ⰿ' => 'Ⰿ',
844
+ 'ⱀ' => 'Ⱀ',
845
+ 'ⱁ' => 'Ⱁ',
846
+ 'ⱂ' => 'Ⱂ',
847
+ 'ⱃ' => 'Ⱃ',
848
+ 'ⱄ' => 'Ⱄ',
849
+ 'ⱅ' => 'Ⱅ',
850
+ 'ⱆ' => 'Ⱆ',
851
+ 'ⱇ' => 'Ⱇ',
852
+ 'ⱈ' => 'Ⱈ',
853
+ 'ⱉ' => 'Ⱉ',
854
+ 'ⱊ' => 'Ⱊ',
855
+ 'ⱋ' => 'Ⱋ',
856
+ 'ⱌ' => 'Ⱌ',
857
+ 'ⱍ' => 'Ⱍ',
858
+ 'ⱎ' => 'Ⱎ',
859
+ 'ⱏ' => 'Ⱏ',
860
+ 'ⱐ' => 'Ⱐ',
861
+ 'ⱑ' => 'Ⱑ',
862
+ 'ⱒ' => 'Ⱒ',
863
+ 'ⱓ' => 'Ⱓ',
864
+ 'ⱔ' => 'Ⱔ',
865
+ 'ⱕ' => 'Ⱕ',
866
+ 'ⱖ' => 'Ⱖ',
867
+ 'ⱗ' => 'Ⱗ',
868
+ 'ⱘ' => 'Ⱘ',
869
+ 'ⱙ' => 'Ⱙ',
870
+ 'ⱚ' => 'Ⱚ',
871
+ 'ⱛ' => 'Ⱛ',
872
+ 'ⱜ' => 'Ⱜ',
873
+ 'ⱝ' => 'Ⱝ',
874
+ 'ⱞ' => 'Ⱞ',
875
+ 'ⱡ' => 'Ⱡ',
876
+ 'ⱥ' => 'Ⱥ',
877
+ 'ⱦ' => 'Ⱦ',
878
+ 'ⱨ' => 'Ⱨ',
879
+ 'ⱪ' => 'Ⱪ',
880
+ 'ⱬ' => 'Ⱬ',
881
+ 'ⱳ' => 'Ⱳ',
882
+ 'ⱶ' => 'Ⱶ',
883
+ 'ⲁ' => 'Ⲁ',
884
+ 'ⲃ' => 'Ⲃ',
885
+ 'ⲅ' => 'Ⲅ',
886
+ 'ⲇ' => 'Ⲇ',
887
+ 'ⲉ' => 'Ⲉ',
888
+ 'ⲋ' => 'Ⲋ',
889
+ 'ⲍ' => 'Ⲍ',
890
+ 'ⲏ' => 'Ⲏ',
891
+ 'ⲑ' => 'Ⲑ',
892
+ 'ⲓ' => 'Ⲓ',
893
+ 'ⲕ' => 'Ⲕ',
894
+ 'ⲗ' => 'Ⲗ',
895
+ 'ⲙ' => 'Ⲙ',
896
+ 'ⲛ' => 'Ⲛ',
897
+ 'ⲝ' => 'Ⲝ',
898
+ 'ⲟ' => 'Ⲟ',
899
+ 'ⲡ' => 'Ⲡ',
900
+ 'ⲣ' => 'Ⲣ',
901
+ 'ⲥ' => 'Ⲥ',
902
+ 'ⲧ' => 'Ⲧ',
903
+ 'ⲩ' => 'Ⲩ',
904
+ 'ⲫ' => 'Ⲫ',
905
+ 'ⲭ' => 'Ⲭ',
906
+ 'ⲯ' => 'Ⲯ',
907
+ 'ⲱ' => 'Ⲱ',
908
+ 'ⲳ' => 'Ⲳ',
909
+ 'ⲵ' => 'Ⲵ',
910
+ 'ⲷ' => 'Ⲷ',
911
+ 'ⲹ' => 'Ⲹ',
912
+ 'ⲻ' => 'Ⲻ',
913
+ 'ⲽ' => 'Ⲽ',
914
+ 'ⲿ' => 'Ⲿ',
915
+ 'ⳁ' => 'Ⳁ',
916
+ 'ⳃ' => 'Ⳃ',
917
+ 'ⳅ' => 'Ⳅ',
918
+ 'ⳇ' => 'Ⳇ',
919
+ 'ⳉ' => 'Ⳉ',
920
+ 'ⳋ' => 'Ⳋ',
921
+ 'ⳍ' => 'Ⳍ',
922
+ 'ⳏ' => 'Ⳏ',
923
+ 'ⳑ' => 'Ⳑ',
924
+ 'ⳓ' => 'Ⳓ',
925
+ 'ⳕ' => 'Ⳕ',
926
+ 'ⳗ' => 'Ⳗ',
927
+ 'ⳙ' => 'Ⳙ',
928
+ 'ⳛ' => 'Ⳛ',
929
+ 'ⳝ' => 'Ⳝ',
930
+ 'ⳟ' => 'Ⳟ',
931
+ 'ⳡ' => 'Ⳡ',
932
+ 'ⳣ' => 'Ⳣ',
933
+ 'ⳬ' => 'Ⳬ',
934
+ 'ⳮ' => 'Ⳮ',
935
+ 'ⳳ' => 'Ⳳ',
936
+ 'ⴀ' => 'Ⴀ',
937
+ 'ⴁ' => 'Ⴁ',
938
+ 'ⴂ' => 'Ⴂ',
939
+ 'ⴃ' => 'Ⴃ',
940
+ 'ⴄ' => 'Ⴄ',
941
+ 'ⴅ' => 'Ⴅ',
942
+ 'ⴆ' => 'Ⴆ',
943
+ 'ⴇ' => 'Ⴇ',
944
+ 'ⴈ' => 'Ⴈ',
945
+ 'ⴉ' => 'Ⴉ',
946
+ 'ⴊ' => 'Ⴊ',
947
+ 'ⴋ' => 'Ⴋ',
948
+ 'ⴌ' => 'Ⴌ',
949
+ 'ⴍ' => 'Ⴍ',
950
+ 'ⴎ' => 'Ⴎ',
951
+ 'ⴏ' => 'Ⴏ',
952
+ 'ⴐ' => 'Ⴐ',
953
+ 'ⴑ' => 'Ⴑ',
954
+ 'ⴒ' => 'Ⴒ',
955
+ 'ⴓ' => 'Ⴓ',
956
+ 'ⴔ' => 'Ⴔ',
957
+ 'ⴕ' => 'Ⴕ',
958
+ 'ⴖ' => 'Ⴖ',
959
+ 'ⴗ' => 'Ⴗ',
960
+ 'ⴘ' => 'Ⴘ',
961
+ 'ⴙ' => 'Ⴙ',
962
+ 'ⴚ' => 'Ⴚ',
963
+ 'ⴛ' => 'Ⴛ',
964
+ 'ⴜ' => 'Ⴜ',
965
+ 'ⴝ' => 'Ⴝ',
966
+ 'ⴞ' => 'Ⴞ',
967
+ 'ⴟ' => 'Ⴟ',
968
+ 'ⴠ' => 'Ⴠ',
969
+ 'ⴡ' => 'Ⴡ',
970
+ 'ⴢ' => 'Ⴢ',
971
+ 'ⴣ' => 'Ⴣ',
972
+ 'ⴤ' => 'Ⴤ',
973
+ 'ⴥ' => 'Ⴥ',
974
+ 'ⴧ' => 'Ⴧ',
975
+ 'ⴭ' => 'Ⴭ',
976
+ 'ꙁ' => 'Ꙁ',
977
+ 'ꙃ' => 'Ꙃ',
978
+ 'ꙅ' => 'Ꙅ',
979
+ 'ꙇ' => 'Ꙇ',
980
+ 'ꙉ' => 'Ꙉ',
981
+ 'ꙋ' => 'Ꙋ',
982
+ 'ꙍ' => 'Ꙍ',
983
+ 'ꙏ' => 'Ꙏ',
984
+ 'ꙑ' => 'Ꙑ',
985
+ 'ꙓ' => 'Ꙓ',
986
+ 'ꙕ' => 'Ꙕ',
987
+ 'ꙗ' => 'Ꙗ',
988
+ 'ꙙ' => 'Ꙙ',
989
+ 'ꙛ' => 'Ꙛ',
990
+ 'ꙝ' => 'Ꙝ',
991
+ 'ꙟ' => 'Ꙟ',
992
+ 'ꙡ' => 'Ꙡ',
993
+ 'ꙣ' => 'Ꙣ',
994
+ 'ꙥ' => 'Ꙥ',
995
+ 'ꙧ' => 'Ꙧ',
996
+ 'ꙩ' => 'Ꙩ',
997
+ 'ꙫ' => 'Ꙫ',
998
+ 'ꙭ' => 'Ꙭ',
999
+ 'ꚁ' => 'Ꚁ',
1000
+ 'ꚃ' => 'Ꚃ',
1001
+ 'ꚅ' => 'Ꚅ',
1002
+ 'ꚇ' => 'Ꚇ',
1003
+ 'ꚉ' => 'Ꚉ',
1004
+ 'ꚋ' => 'Ꚋ',
1005
+ 'ꚍ' => 'Ꚍ',
1006
+ 'ꚏ' => 'Ꚏ',
1007
+ 'ꚑ' => 'Ꚑ',
1008
+ 'ꚓ' => 'Ꚓ',
1009
+ 'ꚕ' => 'Ꚕ',
1010
+ 'ꚗ' => 'Ꚗ',
1011
+ 'ꚙ' => 'Ꚙ',
1012
+ 'ꚛ' => 'Ꚛ',
1013
+ 'ꜣ' => 'Ꜣ',
1014
+ 'ꜥ' => 'Ꜥ',
1015
+ 'ꜧ' => 'Ꜧ',
1016
+ 'ꜩ' => 'Ꜩ',
1017
+ 'ꜫ' => 'Ꜫ',
1018
+ 'ꜭ' => 'Ꜭ',
1019
+ 'ꜯ' => 'Ꜯ',
1020
+ 'ꜳ' => 'Ꜳ',
1021
+ 'ꜵ' => 'Ꜵ',
1022
+ 'ꜷ' => 'Ꜷ',
1023
+ 'ꜹ' => 'Ꜹ',
1024
+ 'ꜻ' => 'Ꜻ',
1025
+ 'ꜽ' => 'Ꜽ',
1026
+ 'ꜿ' => 'Ꜿ',
1027
+ 'ꝁ' => 'Ꝁ',
1028
+ 'ꝃ' => 'Ꝃ',
1029
+ 'ꝅ' => 'Ꝅ',
1030
+ 'ꝇ' => 'Ꝇ',
1031
+ 'ꝉ' => 'Ꝉ',
1032
+ 'ꝋ' => 'Ꝋ',
1033
+ 'ꝍ' => 'Ꝍ',
1034
+ 'ꝏ' => 'Ꝏ',
1035
+ 'ꝑ' => 'Ꝑ',
1036
+ 'ꝓ' => 'Ꝓ',
1037
+ 'ꝕ' => 'Ꝕ',
1038
+ 'ꝗ' => 'Ꝗ',
1039
+ 'ꝙ' => 'Ꝙ',
1040
+ 'ꝛ' => 'Ꝛ',
1041
+ 'ꝝ' => 'Ꝝ',
1042
+ 'ꝟ' => 'Ꝟ',
1043
+ 'ꝡ' => 'Ꝡ',
1044
+ 'ꝣ' => 'Ꝣ',
1045
+ 'ꝥ' => 'Ꝥ',
1046
+ 'ꝧ' => 'Ꝧ',
1047
+ 'ꝩ' => 'Ꝩ',
1048
+ 'ꝫ' => 'Ꝫ',
1049
+ 'ꝭ' => 'Ꝭ',
1050
+ 'ꝯ' => 'Ꝯ',
1051
+ 'ꝺ' => 'Ꝺ',
1052
+ 'ꝼ' => 'Ꝼ',
1053
+ 'ꝿ' => 'Ꝿ',
1054
+ 'ꞁ' => 'Ꞁ',
1055
+ 'ꞃ' => 'Ꞃ',
1056
+ 'ꞅ' => 'Ꞅ',
1057
+ 'ꞇ' => 'Ꞇ',
1058
+ 'ꞌ' => 'Ꞌ',
1059
+ 'ꞑ' => 'Ꞑ',
1060
+ 'ꞓ' => 'Ꞓ',
1061
+ 'ꞔ' => 'Ꞔ',
1062
+ 'ꞗ' => 'Ꞗ',
1063
+ 'ꞙ' => 'Ꞙ',
1064
+ 'ꞛ' => 'Ꞛ',
1065
+ 'ꞝ' => 'Ꞝ',
1066
+ 'ꞟ' => 'Ꞟ',
1067
+ 'ꞡ' => 'Ꞡ',
1068
+ 'ꞣ' => 'Ꞣ',
1069
+ 'ꞥ' => 'Ꞥ',
1070
+ 'ꞧ' => 'Ꞧ',
1071
+ 'ꞩ' => 'Ꞩ',
1072
+ 'ꞵ' => 'Ꞵ',
1073
+ 'ꞷ' => 'Ꞷ',
1074
+ 'ꞹ' => 'Ꞹ',
1075
+ 'ꞻ' => 'Ꞻ',
1076
+ 'ꞽ' => 'Ꞽ',
1077
+ 'ꞿ' => 'Ꞿ',
1078
+ 'ꟃ' => 'Ꟃ',
1079
+ 'ꟈ' => 'Ꟈ',
1080
+ 'ꟊ' => 'Ꟊ',
1081
+ 'ꟶ' => 'Ꟶ',
1082
+ 'ꭓ' => 'Ꭓ',
1083
+ 'ꭰ' => 'Ꭰ',
1084
+ 'ꭱ' => 'Ꭱ',
1085
+ 'ꭲ' => 'Ꭲ',
1086
+ 'ꭳ' => 'Ꭳ',
1087
+ 'ꭴ' => 'Ꭴ',
1088
+ 'ꭵ' => 'Ꭵ',
1089
+ 'ꭶ' => 'Ꭶ',
1090
+ 'ꭷ' => 'Ꭷ',
1091
+ 'ꭸ' => 'Ꭸ',
1092
+ 'ꭹ' => 'Ꭹ',
1093
+ 'ꭺ' => 'Ꭺ',
1094
+ 'ꭻ' => 'Ꭻ',
1095
+ 'ꭼ' => 'Ꭼ',
1096
+ 'ꭽ' => 'Ꭽ',
1097
+ 'ꭾ' => 'Ꭾ',
1098
+ 'ꭿ' => 'Ꭿ',
1099
+ 'ꮀ' => 'Ꮀ',
1100
+ 'ꮁ' => 'Ꮁ',
1101
+ 'ꮂ' => 'Ꮂ',
1102
+ 'ꮃ' => 'Ꮃ',
1103
+ 'ꮄ' => 'Ꮄ',
1104
+ 'ꮅ' => 'Ꮅ',
1105
+ 'ꮆ' => 'Ꮆ',
1106
+ 'ꮇ' => 'Ꮇ',
1107
+ 'ꮈ' => 'Ꮈ',
1108
+ 'ꮉ' => 'Ꮉ',
1109
+ 'ꮊ' => 'Ꮊ',
1110
+ 'ꮋ' => 'Ꮋ',
1111
+ 'ꮌ' => 'Ꮌ',
1112
+ 'ꮍ' => 'Ꮍ',
1113
+ 'ꮎ' => 'Ꮎ',
1114
+ 'ꮏ' => 'Ꮏ',
1115
+ 'ꮐ' => 'Ꮐ',
1116
+ 'ꮑ' => 'Ꮑ',
1117
+ 'ꮒ' => 'Ꮒ',
1118
+ 'ꮓ' => 'Ꮓ',
1119
+ 'ꮔ' => 'Ꮔ',
1120
+ 'ꮕ' => 'Ꮕ',
1121
+ 'ꮖ' => 'Ꮖ',
1122
+ 'ꮗ' => 'Ꮗ',
1123
+ 'ꮘ' => 'Ꮘ',
1124
+ 'ꮙ' => 'Ꮙ',
1125
+ 'ꮚ' => 'Ꮚ',
1126
+ 'ꮛ' => 'Ꮛ',
1127
+ 'ꮜ' => 'Ꮜ',
1128
+ 'ꮝ' => 'Ꮝ',
1129
+ 'ꮞ' => 'Ꮞ',
1130
+ 'ꮟ' => 'Ꮟ',
1131
+ 'ꮠ' => 'Ꮠ',
1132
+ 'ꮡ' => 'Ꮡ',
1133
+ 'ꮢ' => 'Ꮢ',
1134
+ 'ꮣ' => 'Ꮣ',
1135
+ 'ꮤ' => 'Ꮤ',
1136
+ 'ꮥ' => 'Ꮥ',
1137
+ 'ꮦ' => 'Ꮦ',
1138
+ 'ꮧ' => 'Ꮧ',
1139
+ 'ꮨ' => 'Ꮨ',
1140
+ 'ꮩ' => 'Ꮩ',
1141
+ 'ꮪ' => 'Ꮪ',
1142
+ 'ꮫ' => 'Ꮫ',
1143
+ 'ꮬ' => 'Ꮬ',
1144
+ 'ꮭ' => 'Ꮭ',
1145
+ 'ꮮ' => 'Ꮮ',
1146
+ 'ꮯ' => 'Ꮯ',
1147
+ 'ꮰ' => 'Ꮰ',
1148
+ 'ꮱ' => 'Ꮱ',
1149
+ 'ꮲ' => 'Ꮲ',
1150
+ 'ꮳ' => 'Ꮳ',
1151
+ 'ꮴ' => 'Ꮴ',
1152
+ 'ꮵ' => 'Ꮵ',
1153
+ 'ꮶ' => 'Ꮶ',
1154
+ 'ꮷ' => 'Ꮷ',
1155
+ 'ꮸ' => 'Ꮸ',
1156
+ 'ꮹ' => 'Ꮹ',
1157
+ 'ꮺ' => 'Ꮺ',
1158
+ 'ꮻ' => 'Ꮻ',
1159
+ 'ꮼ' => 'Ꮼ',
1160
+ 'ꮽ' => 'Ꮽ',
1161
+ 'ꮾ' => 'Ꮾ',
1162
+ 'ꮿ' => 'Ꮿ',
1163
+ 'a' => 'A',
1164
+ 'b' => 'B',
1165
+ 'c' => 'C',
1166
+ 'd' => 'D',
1167
+ 'e' => 'E',
1168
+ 'f' => 'F',
1169
+ 'g' => 'G',
1170
+ 'h' => 'H',
1171
+ 'i' => 'I',
1172
+ 'j' => 'J',
1173
+ 'k' => 'K',
1174
+ 'l' => 'L',
1175
+ 'm' => 'M',
1176
+ 'n' => 'N',
1177
+ 'o' => 'O',
1178
+ 'p' => 'P',
1179
+ 'q' => 'Q',
1180
+ 'r' => 'R',
1181
+ 's' => 'S',
1182
+ 't' => 'T',
1183
+ 'u' => 'U',
1184
+ 'v' => 'V',
1185
+ 'w' => 'W',
1186
+ 'x' => 'X',
1187
+ 'y' => 'Y',
1188
+ 'z' => 'Z',
1189
+ '𐐨' => '𐐀',
1190
+ '𐐩' => '𐐁',
1191
+ '𐐪' => '𐐂',
1192
+ '𐐫' => '𐐃',
1193
+ '𐐬' => '𐐄',
1194
+ '𐐭' => '𐐅',
1195
+ '𐐮' => '𐐆',
1196
+ '𐐯' => '𐐇',
1197
+ '𐐰' => '𐐈',
1198
+ '𐐱' => '𐐉',
1199
+ '𐐲' => '𐐊',
1200
+ '𐐳' => '𐐋',
1201
+ '𐐴' => '𐐌',
1202
+ '𐐵' => '𐐍',
1203
+ '𐐶' => '𐐎',
1204
+ '𐐷' => '𐐏',
1205
+ '𐐸' => '𐐐',
1206
+ '𐐹' => '𐐑',
1207
+ '𐐺' => '𐐒',
1208
+ '𐐻' => '𐐓',
1209
+ '𐐼' => '𐐔',
1210
+ '𐐽' => '𐐕',
1211
+ '𐐾' => '𐐖',
1212
+ '𐐿' => '𐐗',
1213
+ '𐑀' => '𐐘',
1214
+ '𐑁' => '𐐙',
1215
+ '𐑂' => '𐐚',
1216
+ '𐑃' => '𐐛',
1217
+ '𐑄' => '𐐜',
1218
+ '𐑅' => '𐐝',
1219
+ '𐑆' => '𐐞',
1220
+ '𐑇' => '𐐟',
1221
+ '𐑈' => '𐐠',
1222
+ '𐑉' => '𐐡',
1223
+ '𐑊' => '𐐢',
1224
+ '𐑋' => '𐐣',
1225
+ '𐑌' => '𐐤',
1226
+ '𐑍' => '𐐥',
1227
+ '𐑎' => '𐐦',
1228
+ '𐑏' => '𐐧',
1229
+ '𐓘' => '𐒰',
1230
+ '𐓙' => '𐒱',
1231
+ '𐓚' => '𐒲',
1232
+ '𐓛' => '𐒳',
1233
+ '𐓜' => '𐒴',
1234
+ '𐓝' => '𐒵',
1235
+ '𐓞' => '𐒶',
1236
+ '𐓟' => '𐒷',
1237
+ '𐓠' => '𐒸',
1238
+ '𐓡' => '𐒹',
1239
+ '𐓢' => '𐒺',
1240
+ '𐓣' => '𐒻',
1241
+ '𐓤' => '𐒼',
1242
+ '𐓥' => '𐒽',
1243
+ '𐓦' => '𐒾',
1244
+ '𐓧' => '𐒿',
1245
+ '𐓨' => '𐓀',
1246
+ '𐓩' => '𐓁',
1247
+ '𐓪' => '𐓂',
1248
+ '𐓫' => '𐓃',
1249
+ '𐓬' => '𐓄',
1250
+ '𐓭' => '𐓅',
1251
+ '𐓮' => '𐓆',
1252
+ '𐓯' => '𐓇',
1253
+ '𐓰' => '𐓈',
1254
+ '𐓱' => '𐓉',
1255
+ '𐓲' => '𐓊',
1256
+ '𐓳' => '𐓋',
1257
+ '𐓴' => '𐓌',
1258
+ '𐓵' => '𐓍',
1259
+ '𐓶' => '𐓎',
1260
+ '𐓷' => '𐓏',
1261
+ '𐓸' => '𐓐',
1262
+ '𐓹' => '𐓑',
1263
+ '𐓺' => '𐓒',
1264
+ '𐓻' => '𐓓',
1265
+ '𐳀' => '𐲀',
1266
+ '𐳁' => '𐲁',
1267
+ '𐳂' => '𐲂',
1268
+ '𐳃' => '𐲃',
1269
+ '𐳄' => '𐲄',
1270
+ '𐳅' => '𐲅',
1271
+ '𐳆' => '𐲆',
1272
+ '𐳇' => '𐲇',
1273
+ '𐳈' => '𐲈',
1274
+ '𐳉' => '𐲉',
1275
+ '𐳊' => '𐲊',
1276
+ '𐳋' => '𐲋',
1277
+ '𐳌' => '𐲌',
1278
+ '𐳍' => '𐲍',
1279
+ '𐳎' => '𐲎',
1280
+ '𐳏' => '𐲏',
1281
+ '𐳐' => '𐲐',
1282
+ '𐳑' => '𐲑',
1283
+ '𐳒' => '𐲒',
1284
+ '𐳓' => '𐲓',
1285
+ '𐳔' => '𐲔',
1286
+ '𐳕' => '𐲕',
1287
+ '𐳖' => '𐲖',
1288
+ '𐳗' => '𐲗',
1289
+ '𐳘' => '𐲘',
1290
+ '𐳙' => '𐲙',
1291
+ '𐳚' => '𐲚',
1292
+ '𐳛' => '𐲛',
1293
+ '𐳜' => '𐲜',
1294
+ '𐳝' => '𐲝',
1295
+ '𐳞' => '𐲞',
1296
+ '𐳟' => '𐲟',
1297
+ '𐳠' => '𐲠',
1298
+ '𐳡' => '𐲡',
1299
+ '𐳢' => '𐲢',
1300
+ '𐳣' => '𐲣',
1301
+ '𐳤' => '𐲤',
1302
+ '𐳥' => '𐲥',
1303
+ '𐳦' => '𐲦',
1304
+ '𐳧' => '𐲧',
1305
+ '𐳨' => '𐲨',
1306
+ '𐳩' => '𐲩',
1307
+ '𐳪' => '𐲪',
1308
+ '𐳫' => '𐲫',
1309
+ '𐳬' => '𐲬',
1310
+ '𐳭' => '𐲭',
1311
+ '𐳮' => '𐲮',
1312
+ '𐳯' => '𐲯',
1313
+ '𐳰' => '𐲰',
1314
+ '𐳱' => '𐲱',
1315
+ '𐳲' => '𐲲',
1316
+ '𑣀' => '𑢠',
1317
+ '𑣁' => '𑢡',
1318
+ '𑣂' => '𑢢',
1319
+ '𑣃' => '𑢣',
1320
+ '𑣄' => '𑢤',
1321
+ '𑣅' => '𑢥',
1322
+ '𑣆' => '𑢦',
1323
+ '𑣇' => '𑢧',
1324
+ '𑣈' => '𑢨',
1325
+ '𑣉' => '𑢩',
1326
+ '𑣊' => '𑢪',
1327
+ '𑣋' => '𑢫',
1328
+ '𑣌' => '𑢬',
1329
+ '𑣍' => '𑢭',
1330
+ '𑣎' => '𑢮',
1331
+ '𑣏' => '𑢯',
1332
+ '𑣐' => '𑢰',
1333
+ '𑣑' => '𑢱',
1334
+ '𑣒' => '𑢲',
1335
+ '𑣓' => '𑢳',
1336
+ '𑣔' => '𑢴',
1337
+ '𑣕' => '𑢵',
1338
+ '𑣖' => '𑢶',
1339
+ '𑣗' => '𑢷',
1340
+ '𑣘' => '𑢸',
1341
+ '𑣙' => '𑢹',
1342
+ '𑣚' => '𑢺',
1343
+ '𑣛' => '𑢻',
1344
+ '𑣜' => '𑢼',
1345
+ '𑣝' => '𑢽',
1346
+ '𑣞' => '𑢾',
1347
+ '𑣟' => '𑢿',
1348
+ '𖹠' => '𖹀',
1349
+ '𖹡' => '𖹁',
1350
+ '𖹢' => '𖹂',
1351
+ '𖹣' => '𖹃',
1352
+ '𖹤' => '𖹄',
1353
+ '𖹥' => '𖹅',
1354
+ '𖹦' => '𖹆',
1355
+ '𖹧' => '𖹇',
1356
+ '𖹨' => '𖹈',
1357
+ '𖹩' => '𖹉',
1358
+ '𖹪' => '𖹊',
1359
+ '𖹫' => '𖹋',
1360
+ '𖹬' => '𖹌',
1361
+ '𖹭' => '𖹍',
1362
+ '𖹮' => '𖹎',
1363
+ '𖹯' => '𖹏',
1364
+ '𖹰' => '𖹐',
1365
+ '𖹱' => '𖹑',
1366
+ '𖹲' => '𖹒',
1367
+ '𖹳' => '𖹓',
1368
+ '𖹴' => '𖹔',
1369
+ '𖹵' => '𖹕',
1370
+ '𖹶' => '𖹖',
1371
+ '𖹷' => '𖹗',
1372
+ '𖹸' => '𖹘',
1373
+ '𖹹' => '𖹙',
1374
+ '𖹺' => '𖹚',
1375
+ '𖹻' => '𖹛',
1376
+ '𖹼' => '𖹜',
1377
+ '𖹽' => '𖹝',
1378
+ '𖹾' => '𖹞',
1379
+ '𖹿' => '𖹟',
1380
+ '𞤢' => '𞤀',
1381
+ '𞤣' => '𞤁',
1382
+ '𞤤' => '𞤂',
1383
+ '𞤥' => '𞤃',
1384
+ '𞤦' => '𞤄',
1385
+ '𞤧' => '𞤅',
1386
+ '𞤨' => '𞤆',
1387
+ '𞤩' => '𞤇',
1388
+ '𞤪' => '𞤈',
1389
+ '𞤫' => '𞤉',
1390
+ '𞤬' => '𞤊',
1391
+ '𞤭' => '𞤋',
1392
+ '𞤮' => '𞤌',
1393
+ '𞤯' => '𞤍',
1394
+ '𞤰' => '𞤎',
1395
+ '𞤱' => '𞤏',
1396
+ '𞤲' => '𞤐',
1397
+ '𞤳' => '𞤑',
1398
+ '𞤴' => '𞤒',
1399
+ '𞤵' => '𞤓',
1400
+ '𞤶' => '𞤔',
1401
+ '𞤷' => '𞤕',
1402
+ '𞤸' => '𞤖',
1403
+ '𞤹' => '𞤗',
1404
+ '𞤺' => '𞤘',
1405
+ '𞤻' => '𞤙',
1406
+ '𞤼' => '𞤚',
1407
+ '𞤽' => '𞤛',
1408
+ '𞤾' => '𞤜',
1409
+ '𞤿' => '𞤝',
1410
+ '𞥀' => '𞤞',
1411
+ '𞥁' => '𞤟',
1412
+ '𞥂' => '𞤠',
1413
+ '𞥃' => '𞤡',
1414
+ 'ß' => 'SS',
1415
+ 'ff' => 'FF',
1416
+ 'fi' => 'FI',
1417
+ 'fl' => 'FL',
1418
+ 'ffi' => 'FFI',
1419
+ 'ffl' => 'FFL',
1420
+ 'ſt' => 'ST',
1421
+ 'st' => 'ST',
1422
+ 'և' => 'ԵՒ',
1423
+ 'ﬓ' => 'ՄՆ',
1424
+ 'ﬔ' => 'ՄԵ',
1425
+ 'ﬕ' => 'ՄԻ',
1426
+ 'ﬖ' => 'ՎՆ',
1427
+ 'ﬗ' => 'ՄԽ',
1428
+ 'ʼn' => 'ʼN',
1429
+ 'ΐ' => 'Ϊ́',
1430
+ 'ΰ' => 'Ϋ́',
1431
+ 'ǰ' => 'J̌',
1432
+ 'ẖ' => 'H̱',
1433
+ 'ẗ' => 'T̈',
1434
+ 'ẘ' => 'W̊',
1435
+ 'ẙ' => 'Y̊',
1436
+ 'ẚ' => 'Aʾ',
1437
+ 'ὐ' => 'Υ̓',
1438
+ 'ὒ' => 'Υ̓̀',
1439
+ 'ὔ' => 'Υ̓́',
1440
+ 'ὖ' => 'Υ̓͂',
1441
+ 'ᾶ' => 'Α͂',
1442
+ 'ῆ' => 'Η͂',
1443
+ 'ῒ' => 'Ϊ̀',
1444
+ 'ΐ' => 'Ϊ́',
1445
+ 'ῖ' => 'Ι͂',
1446
+ 'ῗ' => 'Ϊ͂',
1447
+ 'ῢ' => 'Ϋ̀',
1448
+ 'ΰ' => 'Ϋ́',
1449
+ 'ῤ' => 'Ρ̓',
1450
+ 'ῦ' => 'Υ͂',
1451
+ 'ῧ' => 'Ϋ͂',
1452
+ 'ῶ' => 'Ω͂',
1453
+ 'ᾈ' => 'ἈΙ',
1454
+ 'ᾉ' => 'ἉΙ',
1455
+ 'ᾊ' => 'ἊΙ',
1456
+ 'ᾋ' => 'ἋΙ',
1457
+ 'ᾌ' => 'ἌΙ',
1458
+ 'ᾍ' => 'ἍΙ',
1459
+ 'ᾎ' => 'ἎΙ',
1460
+ 'ᾏ' => 'ἏΙ',
1461
+ 'ᾘ' => 'ἨΙ',
1462
+ 'ᾙ' => 'ἩΙ',
1463
+ 'ᾚ' => 'ἪΙ',
1464
+ 'ᾛ' => 'ἫΙ',
1465
+ 'ᾜ' => 'ἬΙ',
1466
+ 'ᾝ' => 'ἭΙ',
1467
+ 'ᾞ' => 'ἮΙ',
1468
+ 'ᾟ' => 'ἯΙ',
1469
+ 'ᾨ' => 'ὨΙ',
1470
+ 'ᾩ' => 'ὩΙ',
1471
+ 'ᾪ' => 'ὪΙ',
1472
+ 'ᾫ' => 'ὫΙ',
1473
+ 'ᾬ' => 'ὬΙ',
1474
+ 'ᾭ' => 'ὭΙ',
1475
+ 'ᾮ' => 'ὮΙ',
1476
+ 'ᾯ' => 'ὯΙ',
1477
+ 'ᾼ' => 'ΑΙ',
1478
+ 'ῌ' => 'ΗΙ',
1479
+ 'ῼ' => 'ΩΙ',
1480
+ 'ᾲ' => 'ᾺΙ',
1481
+ 'ᾴ' => 'ΆΙ',
1482
+ 'ῂ' => 'ῊΙ',
1483
+ 'ῄ' => 'ΉΙ',
1484
+ 'ῲ' => 'ῺΙ',
1485
+ 'ῴ' => 'ΏΙ',
1486
+ 'ᾷ' => 'Α͂Ι',
1487
+ 'ῇ' => 'Η͂Ι',
1488
+ 'ῷ' => 'Ω͂Ι',
1489
+ );
vendor/symfony/polyfill-mbstring/bootstrap.php ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ use Symfony\Polyfill\Mbstring as p;
13
+
14
+ if (\PHP_VERSION_ID >= 80000) {
15
+ return require __DIR__.'/bootstrap80.php';
16
+ }
17
+
18
+ if (!function_exists('mb_convert_encoding')) {
19
+ function mb_convert_encoding($string, $to_encoding, $from_encoding = null) { return p\Mbstring::mb_convert_encoding($string, $to_encoding, $from_encoding); }
20
+ }
21
+ if (!function_exists('mb_decode_mimeheader')) {
22
+ function mb_decode_mimeheader($string) { return p\Mbstring::mb_decode_mimeheader($string); }
23
+ }
24
+ if (!function_exists('mb_encode_mimeheader')) {
25
+ function mb_encode_mimeheader($string, $charset = null, $transfer_encoding = null, $newline = "\r\n", $indent = 0) { return p\Mbstring::mb_encode_mimeheader($string, $charset, $transfer_encoding, $newline, $indent); }
26
+ }
27
+ if (!function_exists('mb_decode_numericentity')) {
28
+ function mb_decode_numericentity($string, $map, $encoding = null) { return p\Mbstring::mb_decode_numericentity($string, $map, $encoding); }
29
+ }
30
+ if (!function_exists('mb_encode_numericentity')) {
31
+ function mb_encode_numericentity($string, $map, $encoding = null, $hex = false) { return p\Mbstring::mb_encode_numericentity($string, $map, $encoding, $hex); }
32
+ }
33
+ if (!function_exists('mb_convert_case')) {
34
+ function mb_convert_case($string, $mode, $encoding = null) { return p\Mbstring::mb_convert_case($string, $mode, $encoding); }
35
+ }
36
+ if (!function_exists('mb_internal_encoding')) {
37
+ function mb_internal_encoding($encoding = null) { return p\Mbstring::mb_internal_encoding($encoding); }
38
+ }
39
+ if (!function_exists('mb_language')) {
40
+ function mb_language($language = null) { return p\Mbstring::mb_language($language); }
41
+ }
42
+ if (!function_exists('mb_list_encodings')) {
43
+ function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); }
44
+ }
45
+ if (!function_exists('mb_encoding_aliases')) {
46
+ function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); }
47
+ }
48
+ if (!function_exists('mb_check_encoding')) {
49
+ function mb_check_encoding($value = null, $encoding = null) { return p\Mbstring::mb_check_encoding($value, $encoding); }
50
+ }
51
+ if (!function_exists('mb_detect_encoding')) {
52
+ function mb_detect_encoding($string, $encodings = null, $strict = false) { return p\Mbstring::mb_detect_encoding($string, $encodings, $strict); }
53
+ }
54
+ if (!function_exists('mb_detect_order')) {
55
+ function mb_detect_order($encoding = null) { return p\Mbstring::mb_detect_order($encoding); }
56
+ }
57
+ if (!function_exists('mb_parse_str')) {
58
+ function mb_parse_str($string, &$result = []) { parse_str($string, $result); return (bool) $result; }
59
+ }
60
+ if (!function_exists('mb_strlen')) {
61
+ function mb_strlen($string, $encoding = null) { return p\Mbstring::mb_strlen($string, $encoding); }
62
+ }
63
+ if (!function_exists('mb_strpos')) {
64
+ function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strpos($haystack, $needle, $offset, $encoding); }
65
+ }
66
+ if (!function_exists('mb_strtolower')) {
67
+ function mb_strtolower($string, $encoding = null) { return p\Mbstring::mb_strtolower($string, $encoding); }
68
+ }
69
+ if (!function_exists('mb_strtoupper')) {
70
+ function mb_strtoupper($string, $encoding = null) { return p\Mbstring::mb_strtoupper($string, $encoding); }
71
+ }
72
+ if (!function_exists('mb_substitute_character')) {
73
+ function mb_substitute_character($substitute_character = null) { return p\Mbstring::mb_substitute_character($substitute_character); }
74
+ }
75
+ if (!function_exists('mb_substr')) {
76
+ function mb_substr($string, $start, $length = 2147483647, $encoding = null) { return p\Mbstring::mb_substr($string, $start, $length, $encoding); }
77
+ }
78
+ if (!function_exists('mb_stripos')) {
79
+ function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_stripos($haystack, $needle, $offset, $encoding); }
80
+ }
81
+ if (!function_exists('mb_stristr')) {
82
+ function mb_stristr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_stristr($haystack, $needle, $before_needle, $encoding); }
83
+ }
84
+ if (!function_exists('mb_strrchr')) {
85
+ function mb_strrchr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrchr($haystack, $needle, $before_needle, $encoding); }
86
+ }
87
+ if (!function_exists('mb_strrichr')) {
88
+ function mb_strrichr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrichr($haystack, $needle, $before_needle, $encoding); }
89
+ }
90
+ if (!function_exists('mb_strripos')) {
91
+ function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strripos($haystack, $needle, $offset, $encoding); }
92
+ }
93
+ if (!function_exists('mb_strrpos')) {
94
+ function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strrpos($haystack, $needle, $offset, $encoding); }
95
+ }
96
+ if (!function_exists('mb_strstr')) {
97
+ function mb_strstr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strstr($haystack, $needle, $before_needle, $encoding); }
98
+ }
99
+ if (!function_exists('mb_get_info')) {
100
+ function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); }
101
+ }
102
+ if (!function_exists('mb_http_output')) {
103
+ function mb_http_output($encoding = null) { return p\Mbstring::mb_http_output($encoding); }
104
+ }
105
+ if (!function_exists('mb_strwidth')) {
106
+ function mb_strwidth($string, $encoding = null) { return p\Mbstring::mb_strwidth($string, $encoding); }
107
+ }
108
+ if (!function_exists('mb_substr_count')) {
109
+ function mb_substr_count($haystack, $needle, $encoding = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $encoding); }
110
+ }
111
+ if (!function_exists('mb_output_handler')) {
112
+ function mb_output_handler($string, $status) { return p\Mbstring::mb_output_handler($string, $status); }
113
+ }
114
+ if (!function_exists('mb_http_input')) {
115
+ function mb_http_input($type = null) { return p\Mbstring::mb_http_input($type); }
116
+ }
117
+
118
+ if (!function_exists('mb_convert_variables')) {
119
+ function mb_convert_variables($to_encoding, $from_encoding, &...$vars) { return p\Mbstring::mb_convert_variables($to_encoding, $from_encoding, ...$vars); }
120
+ }
121
+
122
+ if (!function_exists('mb_ord')) {
123
+ function mb_ord($string, $encoding = null) { return p\Mbstring::mb_ord($string, $encoding); }
124
+ }
125
+ if (!function_exists('mb_chr')) {
126
+ function mb_chr($codepoint, $encoding = null) { return p\Mbstring::mb_chr($codepoint, $encoding); }
127
+ }
128
+ if (!function_exists('mb_scrub')) {
129
+ function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); }
130
+ }
131
+ if (!function_exists('mb_str_split')) {
132
+ function mb_str_split($string, $length = 1, $encoding = null) { return p\Mbstring::mb_str_split($string, $length, $encoding); }
133
+ }
134
+
135
+ if (extension_loaded('mbstring')) {
136
+ return;
137
+ }
138
+
139
+ if (!defined('MB_CASE_UPPER')) {
140
+ define('MB_CASE_UPPER', 0);
141
+ }
142
+ if (!defined('MB_CASE_LOWER')) {
143
+ define('MB_CASE_LOWER', 1);
144
+ }
145
+ if (!defined('MB_CASE_TITLE')) {
146
+ define('MB_CASE_TITLE', 2);
147
+ }
vendor/symfony/polyfill-mbstring/bootstrap80.php ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ use Symfony\Polyfill\Mbstring as p;
13
+
14
+ if (!function_exists('mb_convert_encoding')) {
15
+ function mb_convert_encoding(array|string|null $string, ?string $to_encoding, array|string|null $from_encoding = null): array|string|false { return p\Mbstring::mb_convert_encoding($string ?? '', (string) $to_encoding, $from_encoding); }
16
+ }
17
+ if (!function_exists('mb_decode_mimeheader')) {
18
+ function mb_decode_mimeheader(?string $string): string { return p\Mbstring::mb_decode_mimeheader((string) $string); }
19
+ }
20
+ if (!function_exists('mb_encode_mimeheader')) {
21
+ function mb_encode_mimeheader(?string $string, ?string $charset = null, ?string $transfer_encoding = null, ?string $newline = "\r\n", ?int $indent = 0): string { return p\Mbstring::mb_encode_mimeheader((string) $string, $charset, $transfer_encoding, (string) $newline, (int) $indent); }
22
+ }
23
+ if (!function_exists('mb_decode_numericentity')) {
24
+ function mb_decode_numericentity(?string $string, array $map, ?string $encoding = null): string { return p\Mbstring::mb_decode_numericentity((string) $string, $map, $encoding); }
25
+ }
26
+ if (!function_exists('mb_encode_numericentity')) {
27
+ function mb_encode_numericentity(?string $string, array $map, ?string $encoding = null, ?bool $hex = false): string { return p\Mbstring::mb_encode_numericentity((string) $string, $map, $encoding, (bool) $hex); }
28
+ }
29
+ if (!function_exists('mb_convert_case')) {
30
+ function mb_convert_case(?string $string, ?int $mode, ?string $encoding = null): string { return p\Mbstring::mb_convert_case((string) $string, (int) $mode, $encoding); }
31
+ }
32
+ if (!function_exists('mb_internal_encoding')) {
33
+ function mb_internal_encoding(?string $encoding = null): string|bool { return p\Mbstring::mb_internal_encoding($encoding); }
34
+ }
35
+ if (!function_exists('mb_language')) {
36
+ function mb_language(?string $language = null): string|bool { return p\Mbstring::mb_language($language); }
37
+ }
38
+ if (!function_exists('mb_list_encodings')) {
39
+ function mb_list_encodings(): array { return p\Mbstring::mb_list_encodings(); }
40
+ }
41
+ if (!function_exists('mb_encoding_aliases')) {
42
+ function mb_encoding_aliases(?string $encoding): array { return p\Mbstring::mb_encoding_aliases((string) $encoding); }
43
+ }
44
+ if (!function_exists('mb_check_encoding')) {
45
+ function mb_check_encoding(array|string|null $value = null, ?string $encoding = null): bool { return p\Mbstring::mb_check_encoding($value, $encoding); }
46
+ }
47
+ if (!function_exists('mb_detect_encoding')) {
48
+ function mb_detect_encoding(?string $string, array|string|null $encodings = null, ?bool $strict = false): string|false { return p\Mbstring::mb_detect_encoding((string) $string, $encodings, (bool) $strict); }
49
+ }
50
+ if (!function_exists('mb_detect_order')) {
51
+ function mb_detect_order(array|string|null $encoding = null): array|bool { return p\Mbstring::mb_detect_order($encoding); }
52
+ }
53
+ if (!function_exists('mb_parse_str')) {
54
+ function mb_parse_str(?string $string, &$result = []): bool { parse_str((string) $string, $result); return (bool) $result; }
55
+ }
56
+ if (!function_exists('mb_strlen')) {
57
+ function mb_strlen(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strlen((string) $string, $encoding); }
58
+ }
59
+ if (!function_exists('mb_strpos')) {
60
+ function mb_strpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strpos((string) $haystack, (string) $needle, (int) $offset, $encoding); }
61
+ }
62
+ if (!function_exists('mb_strtolower')) {
63
+ function mb_strtolower(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_strtolower((string) $string, $encoding); }
64
+ }
65
+ if (!function_exists('mb_strtoupper')) {
66
+ function mb_strtoupper(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_strtoupper((string) $string, $encoding); }
67
+ }
68
+ if (!function_exists('mb_substitute_character')) {
69
+ function mb_substitute_character(string|int|null $substitute_character = null): string|int|bool { return p\Mbstring::mb_substitute_character($substitute_character); }
70
+ }
71
+ if (!function_exists('mb_substr')) {
72
+ function mb_substr(?string $string, ?int $start, ?int $length = null, ?string $encoding = null): string { return p\Mbstring::mb_substr((string) $string, (int) $start, $length, $encoding); }
73
+ }
74
+ if (!function_exists('mb_stripos')) {
75
+ function mb_stripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_stripos((string) $haystack, (string) $needle, (int) $offset, $encoding); }
76
+ }
77
+ if (!function_exists('mb_stristr')) {
78
+ function mb_stristr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_stristr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }
79
+ }
80
+ if (!function_exists('mb_strrchr')) {
81
+ function mb_strrchr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrchr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }
82
+ }
83
+ if (!function_exists('mb_strrichr')) {
84
+ function mb_strrichr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrichr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }
85
+ }
86
+ if (!function_exists('mb_strripos')) {
87
+ function mb_strripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strripos((string) $haystack, (string) $needle, (int) $offset, $encoding); }
88
+ }
89
+ if (!function_exists('mb_strrpos')) {
90
+ function mb_strrpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strrpos((string) $haystack, (string) $needle, (int) $offset, $encoding); }
91
+ }
92
+ if (!function_exists('mb_strstr')) {
93
+ function mb_strstr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strstr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }
94
+ }
95
+ if (!function_exists('mb_get_info')) {
96
+ function mb_get_info(?string $type = 'all'): array|string|int|false { return p\Mbstring::mb_get_info((string) $type); }
97
+ }
98
+ if (!function_exists('mb_http_output')) {
99
+ function mb_http_output(?string $encoding = null): string|bool { return p\Mbstring::mb_http_output($encoding); }
100
+ }
101
+ if (!function_exists('mb_strwidth')) {
102
+ function mb_strwidth(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strwidth((string) $string, $encoding); }
103
+ }
104
+ if (!function_exists('mb_substr_count')) {
105
+ function mb_substr_count(?string $haystack, ?string $needle, ?string $encoding = null): int { return p\Mbstring::mb_substr_count((string) $haystack, (string) $needle, $encoding); }
106
+ }
107
+ if (!function_exists('mb_output_handler')) {
108
+ function mb_output_handler(?string $string, ?int $status): string { return p\Mbstring::mb_output_handler((string) $string, (int) $status); }
109
+ }
110
+ if (!function_exists('mb_http_input')) {
111
+ function mb_http_input(?string $type = null): array|string|false { return p\Mbstring::mb_http_input($type); }
112
+ }
113
+
114
+ if (!function_exists('mb_convert_variables')) {
115
+ function mb_convert_variables(?string $to_encoding, array|string|null $from_encoding, mixed &$var, mixed &...$vars): string|false { return p\Mbstring::mb_convert_variables((string) $to_encoding, $from_encoding ?? '', $var, ...$vars); }
116
+ }
117
+
118
+ if (!function_exists('mb_ord')) {
119
+ function mb_ord(?string $string, ?string $encoding = null): int|false { return p\Mbstring::mb_ord((string) $string, $encoding); }
120
+ }
121
+ if (!function_exists('mb_chr')) {
122
+ function mb_chr(?int $codepoint, ?string $encoding = null): string|false { return p\Mbstring::mb_chr((int) $codepoint, $encoding); }
123
+ }
124
+ if (!function_exists('mb_scrub')) {
125
+ function mb_scrub(?string $string, ?string $encoding = null): string { $encoding ??= mb_internal_encoding(); return mb_convert_encoding((string) $string, $encoding, $encoding); }
126
+ }
127
+ if (!function_exists('mb_str_split')) {
128
+ function mb_str_split(?string $string, ?int $length = 1, ?string $encoding = null): array { return p\Mbstring::mb_str_split((string) $string, (int) $length, $encoding); }
129
+ }
130
+
131
+ if (extension_loaded('mbstring')) {
132
+ return;
133
+ }
134
+
135
+ if (!defined('MB_CASE_UPPER')) {
136
+ define('MB_CASE_UPPER', 0);
137
+ }
138
+ if (!defined('MB_CASE_LOWER')) {
139
+ define('MB_CASE_LOWER', 1);
140
+ }
141
+ if (!defined('MB_CASE_TITLE')) {
142
+ define('MB_CASE_TITLE', 2);
143
+ }
vendor/symfony/polyfill-mbstring/composer.json ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "symfony/polyfill-mbstring",
3
+ "type": "library",
4
+ "description": "Symfony polyfill for the Mbstring extension",
5
+ "keywords": ["polyfill", "shim", "compatibility", "portable", "mbstring"],
6
+ "homepage": "https://symfony.com",
7
+ "license": "MIT",
8
+ "authors": [
9
+ {
10
+ "name": "Nicolas Grekas",
11
+ "email": "p@tchwork.com"
12
+ },
13
+ {
14
+ "name": "Symfony Community",
15
+ "homepage": "https://symfony.com/contributors"
16
+ }
17
+ ],
18
+ "require": {
19
+ "php": ">=7.1"
20
+ },
21
+ "provide": {
22
+ "ext-mbstring": "*"
23
+ },
24
+ "autoload": {
25
+ "psr-4": { "Symfony\\Polyfill\\Mbstring\\": "" },
26
+ "files": [ "bootstrap.php" ]
27
+ },
28
+ "suggest": {
29
+ "ext-mbstring": "For best performance"
30
+ },
31
+ "minimum-stability": "dev",
32
+ "extra": {
33
+ "branch-alias": {
34
+ "dev-main": "1.26-dev"
35
+ },
36
+ "thanks": {
37
+ "name": "symfony/polyfill",
38
+ "url": "https://github.com/symfony/polyfill"
39
+ }
40
+ }
41
+ }
vendor/symfony/polyfill-php72/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2015-2019 Fabien Potencier
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
vendor/symfony/polyfill-php72/Php72.php ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Polyfill\Php72;
13
+
14
+ /**
15
+ * @author Nicolas Grekas <p@tchwork.com>
16
+ * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
17
+ *
18
+ * @internal
19
+ */
20
+ final class Php72
21
+ {
22
+ private static $hashMask;
23
+
24
+ public static function utf8_encode($s)
25
+ {
26
+ $s .= $s;
27
+ $len = \strlen($s);
28
+
29
+ for ($i = $len >> 1, $j = 0; $i < $len; ++$i, ++$j) {
30
+ switch (true) {
31
+ case $s[$i] < "\x80": $s[$j] = $s[$i]; break;
32
+ case $s[$i] < "\xC0": $s[$j] = "\xC2"; $s[++$j] = $s[$i]; break;
33
+ default: $s[$j] = "\xC3"; $s[++$j] = \chr(\ord($s[$i]) - 64); break;
34
+ }
35
+ }
36
+
37
+ return substr($s, 0, $j);
38
+ }
39
+
40
+ public static function utf8_decode($s)
41
+ {
42
+ $s = (string) $s;
43
+ $len = \strlen($s);
44
+
45
+ for ($i = 0, $j = 0; $i < $len; ++$i, ++$j) {
46
+ switch ($s[$i] & "\xF0") {
47
+ case "\xC0":
48
+ case "\xD0":
49
+ $c = (\ord($s[$i] & "\x1F") << 6) | \ord($s[++$i] & "\x3F");
50
+ $s[$j] = $c < 256 ? \chr($c) : '?';
51
+ break;
52
+
53
+ case "\xF0":
54
+ ++$i;
55
+ // no break
56
+
57
+ case "\xE0":
58
+ $s[$j] = '?';
59
+ $i += 2;
60
+ break;
61
+
62
+ default:
63
+ $s[$j] = $s[$i];
64
+ }
65
+ }
66
+
67
+ return substr($s, 0, $j);
68
+ }
69
+
70
+ public static function php_os_family()
71
+ {
72
+ if ('\\' === \DIRECTORY_SEPARATOR) {
73
+ return 'Windows';
74
+ }
75
+
76
+ $map = [
77
+ 'Darwin' => 'Darwin',
78
+ 'DragonFly' => 'BSD',
79
+ 'FreeBSD' => 'BSD',
80
+ 'NetBSD' => 'BSD',
81
+ 'OpenBSD' => 'BSD',
82
+ 'Linux' => 'Linux',
83
+ 'SunOS' => 'Solaris',
84
+ ];
85
+
86
+ return isset($map[\PHP_OS]) ? $map[\PHP_OS] : 'Unknown';
87
+ }
88
+
89
+ public static function spl_object_id($object)
90
+ {
91
+ if (null === self::$hashMask) {
92
+ self::initHashMask();
93
+ }
94
+ if (null === $hash = spl_object_hash($object)) {
95
+ return;
96
+ }
97
+
98
+ // On 32-bit systems, PHP_INT_SIZE is 4,
99
+ return self::$hashMask ^ hexdec(substr($hash, 16 - (\PHP_INT_SIZE * 2 - 1), (\PHP_INT_SIZE * 2 - 1)));
100
+ }
101
+
102
+ public static function sapi_windows_vt100_support($stream, $enable = null)
103
+ {
104
+ if (!\is_resource($stream)) {
105
+ trigger_error('sapi_windows_vt100_support() expects parameter 1 to be resource, '.\gettype($stream).' given', \E_USER_WARNING);
106
+
107
+ return false;
108
+ }
109
+
110
+ $meta = stream_get_meta_data($stream);
111
+
112
+ if ('STDIO' !== $meta['stream_type']) {
113
+ trigger_error('sapi_windows_vt100_support() was not able to analyze the specified stream', \E_USER_WARNING);
114
+
115
+ return false;
116
+ }
117
+
118
+ // We cannot actually disable vt100 support if it is set
119
+ if (false === $enable || !self::stream_isatty($stream)) {
120
+ return false;
121
+ }
122
+
123
+ // The native function does not apply to stdin
124
+ $meta = array_map('strtolower', $meta);
125
+ $stdin = 'php://stdin' === $meta['uri'] || 'php://fd/0' === $meta['uri'];
126
+
127
+ return !$stdin
128
+ && (false !== getenv('ANSICON')
129
+ || 'ON' === getenv('ConEmuANSI')
130
+ || 'xterm' === getenv('TERM')
131
+ || 'Hyper' === getenv('TERM_PROGRAM'));
132
+ }
133
+
134
+ public static function stream_isatty($stream)
135
+ {
136
+ if (!\is_resource($stream)) {
137
+ trigger_error('stream_isatty() expects parameter 1 to be resource, '.\gettype($stream).' given', \E_USER_WARNING);
138
+
139
+ return false;
140
+ }
141
+
142
+ if ('\\' === \DIRECTORY_SEPARATOR) {
143
+ $stat = @fstat($stream);
144
+ // Check if formatted mode is S_IFCHR
145
+ return $stat ? 0020000 === ($stat['mode'] & 0170000) : false;
146
+ }
147
+
148
+ return \function_exists('posix_isatty') && @posix_isatty($stream);
149
+ }
150
+
151
+ private static function initHashMask()
152
+ {
153
+ $obj = (object) [];
154
+ self::$hashMask = -1;
155
+
156
+ // check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below
157
+ $obFuncs = ['ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush'];
158
+ foreach (debug_backtrace(\PHP_VERSION_ID >= 50400 ? \DEBUG_BACKTRACE_IGNORE_ARGS : false) as $frame) {
159
+ if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && \in_array($frame['function'], $obFuncs)) {
160
+ $frame['line'] = 0;
161
+ break;
162
+ }
163
+ }
164
+ if (!empty($frame['line'])) {
165
+ ob_start();
166
+ debug_zval_dump($obj);
167
+ self::$hashMask = (int) substr(ob_get_clean(), 17);
168
+ }
169
+
170
+ self::$hashMask ^= hexdec(substr(spl_object_hash($obj), 16 - (\PHP_INT_SIZE * 2 - 1), (\PHP_INT_SIZE * 2 - 1)));
171
+ }
172
+
173
+ public static function mb_chr($code, $encoding = null)
174
+ {
175
+ if (0x80 > $code %= 0x200000) {
176
+ $s = \chr($code);
177
+ } elseif (0x800 > $code) {
178
+ $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F);
179
+ } elseif (0x10000 > $code) {
180
+ $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
181
+ } else {
182
+ $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
183
+ }
184
+
185
+ if ('UTF-8' !== $encoding = $encoding ?? mb_internal_encoding()) {
186
+ $s = mb_convert_encoding($s, $encoding, 'UTF-8');
187
+ }
188
+
189
+ return $s;
190
+ }
191
+
192
+ public static function mb_ord($s, $encoding = null)
193
+ {
194
+ if (null === $encoding) {
195
+ $s = mb_convert_encoding($s, 'UTF-8');
196
+ } elseif ('UTF-8' !== $encoding) {
197
+ $s = mb_convert_encoding($s, 'UTF-8', $encoding);
198
+ }
199
+
200
+ if (1 === \strlen($s)) {
201
+ return \ord($s);
202
+ }
203
+
204
+ $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
205
+ if (0xF0 <= $code) {
206
+ return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
207
+ }
208
+ if (0xE0 <= $code) {
209
+ return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
210
+ }
211
+ if (0xC0 <= $code) {
212
+ return (($code - 0xC0) << 6) + $s[2] - 0x80;
213
+ }
214
+
215
+ return $code;
216
+ }
217
+ }
vendor/symfony/polyfill-php72/README.md ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Symfony Polyfill / Php72
2
+ ========================
3
+
4
+ This component provides functions added to PHP 7.2 core:
5
+
6
+ - [`spl_object_id`](https://php.net/spl_object_id)
7
+ - [`stream_isatty`](https://php.net/stream_isatty)
8
+
9
+ And also functions added to PHP 7.2 mbstring:
10
+
11
+ - [`mb_ord`](https://php.net/mb_ord)
12
+ - [`mb_chr`](https://php.net/mb_chr)
13
+ - [`mb_scrub`](https://php.net/mb_scrub)
14
+
15
+ On Windows only:
16
+
17
+ - [`sapi_windows_vt100_support`](https://php.net/sapi_windows_vt100_support)
18
+
19
+ Moved to core since 7.2 (was in the optional XML extension earlier):
20
+
21
+ - [`utf8_encode`](https://php.net/utf8_encode)
22
+ - [`utf8_decode`](https://php.net/utf8_decode)
23
+
24
+ Also, it provides constants added to PHP 7.2:
25
+
26
+ - [`PHP_FLOAT_*`](https://php.net/reserved.constants#constant.php-float-dig)
27
+ - [`PHP_OS_FAMILY`](https://php.net/reserved.constants#constant.php-os-family)
28
+
29
+ More information can be found in the
30
+ [main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).
31
+
32
+ License
33
+ =======
34
+
35
+ This library is released under the [MIT license](LICENSE).
vendor/symfony/polyfill-php72/bootstrap.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ use Symfony\Polyfill\Php72 as p;
13
+
14
+ if (\PHP_VERSION_ID >= 70200) {
15
+ return;
16
+ }
17
+
18
+ if (!defined('PHP_FLOAT_DIG')) {
19
+ define('PHP_FLOAT_DIG', 15);
20
+ }
21
+ if (!defined('PHP_FLOAT_EPSILON')) {
22
+ define('PHP_FLOAT_EPSILON', 2.2204460492503E-16);
23
+ }
24
+ if (!defined('PHP_FLOAT_MIN')) {
25
+ define('PHP_FLOAT_MIN', 2.2250738585072E-308);
26
+ }
27
+ if (!defined('PHP_FLOAT_MAX')) {
28
+ define('PHP_FLOAT_MAX', 1.7976931348623157E+308);
29
+ }
30
+ if (!defined('PHP_OS_FAMILY')) {
31
+ define('PHP_OS_FAMILY', p\Php72::php_os_family());
32
+ }
33
+
34
+ if ('\\' === \DIRECTORY_SEPARATOR && !function_exists('sapi_windows_vt100_support')) {
35
+ function sapi_windows_vt100_support($stream, $enable = null) { return p\Php72::sapi_windows_vt100_support($stream, $enable); }
36
+ }
37
+ if (!function_exists('stream_isatty')) {
38
+ function stream_isatty($stream) { return p\Php72::stream_isatty($stream); }
39
+ }
40
+ if (!function_exists('utf8_encode')) {
41
+ function utf8_encode($string) { return p\Php72::utf8_encode($string); }
42
+ }
43
+ if (!function_exists('utf8_decode')) {
44
+ function utf8_decode($string) { return p\Php72::utf8_decode($string); }
45
+ }
46
+ if (!function_exists('spl_object_id')) {
47
+ function spl_object_id($object) { return p\Php72::spl_object_id($object); }
48
+ }
49
+ if (!function_exists('mb_ord')) {
50
+ function mb_ord($string, $encoding = null) { return p\Php72::mb_ord($string, $encoding); }
51
+ }
52
+ if (!function_exists('mb_chr')) {
53
+ function mb_chr($codepoint, $encoding = null) { return p\Php72::mb_chr($codepoint, $encoding); }
54
+ }
55
+ if (!function_exists('mb_scrub')) {
56
+ function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); }
57
+ }
vendor/symfony/polyfill-php72/composer.json ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "symfony/polyfill-php72",
3
+ "type": "library",
4
+ "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
5
+ "keywords": ["polyfill", "shim", "compatibility", "portable"],
6
+ "homepage": "https://symfony.com",
7
+ "license": "MIT",
8
+ "authors": [
9
+ {
10
+ "name": "Nicolas Grekas",
11
+ "email": "p@tchwork.com"
12
+ },
13
+ {
14
+ "name": "Symfony Community",
15
+ "homepage": "https://symfony.com/contributors"
16
+ }
17
+ ],
18
+ "require": {
19
+ "php": ">=7.1"
20
+ },
21
+ "autoload": {
22
+ "psr-4": { "Symfony\\Polyfill\\Php72\\": "" },
23
+ "files": [ "bootstrap.php" ]
24
+ },
25
+ "minimum-stability": "dev",
26
+ "extra": {
27
+ "branch-alias": {
28
+ "dev-main": "1.26-dev"
29
+ },
30
+ "thanks": {
31
+ "name": "symfony/polyfill",
32
+ "url": "https://github.com/symfony/polyfill"
33
+ }
34
+ }
35
+ }
vendor/twig/twig/.gitattributes CHANGED
@@ -1,2 +1,4 @@
1
- /tests export-ignore
 
 
2
  /phpunit.xml.dist export-ignore
1
+ /doc/ export-ignore
2
+ /extra/ export-ignore
3
+ /tests/ export-ignore
4
  /phpunit.xml.dist export-ignore
vendor/twig/twig/.github/workflows/ci.yml ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "CI"
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches:
7
+ - '2.x'
8
+
9
+ env:
10
+ SYMFONY_PHPUNIT_DISABLE_RESULT_CACHE: 1
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ tests:
17
+ name: "PHP ${{ matrix.php-version }}"
18
+
19
+ runs-on: 'ubuntu-latest'
20
+
21
+ continue-on-error: ${{ matrix.experimental }}
22
+
23
+ strategy:
24
+ matrix:
25
+ php-version:
26
+ - '7.1.3'
27
+ - '7.2.5'
28
+ - '7.3'
29
+ - '7.4'
30
+ - '8.0'
31
+ - '8.1'
32
+ experimental: [false]
33
+
34
+ steps:
35
+ - name: "Checkout code"
36
+ uses: actions/checkout@v2
37
+
38
+ - name: "Install PHP with extensions"
39
+ uses: shivammathur/setup-php@v2
40
+ with:
41
+ coverage: "none"
42
+ php-version: ${{ matrix.php-version }}
43
+ ini-values: memory_limit=-1
44
+
45
+ - name: "Add PHPUnit matcher"
46
+ run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
47
+
48
+ - run: composer install
49
+
50
+ - name: "Install PHPUnit"
51
+ run: vendor/bin/simple-phpunit install
52
+
53
+ - name: "PHPUnit version"
54
+ run: vendor/bin/simple-phpunit --version
55
+
56
+ - name: "Run tests"
57
+ run: vendor/bin/simple-phpunit
58
+
59
+ extension-tests:
60
+ needs:
61
+ - 'tests'
62
+
63
+ name: "${{ matrix.extension }} with PHP ${{ matrix.php-version }}"
64
+
65
+ runs-on: 'ubuntu-latest'
66
+
67
+ continue-on-error: true
68
+
69
+ strategy:
70
+ matrix:
71
+ php-version:
72
+ - '7.2.5'
73
+ - '7.3'
74
+ - '7.4'
75
+ - '8.0'
76
+ - '8.1'
77
+ extension:
78
+ - 'extra/cssinliner-extra'
79
+ - 'extra/html-extra'
80
+ - 'extra/inky-extra'
81
+ - 'extra/intl-extra'
82
+ - 'extra/markdown-extra'
83
+ - 'extra/string-extra'
84
+ - 'extra/twig-extra-bundle'
85
+ experimental: [false]
86
+
87
+ steps:
88
+ - name: "Checkout code"
89
+ uses: actions/checkout@v2
90
+
91
+ - name: "Install PHP with extensions"
92
+ uses: shivammathur/setup-php@v2
93
+ with:
94
+ coverage: "none"
95
+ php-version: ${{ matrix.php-version }}
96
+ ini-values: memory_limit=-1
97
+
98
+ - name: "Add PHPUnit matcher"
99
+ run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
100
+
101
+ - run: composer install
102
+
103
+ - name: "Install PHPUnit"
104
+ run: vendor/bin/simple-phpunit install
105
+
106
+ - name: "PHPUnit version"
107
+ run: vendor/bin/simple-phpunit --version
108
+
109
+ - name: "Composer install"
110
+ working-directory: ${{ matrix.extension}}
111
+ run: composer install
112
+
113
+ - name: "Run tests"
114
+ working-directory: ${{ matrix.extension}}
115
+ run: ../../vendor/bin/simple-phpunit
116
+
117
+ integration-tests:
118
+ needs:
119
+ - 'tests'
120
+
121
+ name: "Integration tests with PHP ${{ matrix.php-version }}"
122
+
123
+ runs-on: 'ubuntu-20.04'
124
+
125
+ continue-on-error: true
126
+
127
+ strategy:
128
+ matrix:
129
+ php-version:
130
+ - '7.3'
131
+
132
+ steps:
133
+ - name: "Checkout code"
134
+ uses: actions/checkout@v2
135
+
136
+ - name: "Install PHP with extensions"
137
+ uses: shivammathur/setup-php@v2
138
+ with:
139
+ coverage: "none"
140
+ extensions: "gd, pdo_sqlite"
141
+ php-version: ${{ matrix.php-version }}
142
+ ini-values: memory_limit=-1
143
+ tools: composer:v2
144
+
145
+ - run: bash ./tests/drupal_test.sh
146
+ shell: "bash"
vendor/twig/twig/.github/workflows/documentation.yml ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "Documentation"
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches:
7
+ - '2.x'
8
+ - '3.x'
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ build:
15
+ name: "Build"
16
+
17
+ runs-on: ubuntu-latest
18
+
19
+ steps:
20
+ - name: "Checkout code"
21
+ uses: actions/checkout@v2
22
+
23
+ - name: "Set-up PHP"
24
+ uses: shivammathur/setup-php@v2
25
+ with:
26
+ php-version: 8.1
27
+ coverage: none
28
+ tools: "composer:v2"
29
+
30
+ - name: Get composer cache directory
31
+ id: composercache
32
+ working-directory: doc/_build
33
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
34
+
35
+ - name: Cache dependencies
36
+ uses: actions/cache@v2
37
+ with:
38
+ path: ${{ steps.composercache.outputs.dir }}
39
+ key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
40
+ restore-keys: ${{ runner.os }}-composer-
41
+
42
+ - name: "Install dependencies"
43
+ working-directory: doc/_build
44
+ run: composer install --prefer-dist --no-progress
45
+
46
+ - name: "Build the docs"
47
+ working-directory: doc/_build
48
+ run: php build.php --disable-cache
49
+
50
+ doctor-rst:
51
+ name: "DOCtor-RST"
52
+
53
+ runs-on: ubuntu-latest
54
+
55
+ steps:
56
+ - name: "Checkout code"
57
+ uses: actions/checkout@v2
58
+
59
+ - name: "Run DOCtor-RST"
60
+ uses: docker://oskarstark/doctor-rst
61
+ with:
62
+ args: --short
63
+ env:
64
+ DOCS_DIR: 'doc/'
vendor/twig/twig/.gitignore CHANGED
@@ -1,6 +1,6 @@
1
- /build
 
2
  /composer.lock
3
- /ext/twig/autom4te.cache/
4
  /phpunit.xml
5
  /vendor
6
  .phpunit.result.cache
1
+ /doc/_build/vendor
2
+ /doc/_build/output
3
  /composer.lock
 
4
  /phpunit.xml
5
  /vendor
6
  .phpunit.result.cache
vendor/twig/twig/{.php_cs.dist → .php-cs-fixer.dist.php} RENAMED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- return PhpCsFixer\Config::create()
4
  ->setRules([
5
  '@Symfony' => true,
6
  '@Symfony:risky' => true,
@@ -16,5 +16,5 @@ return PhpCsFixer\Config::create()
16
  'native_function_invocation' => ['include' => ['@compiler_optimized'], 'scope' => 'all'],
17
  ])
18
  ->setRiskyAllowed(true)
19
- ->setFinder(PhpCsFixer\Finder::create()->in(__DIR__))
20
  ;
1
  <?php
2
 
3
+ return (new PhpCsFixer\Config())
4
  ->setRules([
5
  '@Symfony' => true,
6
  '@Symfony:risky' => true,
16
  'native_function_invocation' => ['include' => ['@compiler_optimized'], 'scope' => 'all'],
17
  ])
18
  ->setRiskyAllowed(true)
19
+ ->setFinder((new PhpCsFixer\Finder())->in(__DIR__))
20
  ;
vendor/twig/twig/.travis.yml DELETED
@@ -1,46 +0,0 @@
1
- language: php
2
-
3
- dist: trusty
4
-
5
- sudo: false
6
-
7
- cache:
8
- directories:
9
- - vendor
10
- - $HOME/.composer/cache/files
11
-
12
-
13
- env:
14
- global:
15
- - TWIG_EXT=no
16
- - SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT=1
17
-
18
- before_install:
19
- - phpenv config-rm xdebug.ini || return 0
20
-
21
- install:
22
- - travis_retry composer install
23
-
24
- before_script:
25
- - if [ "$TWIG_EXT" == "yes" ]; then sh -c "cd ext/twig && phpize && ./configure --enable-twig && make && make install"; fi
26
- - if [ "$TWIG_EXT" == "yes" ]; then echo "extension=twig.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`; fi
27
-
28
- script: ./vendor/bin/simple-phpunit
29
-
30
- jobs:
31
- fast_finish: true
32
- include:
33
- - php: 5.5
34
- - php: 5.5
35
- env: TWIG_EXT=yes
36
- - php: 5.6
37
- - php: 5.6
38
- env: TWIG_EXT=yes
39
- - php: 7.0
40
- - php: 7.1
41
- - php: 7.2
42
- - php: 7.3
43
- - php: 7.4snapshot
44
- - stage: integration tests
45
- php: 7.3
46
- script: ./drupal_test.sh
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/CHANGELOG CHANGED
@@ -1,61 +1,208 @@
1
- * 1.42.5 (2020-02-11)
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  * Fix implementation of case-insensitivity for method names
4
 
5
- * 1.42.4 (2019-11-11)
6
 
7
- * optimized "block('foo') ?? 'bar"
8
- * added supported for exponential numbers
9
 
10
- * 1.42.3 (2019-08-24)
11
 
12
- * fixed the "split" filter when the delimiter is "0"
13
- * fixed the "empty" test on Traversable instances
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  * fixed cache when opcache is installed but disabled
15
- * fixed PHP 7.4 compatibility
16
- * bumped the minimal PHP version to 5.5
 
 
17
 
18
- * 1.42.2 (2019-06-18)
 
 
19
 
20
- * Display partial output (PHP buffer) when an error occurs in debug mode
21
 
22
- * 1.42.1 (2019-06-04)
 
 
23
 
24
  * added support for "Twig\Markup" instances in the "in" test (again)
25
  * allowed string operators as variables names in assignments
 
26
 
27
- * 1.42.0 (2019-05-31)
28
 
 
 
 
 
 
 
 
29
  * fixed the "filter" filter when the argument is \Traversable but does not implement \Iterator (\SimpleXmlElement for instance)
30
  * fixed a PHP fatal error when calling a macro imported in a block in a nested block
31
  * fixed a PHP fatal error when calling a macro imported in the template in another macro
32
  * fixed wrong error message on "import" and "from"
33
 
34
- * 1.41.0 (2019-05-14)
35
 
36
- * fixed support for PHP 7.4
37
  * added "filter", "map", and "reduce" filters (and support for arrow functions)
38
  * fixed partial output leak when a PHP fatal error occurs
39
  * optimized context access on PHP 7.4
40
 
41
- * 1.40.1 (2019-04-29)
42
-
43
- * fixed regression in NodeTraverser
44
-
45
- * 1.40.0 (2019-04-28)
46
 
 
47
  * allowed Twig\NodeVisitor\NodeVisitorInterface::leaveNode() to return "null" instead of "false" (same meaning)
 
48
  * added the "apply" tag as a replacement for the "filter" tag
49
  * allowed Twig\Loader\FilesystemLoader::findTemplate() to return "null" instead of "false" (same meaning)
50
  * added support for "Twig\Markup" instances in the "in" test
51
- * fixed Lexer when using custom options containing the # char
52
  * fixed "import" when macros are stored in a template string
 
 
53
 
54
- * 1.39.1 (2019-04-16)
55
 
56
  * fixed EscaperNodeVisitor
 
 
57
 
58
- * 1.39.0 (2019-04-16)
59
 
60
  * added Traversable support for the length filter
61
  * fixed some wrong location in error messages
@@ -65,28 +212,30 @@
65
  * fixed the "with" behavior to always include the globals (for consistency with the "include" and "embed" tags)
66
  * fixed "include" with "ignore missing" when an error loading occurs in the included template
67
  * added support for a new whitespace trimming option ({%~ ~%}, {{~ ~}}, {#~ ~#})
 
68
 
69
- * 1.38.4 (2019-03-23)
70
 
 
71
  * fixed CheckToStringNode implementation (broken when a function/filter is variadic)
72
 
73
- * 1.38.3 (2019-03-21)
74
 
75
  * fixed the spaceless filter so that it behaves like the spaceless tag
76
  * fixed BC break on Environment::resolveTemplate()
77
- * fixed the bundled Autoloader to also load namespaced classes
78
  * allowed Traversable objects to be used in the "with" tag
79
  * allowed Traversable objects to be used in the "with" argument of the "include" and "embed" tags
80
 
81
- * 1.38.2 (2019-03-12)
82
 
83
  * added TemplateWrapper::getTemplateName()
84
 
85
- * 1.38.1 (2019-03-12)
86
 
87
  * fixed class aliases
88
 
89
- * 1.38.0 (2019-03-12)
90
 
91
  * fixed sandbox security issue (under some circumstances, calling the
92
  __toString() method on an object was possible even if not allowed by the
@@ -94,31 +243,41 @@
94
  * fixed batch filter clobbers array keys when fill parameter is used
95
  * added preserveKeys support for the batch filter
96
  * fixed "embed" support when used from "template_from_string"
 
97
  * added the possibility to pass a TemplateWrapper to Twig\Environment::load()
 
98
  * improved the performance of the sandbox
 
99
  * added a spaceless filter
100
  * added max value to the "random" function
 
 
 
101
  * made namespace classes the default classes (PSR-0 ones are aliases now)
102
- * removed duplicated directory separator in FilesystemLoader
103
  * added Twig\Loader\ChainLoader::getLoaders()
 
 
 
 
104
  * changed internal code to use the namespaced classes as much as possible
 
105
 
106
- * 1.37.1 (2019-01-14)
107
 
108
  * fixed regression (key exists check for non ArrayObject objects)
109
- * fixed logic in TemplateWrapper
110
 
111
- * 1.37.0 (2019-01-14)
112
 
113
  * fixed ArrayObject access with a null value
114
  * fixed embedded templates starting with a BOM
115
  * fixed using a Twig_TemplateWrapper instance as an argument to extends
 
 
116
  * switched generated code to use the PHP short array notation
117
- * dropped PHP 5.3 support
118
  * fixed float representation in compiled templates
119
  * added a second argument to the join filter (last separator configuration)
120
 
121
- * 1.36.0 (2018-12-16)
122
 
123
  * made sure twig_include returns a string
124
  * fixed multi-byte UFT-8 in escape('html_attr')
@@ -127,74 +286,84 @@
127
  * fixed GlobalsInterface extended class
128
  * fixed filesystem loader throwing an exception instead of returning false
129
 
130
- * 1.35.4 (2018-07-13)
131
 
132
- * ensured that syntax errors are triggered with the right line
 
133
  * added the Symfony ctype polyfill as a dependency
 
 
 
134
  * "js" filter now produces valid JSON
135
 
136
- * 1.35.3 (2018-03-20)
137
 
 
 
 
 
 
 
138
  * fixed block names unicity
139
  * fixed counting children of SimpleXMLElement objects
140
  * added missing else clause to avoid infinite loops
141
  * fixed .. (range operator) in sandbox policy
142
 
143
- * 1.35.2 (2018-03-03)
144
 
145
  * fixed a regression in the way the profiler is registered in templates
146
 
147
- * 1.35.1 (2018-03-02)
148
 
 
 
149
  * added an exception when using "===" instead of "same as"
150
  * fixed possible array to string conversion concealing actual error
151
  * made variable names deterministic in compiled templates
152
  * fixed length filter when passing an instance of IteratorAggregate
153
  * fixed Environment::resolveTemplate to accept instances of TemplateWrapper
154
 
155
- * 1.35.0 (2017-09-27)
156
 
157
  * added Twig_Profiler_Profile::reset()
158
  * fixed use TokenParser to return an empty Node
159
  * added RuntimeExtensionInterface
160
  * added circular reference detection when loading templates
161
-
162
- * 1.34.4 (2017-07-04)
163
-
164
  * added support for runtime loaders in IntegrationTestCase
165
  * fixed deprecation when using Twig_Profiler_Dumper_Html
 
166
 
167
- * 1.34.3 (2017-06-07)
168
 
169
  * fixed namespaces introduction
170
 
171
- * 1.34.2 (2017-06-05)
172
 
173
  * fixed namespaces introduction
174
 
175
- * 1.34.1 (2017-06-05)
176
 
177
  * fixed namespaces introduction
178
 
179
- * 1.34.0 (2017-06-05)
180
 
181
  * added support for PHPUnit 6 when testing extensions
182
  * fixed PHP 7.2 compatibility
183
  * fixed template name generation in Twig_Environment::createTemplate()
184
  * removed final tag on Twig_TokenParser_Include
185
- * added namespaced aliases for all (non-deprecated) classes and interfaces
186
  * dropped HHVM support
187
- * dropped PHP 5.2 support
 
188
 
189
- * 1.33.2 (2017-04-20)
190
 
191
  * fixed edge case in the method cache for Twig attributes
192
 
193
- * 1.33.1 (2017-04-18)
194
 
195
  * fixed the empty() test
196
 
197
- * 1.33.0 (2017-03-22)
198
 
199
  * fixed a race condition handling when writing cache files
200
  * "length" filter now returns string length when applied to an object that does
@@ -202,937 +371,35 @@
202
  * "empty" test will now consider the return value of the __toString() method for
203
  objects implement __toString() but not \Countable
204
  * fixed JS escaping for unicode characters with higher code points
 
205
 
206
- * 1.32.0 (2017-02-26)
207
 
208
- * fixed deprecation notice in Twig_Util_DeprecationCollector
209
  * added a PSR-11 compatible runtime loader
210
  * added `side` argument to `trim` to allow left or right trimming only.
211
 
212
- * 1.31.0 (2017-01-11)
213
 
 
214
  * added Twig_NodeCaptureInterface for nodes that capture all output
215
- * fixed marking the environment as initialized too early
216
- * fixed C89 compat for the C extension
217
- * turned fatal error into exception when a previously generated cache is corrupted
218
- * fixed offline cache warm-ups for embedded templates
219
-
220
- * 1.30.0 (2016-12-23)
221
-
222
- * added Twig_FactoryRuntimeLoader
223
- * deprecated function/test/filter/tag overriding
224
- * deprecated the "disable_c_ext" attribute on Twig_Node_Expression_GetAttr
225
-
226
- * 1.29.0 (2016-12-13)
227
-
228
- * fixed sandbox being left enabled if an exception is thrown while rendering
229
- * marked some classes as being final (via @final)
230
- * made Twig_Error report real source path when possible
231
- * added support for {{ _self }} to provide an upgrade path from 1.x to 2.0 (replaces {{ _self.templateName }})
232
- * deprecated silent display of undefined blocks
233
- * deprecated support for mbstring.func_overload != 0
234
-
235
- * 1.28.2 (2016-11-23)
236
-
237
- * fixed precedence between getFoo() and isFoo() in Twig_Template::getAttribute()
238
- * improved a deprecation message
239
-
240
- * 1.28.1 (2016-11-18)
241
-
242
- * fixed block() function when used with a template argument
243
-
244
- * 1.28.0 (2016-11-17)
245
-
246
- * added support for the PHP 7 null coalescing operator for the ?? Twig implementation
247
- * exposed a way to access template data and methods in a portable way
248
- * changed context access to use the PHP 7 null coalescing operator when available
249
- * added the "with" tag
250
- * added support for a custom template on the block() function
251
- * added "is defined" support for block() and constant()
252
- * optimized the way attributes are fetched
253
-
254
- * 1.27.0 (2016-10-25)
255
-
256
- * deprecated Twig_Parser::getEnvironment()
257
- * deprecated Twig_Parser::addHandler() and Twig_Parser::addNodeVisitor()
258
- * deprecated Twig_Compiler::addIndentation()
259
- * fixed regression when registering two extensions having the same class name
260
- * deprecated Twig_LoaderInterface::getSource() (implement Twig_SourceContextLoaderInterface instead)
261
- * fixed the filesystem loader with relative paths
262
- * deprecated Twig_Node::getLine() in favor of Twig_Node::getTemplateLine()
263
- * deprecated Twig_Template::getSource() in favor of Twig_Template::getSourceContext()
264
- * deprecated Twig_Node::getFilename() in favor of Twig_Node::getTemplateName()
265
- * deprecated the "filename" escaping strategy (use "name" instead)
266
- * added Twig_Source to hold information about the original template
267
- * deprecated Twig_Error::getTemplateFile() and Twig_Error::setTemplateFile() in favor of Twig_Error::getTemplateName() and Twig_Error::setTemplateName()
268
- * deprecated Parser::getFilename()
269
- * fixed template paths when a template name contains a protocol like vfs://
270
- * improved debugging with Twig_Sandbox_SecurityError exceptions for disallowed methods and properties
271
-
272
- * 1.26.1 (2016-10-05)
273
-
274
- * removed template source code from generated template classes when debug is disabled
275
- * fixed default implementation of Twig_Template::getDebugInfo() for better BC
276
- * fixed regression on static calls for functions/filters/tests
277
-
278
- * 1.26.0 (2016-10-02)
279
-
280
- * added template cache invalidation based on more environment options
281
- * added a missing deprecation notice
282
- * fixed template paths when a template is stored in a PHAR file
283
- * allowed filters/functions/tests implementation to use a different class than the extension they belong to
284
- * deprecated Twig_ExtensionInterface::getName()
285
-
286
- * 1.25.0 (2016-09-21)
287
-
288
- * changed the way we store template source in template classes
289
- * removed usage of realpath in cache keys
290
- * fixed Twig cache sharing when used with different versions of PHP
291
- * removed embed parent workaround for simple use cases
292
- * deprecated the ability to store non Node instances in Node::$nodes
293
- * deprecated Twig_Environment::getLexer(), Twig_Environment::getParser(), Twig_Environment::getCompiler()
294
- * deprecated Twig_Compiler::getFilename()
295
-
296
- * 1.24.2 (2016-09-01)
297
-
298
- * fixed static callables
299
- * fixed a potential PHP warning when loading the cache
300
- * fixed a case where the autoescaping does not work as expected
301
-
302
- * 1.24.1 (2016-05-30)
303
-
304
- * fixed reserved keywords (forbids true, false, null and none keywords for variables names)
305
- * fixed support for PHP7 (Throwable support)
306
- * marked the following methods as being internals on Twig_Environment:
307
- getFunctions(), getFilters(), getTests(), getFunction(), getFilter(), getTest(),
308
- getTokenParsers(), getTags(), getNodeVisitors(), getUnaryOperators(), getBinaryOperators(),
309
- getFunctions(), getFilters(), getGlobals(), initGlobals(), initExtensions(), and initExtension()
310
-
311
- * 1.24.0 (2016-01-25)
312
-
313
- * adding support for the ?? operator
314
- * fixed the defined test when used on a constant, a map, or a sequence
315
- * undeprecated _self (should only be used to get the template name, not the template instance)
316
- * fixed parsing on PHP7
317
-
318
- * 1.23.3 (2016-01-11)
319
-
320
- * fixed typo
321
-
322
- * 1.23.2 (2015-01-11)
323
-
324
- * added versions in deprecated messages
325
- * made file cache tolerant for trailing (back)slashes on directory configuration
326
- * deprecated unused Twig_Node_Expression_ExtensionReference class
327
-
328
- * 1.23.1 (2015-11-05)
329
-
330
- * fixed some exception messages which triggered PHP warnings
331
- * fixed BC on Twig_Test_NodeTestCase
332
-
333
- * 1.23.0 (2015-10-29)
334
-
335
- * deprecated the possibility to override an extension by registering another one with the same name
336
- * deprecated Twig_ExtensionInterface::getGlobals() (added Twig_Extension_GlobalsInterface for BC)
337
- * deprecated Twig_ExtensionInterface::initRuntime() (added Twig_Extension_InitRuntimeInterface for BC)
338
- * deprecated Twig_Environment::computeAlternatives()
339
-
340
- * 1.22.3 (2015-10-13)
341
-
342
- * fixed regression when using null as a cache strategy
343
- * improved performance when checking template freshness
344
- * fixed warnings when loaded templates do not exist
345
- * fixed template class name generation to prevent possible collisions
346
- * fixed logic for custom escapers to call them even on integers and null values
347
- * changed template cache names to take into account the Twig C extension
348
-
349
- * 1.22.2 (2015-09-22)
350
-
351
- * fixed a race condition in template loading
352
-
353
- * 1.22.1 (2015-09-15)
354
-
355
- * fixed regression in template_from_string
356
-
357
- * 1.22.0 (2015-09-13)
358
-
359
- * made Twig_Test_IntegrationTestCase more flexible
360
- * added an option to force PHP bytecode invalidation when writing a compiled template into the cache
361
- * fixed the profiler duration for the root node
362
- * changed template cache names to take into account enabled extensions
363
- * deprecated Twig_Environment::clearCacheFiles(), Twig_Environment::getCacheFilename(),
364
- Twig_Environment::writeCacheFile(), and Twig_Environment::getTemplateClassPrefix()
365
- * added a way to override the filesystem template cache system
366
- * added a way to get the original template source from Twig_Template
367
-
368
- * 1.21.2 (2015-09-09)
369
-
370
- * fixed variable names for the deprecation triggering code
371
- * fixed escaping strategy detection based on filename
372
- * added Traversable support for replace, merge, and sort
373
- * deprecated support for character by character replacement for the "replace" filter
374
-
375
- * 1.21.1 (2015-08-26)
376
-
377
- * fixed regression when using the deprecated Twig_Test_* classes
378
-
379
- * 1.21.0 (2015-08-24)
380
-
381
- * added deprecation notices for deprecated features
382
- * added a deprecation "framework" for filters/functions/tests and test fixtures
383
-
384
- * 1.20.0 (2015-08-12)
385
-
386
- * forbid access to the Twig environment from templates and internal parts of Twig_Template
387
- * fixed limited RCEs when in sandbox mode
388
- * deprecated Twig_Template::getEnvironment()
389
- * deprecated the _self variable for usage outside of the from and import tags
390
- * added Twig_BaseNodeVisitor to ease the compatibility of node visitors
391
- between 1.x and 2.x
392
-
393
- * 1.19.0 (2015-07-31)
394
-
395
- * fixed wrong error message when including an undefined template in a child template
396
- * added support for variadic filters, functions, and tests
397
- * added support for extra positional arguments in macros
398
- * added ignore_missing flag to the source function
399
- * fixed batch filter with zero items
400
- * deprecated Twig_Environment::clearTemplateCache()
401
- * fixed sandbox disabling when using the include function
402
-
403
- * 1.18.2 (2015-06-06)
404
-
405
- * fixed template/line guessing in exceptions for nested templates
406
- * optimized the number of inodes and the size of realpath cache when using the cache
407
-
408
- * 1.18.1 (2015-04-19)
409
-
410
- * fixed memory leaks in the C extension
411
- * deprecated Twig_Loader_String
412
- * fixed the slice filter when used with a SimpleXMLElement object
413
- * fixed filesystem loader when trying to load non-files (like directories)
414
-
415
- * 1.18.0 (2015-01-25)
416
-
417
- * fixed some error messages where the line was wrong (unknown variables or argument names)
418
- * added a new way to customize the main Module node (via empty nodes)
419
- * added Twig_Environment::createTemplate() to create a template from a string
420
- * added a profiler
421
- * fixed filesystem loader cache when different file paths are used for the same template
422
-
423
- * 1.17.0 (2015-01-14)
424
-
425
- * added a 'filename' autoescaping strategy, which dynamically chooses the
426
- autoescaping strategy for a template based on template file extension.
427
-
428
- * 1.16.3 (2014-12-25)
429
-
430
- * fixed regression for dynamic parent templates
431
- * fixed cache management with statcache
432
- * fixed a regression in the slice filter
433
-
434
- * 1.16.2 (2014-10-17)
435
-
436
- * fixed timezone on dates as strings
437
- * fixed 2-words test names when a custom node class is not used
438
- * fixed macros when using an argument named like a PHP super global (like GET or POST)
439
- * fixed date_modify when working with DateTimeImmutable
440
- * optimized for loops
441
- * fixed multi-byte characters handling in the split filter
442
- * fixed a regression in the in operator
443
- * fixed a regression in the slice filter
444
-
445
- * 1.16.1 (2014-10-10)
446
-
447
- * improved error reporting in a sandboxed template
448
- * fixed missing error file/line information under certain circumstances
449
- * fixed wrong error line number in some error messages
450
- * fixed the in operator to use strict comparisons
451
- * sped up the slice filter
452
- * fixed for mb function overload mb_substr acting different
453
- * fixed the attribute() function when passing a variable for the arguments
454
-
455
- * 1.16.0 (2014-07-05)
456
-
457
- * changed url_encode to always encode according to RFC 3986
458
- * fixed inheritance in a 'use'-hierarchy
459
- * removed the __toString policy check when the sandbox is disabled
460
- * fixed recursively calling blocks in templates with inheritance
461
-
462
- * 1.15.1 (2014-02-13)
463
-
464
- * fixed the conversion of the special '0000-00-00 00:00' date
465
- * added an error message when trying to import an undefined block from a trait
466
- * fixed a C extension crash when accessing defined but uninitialized property.
467
-
468
- * 1.15.0 (2013-12-06)
469
-
470
- * made ignoreStrictCheck in Template::getAttribute() works with __call() methods throwing BadMethodCallException
471
- * added min and max functions
472
- * added the round filter
473
- * fixed a bug that prevented the optimizers to be enabled/disabled selectively
474
- * fixed first and last filters for UTF-8 strings
475
- * added a source function to include the content of a template without rendering it
476
- * fixed the C extension sandbox behavior when get or set is prepend to method name
477
-
478
- * 1.14.2 (2013-10-30)
479
-
480
- * fixed error filename/line when an error occurs in an included file
481
- * allowed operators that contain whitespaces to have more than one whitespace
482
- * allowed tests to be made of 1 or 2 words (like "same as" or "divisible by")
483
-
484
- * 1.14.1 (2013-10-15)
485
-
486
- * made it possible to use named operators as variables
487
- * fixed the possibility to have a variable named 'matches'
488
- * added support for PHP 5.5 DateTimeInterface
489
-
490
- * 1.14.0 (2013-10-03)
491
-
492
- * fixed usage of the html_attr escaping strategy to avoid double-escaping with the html strategy
493
- * added new operators: ends with, starts with, and matches
494
- * fixed some compatibility issues with HHVM
495
- * added a way to add custom escaping strategies
496
- * fixed the C extension compilation on Windows
497
- * fixed the batch filter when using a fill argument with an exact match of elements to batch
498
- * fixed the filesystem loader cache when a template name exists in several namespaces
499
- * fixed template_from_string when the template includes or extends other ones
500
- * fixed a crash of the C extension on an edge case
501
-
502
- * 1.13.2 (2013-08-03)
503
-
504
- * fixed the error line number for an error occurs in and embedded template
505
- * fixed crashes of the C extension on some edge cases
506
-
507
- * 1.13.1 (2013-06-06)
508
-
509
- * added the possibility to ignore the filesystem constructor argument in Twig_Loader_Filesystem
510
- * fixed Twig_Loader_Chain::exists() for a loader which implements Twig_ExistsLoaderInterface
511
- * adjusted backtrace call to reduce memory usage when an error occurs
512
- * added support for object instances as the second argument of the constant test
513
- * fixed the include function when used in an assignment
514
-
515
- * 1.13.0 (2013-05-10)
516
-
517
- * fixed getting a numeric-like item on a variable ('09' for instance)
518
- * fixed getting a boolean or float key on an array, so it is consistent with PHP's array access:
519
- `{{ array[false] }}` behaves the same as `echo $array[false];` (equals `$array[0]`)
520
- * made the escape filter 20% faster for happy path (escaping string for html with UTF-8)
521
- * changed ☃ to § in tests
522
- * enforced usage of named arguments after positional ones
523
-
524
- * 1.12.3 (2013-04-08)
525
-
526
- * fixed a security issue in the filesystem loader where it was possible to include a template one
527
- level above the configured path
528
- * fixed fatal error that should be an exception when adding a filter/function/test too late
529
- * added a batch filter
530
- * added support for encoding an array as query string in the url_encode filter
531
-
532
- * 1.12.2 (2013-02-09)
533
-
534
- * fixed the timezone used by the date filter and function when the given date contains a timezone (like 2010-01-28T15:00:00+02:00)
535
- * fixed globals when getGlobals is called early on
536
- * added the first and last filter
537
-
538
- * 1.12.1 (2013-01-15)
539
-
540
- * added support for object instances as the second argument of the constant function
541
- * relaxed globals management to avoid a BC break
542
- * added support for {{ some_string[:2] }}
543
-
544
- * 1.12.0 (2013-01-08)
545
-
546
- * added verbatim as an alias for the raw tag to avoid confusion with the raw filter
547
- * fixed registration of tests and functions as anonymous functions
548
- * fixed globals management
549
-
550
- * 1.12.0-RC1 (2012-12-29)
551
-
552
- * added an include function (does the same as the include tag but in a more flexible way)
553
- * added the ability to use any PHP callable to define filters, functions, and tests
554
- * added a syntax error when using a loop variable that is not defined
555
- * added the ability to set default values for macro arguments
556
- * added support for named arguments for filters, tests, and functions
557
- * moved filters/functions/tests syntax errors to the parser
558
- * added support for extended ternary operator syntaxes
559
-
560
- * 1.11.1 (2012-11-11)
561
-
562
- * fixed debug info line numbering (was off by 2)
563
- * fixed escaping when calling a macro inside another one (regression introduced in 1.9.1)
564
- * optimized variable access on PHP 5.4
565
- * fixed a crash of the C extension when an exception was thrown from a macro called without being imported (using _self.XXX)
566
-
567
- * 1.11.0 (2012-11-07)
568
-
569
- * fixed macro compilation when a variable name is a PHP reserved keyword
570
- * changed the date filter behavior to always apply the default timezone, except if false is passed as the timezone
571
- * fixed bitwise operator precedences
572
- * added the template_from_string function
573
- * fixed default timezone usage for the date function
574
- * optimized the way Twig exceptions are managed (to make them faster)
575
- * added Twig_ExistsLoaderInterface (implementing this interface in your loader make the chain loader much faster)
576
-
577
- * 1.10.3 (2012-10-19)
578
-
579
- * fixed wrong template location in some error messages
580
- * reverted a BC break introduced in 1.10.2
581
- * added a split filter
582
-
583
- * 1.10.2 (2012-10-15)
584
-
585
- * fixed macro calls on PHP 5.4
586
-
587
- * 1.10.1 (2012-10-15)
588
-
589
- * made a speed optimization to macro calls when imported via the "import" tag
590
- * fixed C extension compilation on Windows
591
- * fixed a segfault in the C extension when using DateTime objects
592
-
593
- * 1.10.0 (2012-09-28)
594
-
595
- * extracted functional tests framework to make it reusable for third-party extensions
596
- * added namespaced templates support in Twig_Loader_Filesystem
597
- * added Twig_Loader_Filesystem::prependPath()
598
- * fixed an error when a token parser pass a closure as a test to the subparse() method
599
-
600
- * 1.9.2 (2012-08-25)
601
-
602
- * fixed the in operator for objects that contain circular references
603
- * fixed the C extension when accessing a public property of an object implementing the \ArrayAccess interface
604
-
605
- * 1.9.1 (2012-07-22)
606
-
607
- * optimized macro calls when auto-escaping is on
608
- * fixed wrong parent class for Twig_Function_Node
609
- * made Twig_Loader_Chain more explicit about problems
610
-
611
- * 1.9.0 (2012-07-13)
612
-
613
- * made the parsing independent of the template loaders
614
- * fixed exception trace when an error occurs when rendering a child template
615
- * added escaping strategies for CSS, URL, and HTML attributes
616
- * fixed nested embed tag calls
617
- * added the date_modify filter
618
-
619
- * 1.8.3 (2012-06-17)
620
-
621
- * fixed paths in the filesystem loader when passing a path that ends with a slash or a backslash
622
- * fixed escaping when a project defines a function named html or js
623
- * fixed chmod mode to apply the umask correctly
624
-
625
- * 1.8.2 (2012-05-30)
626
-
627
- * added the abs filter
628
- * fixed a regression when using a number in template attributes
629
- * fixed compiler when mbstring.func_overload is set to 2
630
- * fixed DateTimeZone support in date filter
631
-
632
- * 1.8.1 (2012-05-17)
633
-
634
- * fixed a regression when dealing with SimpleXMLElement instances in templates
635
- * fixed "is_safe" value for the "dump" function when "html_errors" is not defined in php.ini
636
- * switched to use mbstring whenever possible instead of iconv (you might need to update your encoding as mbstring and iconv encoding names sometimes differ)
637
-
638
- * 1.8.0 (2012-05-08)
639
-
640
- * enforced interface when adding tests, filters, functions, and node visitors from extensions
641
- * fixed a side-effect of the date filter where the timezone might be changed
642
- * simplified usage of the autoescape tag; the only (optional) argument is now the escaping strategy or false (with a BC layer)
643
- * added a way to dynamically change the auto-escaping strategy according to the template "filename"
644
- * changed the autoescape option to also accept a supported escaping strategy (for BC, true is equivalent to html)
645
- * added an embed tag
646
-
647
- * 1.7.0 (2012-04-24)
648
-
649
- * fixed a PHP warning when using CIFS
650
- * fixed template line number in some exceptions
651
- * added an iterable test
652
- * added an error when defining two blocks with the same name in a template
653
- * added the preserves_safety option for filters
654
- * fixed a PHP notice when trying to access a key on a non-object/array variable
655
- * enhanced error reporting when the template file is an instance of SplFileInfo
656
- * added Twig_Environment::mergeGlobals()
657
- * added compilation checks to avoid misuses of the sandbox tag
658
- * fixed filesystem loader freshness logic for high traffic websites
659
- * fixed random function when charset is null
660
-
661
- * 1.6.5 (2012-04-11)
662
-
663
- * fixed a regression when a template only extends another one without defining any blocks
664
-
665
- * 1.6.4 (2012-04-02)
666
-
667
- * fixed PHP notice in Twig_Error::guessTemplateLine() introduced in 1.6.3
668
- * fixed performance when compiling large files
669
- * optimized parent template creation when the template does not use dynamic inheritance
670
-
671
- * 1.6.3 (2012-03-22)
672
-
673
- * fixed usage of Z_ADDREF_P for PHP 5.2 in the C extension
674
- * fixed compilation of numeric values used in templates when using a locale where the decimal separator is not a dot
675
- * made the strategy used to guess the real template file name and line number in exception messages much faster and more accurate
676
-
677
- * 1.6.2 (2012-03-18)
678
-
679
- * fixed sandbox mode when used with inheritance
680
- * added preserveKeys support for the slice filter
681
- * fixed the date filter when a DateTime instance is passed with a specific timezone
682
- * added a trim filter
683
-
684
- * 1.6.1 (2012-02-29)
685
-
686
- * fixed Twig C extension
687
- * removed the creation of Twig_Markup instances when not needed
688
- * added a way to set the default global timezone for dates
689
- * fixed the slice filter on strings when the length is not specified
690
- * fixed the creation of the cache directory in case of a race condition
691
-
692
- * 1.6.0 (2012-02-04)
693
-
694
- * fixed raw blocks when used with the whitespace trim option
695
- * made a speed optimization to macro calls when imported via the "from" tag
696
- * fixed globals, parsers, visitors, filters, tests, and functions management in Twig_Environment when a new one or new extension is added
697
- * fixed the attribute function when passing arguments
698
- * added slice notation support for the [] operator (syntactic sugar for the slice operator)
699
- * added a slice filter
700
- * added string support for the reverse filter
701
- * fixed the empty test and the length filter for Twig_Markup instances
702
- * added a date function to ease date comparison
703
- * fixed unary operators precedence
704
- * added recursive parsing support in the parser
705
- * added string and integer handling for the random function
706
-
707
- * 1.5.1 (2012-01-05)
708
-
709
- * fixed a regression when parsing strings
710
-
711
- * 1.5.0 (2012-01-04)
712
-
713
- * added Traversable objects support for the join filter
714
-
715
- * 1.5.0-RC2 (2011-12-30)
716
-
717
- * added a way to set the default global date interval format
718
- * fixed the date filter for DateInterval instances (setTimezone() does not exist for them)
719
- * refactored Twig_Template::display() to ease its extension
720
- * added a number_format filter
721
-
722
- * 1.5.0-RC1 (2011-12-26)
723
-
724
- * removed the need to quote hash keys
725
- * allowed hash keys to be any expression
726
- * added a do tag
727
- * added a flush tag
728
- * added support for dynamically named filters and functions
729
- * added a dump function to help debugging templates
730
- * added a nl2br filter
731
- * added a random function
732
- * added a way to change the default format for the date filter
733
- * fixed the lexer when an operator ending with a letter ends a line
734
- * added string interpolation support
735
- * enhanced exceptions for unknown filters, functions, tests, and tags
736
-
737
- * 1.4.0 (2011-12-07)
738
-
739
- * fixed lexer when using big numbers (> PHP_INT_MAX)
740
- * added missing preserveKeys argument to the reverse filter
741
- * fixed macros containing filter tag calls
742
-
743
- * 1.4.0-RC2 (2011-11-27)
744
-
745
- * removed usage of Reflection in Twig_Template::getAttribute()
746
- * added a C extension that can optionally replace Twig_Template::getAttribute()
747
- * added negative timestamp support to the date filter
748
-
749
- * 1.4.0-RC1 (2011-11-20)
750
-
751
- * optimized variable access when using PHP 5.4
752
- * changed the precedence of the .. operator to be more consistent with languages that implements such a feature like Ruby
753
- * added an Exception to Twig_Loader_Array::isFresh() method when the template does not exist to be consistent with other loaders
754
- * added Twig_Function_Node to allow more complex functions to have their own Node class
755
- * added Twig_Filter_Node to allow more complex filters to have their own Node class
756
- * added Twig_Test_Node to allow more complex tests to have their own Node class
757
- * added a better error message when a template is empty but contain a BOM
758
- * fixed "in" operator for empty strings
759
- * fixed the "defined" test and the "default" filter (now works with more than one call (foo.bar.foo) and for both values of the strict_variables option)
760
- * changed the way extensions are loaded (addFilter/addFunction/addGlobal/addTest/addNodeVisitor/addTokenParser/addExtension can now be called in any order)
761
- * added Twig_Environment::display()
762
- * made the escape filter smarter when the encoding is not supported by PHP
763
- * added a convert_encoding filter
764
- * moved all node manipulations outside the compile() Node method
765
- * made several speed optimizations
766
-
767
- * 1.3.0 (2011-10-08)
768
-
769
- no changes
770
 
771
- * 1.3.0-RC1 (2011-10-04)
772
-
773
- * added an optimization for the parent() function
774
- * added cache reloading when auto_reload is true and an extension has been modified
775
- * added the possibility to force the escaping of a string already marked as safe (instance of Twig_Markup)
776
- * allowed empty templates to be used as traits
777
- * added traits support for the "parent" function
778
-
779
- * 1.2.0 (2011-09-13)
780
-
781
- no changes
782
-
783
- * 1.2.0-RC1 (2011-09-10)
784
-
785
- * enhanced the exception when a tag remains unclosed
786
- * added support for empty Countable objects for the "empty" test
787
- * fixed algorithm that determines if a template using inheritance is valid (no output between block definitions)
788
- * added better support for encoding problems when escaping a string (available as of PHP 5.4)
789
- * added a way to ignore a missing template when using the "include" tag ({% include "foo" ignore missing %})
790
- * added support for an array of templates to the "include" and "extends" tags ({% include ['foo', 'bar'] %})
791
- * added support for bitwise operators in expressions
792
- * added the "attribute" function to allow getting dynamic attributes on variables
793
- * added Twig_Loader_Chain
794
- * added Twig_Loader_Array::setTemplate()
795
- * added an optimization for the set tag when used to capture a large chunk of static text
796
- * changed name regex to match PHP one "[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*" (works for blocks, tags, functions, filters, and macros)
797
- * removed the possibility to use the "extends" tag from a block
798
- * added "if" modifier support to "for" loops
799
-
800
- * 1.1.2 (2011-07-30)
801
-
802
- * fixed json_encode filter on PHP 5.2
803
- * fixed regression introduced in 1.1.1 ({{ block(foo|lower) }})
804
- * fixed inheritance when using conditional parents
805
- * fixed compilation of templates when the body of a child template is not empty
806
- * fixed output when a macro throws an exception
807
- * fixed a parsing problem when a large chunk of text is enclosed in a comment tag
808
- * added PHPDoc for all Token parsers and Core extension functions
809
-
810
- * 1.1.1 (2011-07-17)
811
-
812
- * added a performance optimization in the Optimizer (also helps to lower the number of nested level calls)
813
- * made some performance improvement for some edge cases
814
-
815
- * 1.1.0 (2011-06-28)
816
-
817
- * fixed json_encode filter
818
-
819
- * 1.1.0-RC3 (2011-06-24)
820
-
821
- * fixed method case-sensitivity when using the sandbox mode
822
- * added timezone support for the date filter
823
- * fixed possible security problems with NUL bytes
824
-
825
- * 1.1.0-RC2 (2011-06-16)
826
-
827
- * added an exception when the template passed to "use" is not a string
828
- * made 'a.b is defined' not throw an exception if a is not defined (in strict mode)
829
- * added {% line \d+ %} directive
830
-
831
- * 1.1.0-RC1 (2011-05-28)
832
-
833
- Flush your cache after upgrading.
834
-
835
- * fixed date filter when using a timestamp
836
- * fixed the defined test for some cases
837
- * fixed a parsing problem when a large chunk of text is enclosed in a raw tag
838
- * added support for horizontal reuse of template blocks (see docs for more information)
839
- * added whitespace control modifier to all tags (see docs for more information)
840
- * added null as an alias for none (the null test is also an alias for the none test now)
841
- * made TRUE, FALSE, NONE equivalent to their lowercase counterparts
842
- * wrapped all compilation and runtime exceptions with Twig_Error_Runtime and added logic to guess the template name and line
843
- * moved display() method to Twig_Template (generated templates should now use doDisplay() instead)
844
-
845
- * 1.0.0 (2011-03-27)
846
-
847
- * fixed output when using mbstring
848
- * fixed duplicate call of methods when using the sandbox
849
- * made the charset configurable for the escape filter
850
-
851
- * 1.0.0-RC2 (2011-02-21)
852
-
853
- * changed the way {% set %} works when capturing (the content is now marked as safe)
854
- * added support for macro name in the endmacro tag
855
- * make Twig_Error compatible with PHP 5.3.0 >
856
- * fixed an infinite loop on some Windows configurations
857
- * fixed the "length" filter for numbers
858
- * fixed Template::getAttribute() as properties in PHP are case sensitive
859
- * removed coupling between Twig_Node and Twig_Template
860
- * fixed the ternary operator precedence rule
861
-
862
- * 1.0.0-RC1 (2011-01-09)
863
-
864
- Backward incompatibilities:
865
-
866
- * the "items" filter, which has been deprecated for quite a long time now, has been removed
867
- * the "range" filter has been converted to a function: 0|range(10) -> range(0, 10)
868
- * the "constant" filter has been converted to a function: {{ some_date|date('DATE_W3C'|constant) }} -> {{ some_date|date(constant('DATE_W3C')) }}
869
- * the "cycle" filter has been converted to a function: {{ ['odd', 'even']|cycle(i) }} -> {{ cycle(['odd', 'even'], i) }}
870
- * the "for" tag does not support "joined by" anymore
871
- * the "autoescape" first argument is now "true"/"false" (instead of "on"/"off")
872
- * the "parent" tag has been replaced by a "parent" function ({{ parent() }} instead of {% parent %})
873
- * the "display" tag has been replaced by a "block" function ({{ block('title') }} instead of {% display title %})
874
- * removed the grammar and simple token parser (moved to the Twig Extensions repository)
875
-
876
- Changes:
877
-
878
- * added "needs_context" option for filters and functions (the context is then passed as a first argument)
879
- * added global variables support
880
- * made macros return their value instead of echoing directly (fixes calling a macro in sandbox mode)
881
- * added the "from" tag to import macros as functions
882
- * added support for functions (a function is just syntactic sugar for a getAttribute() call)
883
- * made macros callable when sandbox mode is enabled
884
- * added an exception when a macro uses a reserved name
885
- * the "default" filter now uses the "empty" test instead of just checking for null
886
- * added the "empty" test
887
-
888
- * 0.9.10 (2010-12-16)
889
-
890
- Backward incompatibilities:
891
-
892
- * The Escaper extension is enabled by default, which means that all displayed
893
- variables are now automatically escaped. You can revert to the previous
894
- behavior by removing the extension via $env->removeExtension('escaper')
895
- or just set the 'autoescape' option to 'false'.
896
- * removed the "without loop" attribute for the "for" tag (not needed anymore
897
- as the Optimizer take care of that for most cases)
898
- * arrays and hashes have now a different syntax
899
- * arrays keep the same syntax with square brackets: [1, 2]
900
- * hashes now use curly braces (["a": "b"] should now be written as {"a": "b"})
901
- * support for "arrays with keys" and "hashes without keys" is not supported anymore ([1, "foo": "bar"] or {"foo": "bar", 1})
902
- * the i18n extension is now part of the Twig Extensions repository
903
-
904
- Changes:
905
-
906
- * added the merge filter
907
- * removed 'is_escaper' option for filters (a left over from the previous version) -- you must use 'is_safe' now instead
908
- * fixed usage of operators as method names (like is, in, and not)
909
- * changed the order of execution for node visitors
910
- * fixed default() filter behavior when used with strict_variables set to on
911
- * fixed filesystem loader compatibility with PHAR files
912
- * enhanced error messages when an unexpected token is parsed in an expression
913
- * fixed filename not being added to syntax error messages
914
- * added the autoescape option to enable/disable autoescaping
915
- * removed the newline after a comment (mimics PHP behavior)
916
- * added a syntax error exception when parent block is used on a template that does not extend another one
917
- * made the Escaper extension enabled by default
918
- * fixed sandbox extension when used with auto output escaping
919
- * fixed escaper when wrapping a Twig_Node_Print (the original class must be preserved)
920
- * added an Optimizer extension (enabled by default; optimizes "for" loops and "raw" filters)
921
- * added priority to node visitors
922
-
923
- * 0.9.9 (2010-11-28)
924
-
925
- Backward incompatibilities:
926
- * the self special variable has been renamed to _self
927
- * the odd and even filters are now tests:
928
- {{ foo|odd }} must now be written {{ foo is odd }}
929
- * the "safe" filter has been renamed to "raw"
930
- * in Node classes,
931
- sub-nodes are now accessed via getNode() (instead of property access)
932
- attributes via getAttribute() (instead of array access)
933
- * the urlencode filter had been renamed to url_encode
934
- * the include tag now merges the passed variables with the current context by default
935
- (the old behavior is still possible by adding the "only" keyword)
936
- * moved Exceptions to Twig_Error_* (Twig_SyntaxError/Twig_RuntimeError are now Twig_Error_Syntax/Twig_Error_Runtime)
937
- * removed support for {{ 1 < i < 3 }} (use {{ i > 1 and i < 3 }} instead)
938
- * the "in" filter has been removed ({{ a|in(b) }} should now be written {{ a in b }})
939
-
940
- Changes:
941
- * added file and line to Twig_Error_Runtime exceptions thrown from Twig_Template
942
- * changed trans tag to accept any variable for the plural count
943
- * fixed sandbox mode (__toString() method check was not enforced if called implicitly from complex statements)
944
- * added the ** (power) operator
945
- * changed the algorithm used for parsing expressions
946
- * added the spaceless tag
947
- * removed trim_blocks option
948
- * added support for is*() methods for attributes (foo.bar now looks for foo->getBar() or foo->isBar())
949
- * changed all exceptions to extend Twig_Error
950
- * fixed unary expressions ({{ not(1 or 0) }})
951
- * fixed child templates (with an extend tag) that uses one or more imports
952
- * added support for {{ 1 not in [2, 3] }} (more readable than the current {{ not (1 in [2, 3]) }})
953
- * escaping has been rewritten
954
- * the implementation of template inheritance has been rewritten
955
- (blocks can now be called individually and still work with inheritance)
956
- * fixed error handling for if tag when a syntax error occurs within a subparse process
957
- * added a way to implement custom logic for resolving token parsers given a tag name
958
- * fixed js escaper to be stricter (now uses a whilelist-based js escaper)
959
- * added the following filers: "constant", "trans", "replace", "json_encode"
960
- * added a "constant" test
961
- * fixed objects with __toString() not being autoescaped
962
- * fixed subscript expressions when calling __call() (methods now keep the case)
963
- * added "test" feature (accessible via the "is" operator)
964
- * removed the debug tag (should be done in an extension)
965
- * fixed trans tag when no vars are used in plural form
966
- * fixed race condition when writing template cache
967
- * added the special _charset variable to reference the current charset
968
- * added the special _context variable to reference the current context
969
- * renamed self to _self (to avoid conflict)
970
- * fixed Twig_Template::getAttribute() for protected properties
971
-
972
- * 0.9.8 (2010-06-28)
973
-
974
- Backward incompatibilities:
975
- * the trans tag plural count is now attached to the plural tag:
976
- old: `{% trans count %}...{% plural %}...{% endtrans %}`
977
- new: `{% trans %}...{% plural count %}...{% endtrans %}`
978
-
979
- * added a way to translate strings coming from a variable ({% trans var %})
980
- * fixed trans tag when used with the Escaper extension
981
- * fixed default cache umask
982
- * removed Twig_Template instances from the debug tag output
983
- * fixed objects with __isset() defined
984
- * fixed set tag when used with a capture
985
- * fixed type hinting for Twig_Environment::addFilter() method
986
-
987
- * 0.9.7 (2010-06-12)
988
-
989
- Backward incompatibilities:
990
- * changed 'as' to '=' for the set tag ({% set title as "Title" %} must now be {% set title = "Title" %})
991
- * removed the sandboxed attribute of the include tag (use the new sandbox tag instead)
992
- * refactored the Node system (if you have custom nodes, you will have to update them to use the new API)
993
-
994
- * added self as a special variable that refers to the current template (useful for importing macros from the current template)
995
- * added Twig_Template instance support to the include tag
996
- * added support for dynamic and conditional inheritance ({% extends some_var %} and {% extends standalone ? "minimum" : "base" %})
997
- * added a grammar sub-framework to ease the creation of custom tags
998
- * fixed the for tag for large arrays (some loop variables are now only available for arrays and objects that implement the Countable interface)
999
- * removed the Twig_Resource::resolveMissingFilter() method
1000
- * fixed the filter tag which did not apply filtering to included files
1001
- * added a bunch of unit tests
1002
- * added a bunch of phpdoc
1003
- * added a sandbox tag in the sandbox extension
1004
- * changed the date filter to support any date format supported by DateTime
1005
- * added strict_variable setting to throw an exception when an invalid variable is used in a template (disabled by default)
1006
- * added the lexer, parser, and compiler as arguments to the Twig_Environment constructor
1007
- * changed the cache option to only accepts an explicit path to a cache directory or false
1008
- * added a way to add token parsers, filters, and visitors without creating an extension
1009
- * added three interfaces: Twig_NodeInterface, Twig_TokenParserInterface, and Twig_FilterInterface
1010
- * changed the generated code to match the new coding standards
1011
- * fixed sandbox mode (__toString() method check was not enforced if called implicitly from a simple statement like {{ article }})
1012
- * added an exception when a child template has a non-empty body (as it is always ignored when rendering)
1013
-
1014
- * 0.9.6 (2010-05-12)
1015
-
1016
- * fixed variables defined outside a loop and for which the value changes in a for loop
1017
- * fixed the test suite for PHP 5.2 and older versions of PHPUnit
1018
- * added support for __call() in expression resolution
1019
- * fixed node visiting for macros (macros are now visited by visitors as any other node)
1020
- * fixed nested block definitions with a parent call (rarely useful but nonetheless supported now)
1021
- * added the cycle filter
1022
- * fixed the Lexer when mbstring.func_overload is used with an mbstring.internal_encoding different from ASCII
1023
- * added a long-syntax for the set tag ({% set foo %}...{% endset %})
1024
- * unit tests are now powered by PHPUnit
1025
- * added support for gettext via the `i18n` extension
1026
- * fixed twig_capitalize_string_filter() and fixed twig_length_filter() when used with UTF-8 values
1027
- * added a more useful exception if an if tag is not closed properly
1028
- * added support for escaping strategy in the autoescape tag
1029
- * fixed lexer when a template has a big chunk of text between/in a block
1030
-
1031
- * 0.9.5 (2010-01-20)
1032
-
1033
- As for any new release, don't forget to remove all cached templates after
1034
- upgrading.
1035
-
1036
- If you have defined custom filters, you MUST upgrade them for this release. To
1037
- upgrade, replace "array" with "new Twig_Filter_Function", and replace the
1038
- environment constant by the "needs_environment" option:
1039
-
1040
- // before
1041
- 'even' => array('twig_is_even_filter', false),
1042
- 'escape' => array('twig_escape_filter', true),
1043
-
1044
- // after
1045
- 'even' => new Twig_Filter_Function('twig_is_even_filter'),
1046
- 'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true)),
1047
-
1048
- If you have created NodeTransformer classes, you will need to upgrade them to
1049
- the new interface (please note that the interface is not yet considered
1050
- stable).
1051
-
1052
- * fixed list nodes that did not extend the Twig_NodeListInterface
1053
- * added the "without loop" option to the for tag (it disables the generation of the loop variable)
1054
- * refactored node transformers to node visitors
1055
- * fixed automatic-escaping for blocks
1056
- * added a way to specify variables to pass to an included template
1057
- * changed the automatic-escaping rules to be more sensible and more configurable in custom filters (the documentation lists all the rules)
1058
- * improved the filter system to allow object methods to be used as filters
1059
- * changed the Array and String loaders to actually make use of the cache mechanism
1060
- * included the default filter function definitions in the extension class files directly (Core, Escaper)
1061
- * added the // operator (like the floor() PHP function)
1062
- * added the .. operator (as a syntactic sugar for the range filter when the step is 1)
1063
- * added the in operator (as a syntactic sugar for the in filter)
1064
- * added the following filters in the Core extension: in, range
1065
- * added support for arrays (same behavior as in PHP, a mix between lists and dictionaries, arrays and hashes)
1066
- * enhanced some error messages to provide better feedback in case of parsing errors
1067
-
1068
- * 0.9.4 (2009-12-02)
1069
-
1070
- If you have custom loaders, you MUST upgrade them for this release: The
1071
- Twig_Loader base class has been removed, and the Twig_LoaderInterface has also
1072
- been changed (see the source code for more information or the documentation).
1073
-
1074
- * added support for DateTime instances for the date filter
1075
- * fixed loop.last when the array only has one item
1076
- * made it possible to insert newlines in tag and variable blocks
1077
- * fixed a bug when a literal '\n' were present in a template text
1078
- * fixed bug when the filename of a template contains */
1079
- * refactored loaders
1080
-
1081
- * 0.9.3 (2009-11-11)
1082
-
1083
- This release is NOT backward compatible with the previous releases.
1084
-
1085
- The loaders do not take the cache and autoReload arguments anymore. Instead,
1086
- the Twig_Environment class has two new options: cache and auto_reload.
1087
- Upgrading your code means changing this kind of code:
1088
-
1089
- $loader = new Twig_Loader_Filesystem('/path/to/templates', '/path/to/compilation_cache', true);
1090
- $twig = new Twig_Environment($loader);
1091
-
1092
- to something like this:
1093
-
1094
- $loader = new Twig_Loader_Filesystem('/path/to/templates');
1095
- $twig = new Twig_Environment($loader, array(
1096
- 'cache' => '/path/to/compilation_cache',
1097
- 'auto_reload' => true,
1098
- ));
1099
-
1100
- * deprecated the "items" filter as it is not needed anymore
1101
- * made cache and auto_reload options of Twig_Environment instead of arguments of Twig_Loader
1102
- * optimized template loading speed
1103
- * removed output when an error occurs in a template and render() is used
1104
- * made major speed improvements for loops (up to 300% on even the smallest loops)
1105
- * added properties as part of the sandbox mode
1106
- * added public properties support (obj.item can now be the item property on the obj object)
1107
- * extended set tag to support expression as value ({% set foo as 'foo' ~ 'bar' %} )
1108
- * fixed bug when \ was used in HTML
1109
-
1110
- * 0.9.2 (2009-10-29)
1111
-
1112
- * made some speed optimizations
1113
- * changed the cache extension to .php
1114
- * added a js escaping strategy
1115
- * added support for short block tag
1116
- * changed the filter tag to allow chained filters
1117
- * made lexer more flexible as you can now change the default delimiters
1118
- * added set tag
1119
- * changed default directory permission when cache dir does not exist (more secure)
1120
- * added macro support
1121
- * changed filters first optional argument to be a Twig_Environment instance instead of a Twig_Template instance
1122
- * made Twig_Autoloader::autoload() a static method
1123
- * avoid writing template file if an error occurs
1124
- * added $ escaping when outputting raw strings
1125
- * enhanced some error messages to ease debugging
1126
- * fixed empty cache files when the template contains an error
1127
-
1128
- * 0.9.1 (2009-10-14)
1129
-
1130
- * fixed a bug in PHP 5.2.6
1131
- * fixed numbers with one than one decimal
1132
- * added support for method calls with arguments ({{ foo.bar('a', 43) }})
1133
- * made small speed optimizations
1134
- * made minor tweaks to allow better extensibility and flexibility
1135
-
1136
- * 0.9.0 (2009-10-12)
1137
-
1138
- * Initial release
1
+ # 2.15.3 (2022-09-28)
2
 
3
+ * Fix a security issue on filesystem loader (possibility to load a template outside a configured directory)
4
+
5
+ # 2.15.2 (2022-08-12)
6
+
7
+ * Allow inherited magic method to still run with calling class
8
+ * Fix CallExpression::reflectCallable() throwing TypeError
9
+ * Fix typo in naming (currency_code)
10
+
11
+ # 2.15.1 (2022-05-17)
12
+
13
+ * Fix optimizing non-public named closures
14
+
15
+ # 2.15.0 (2022-05-15)
16
+
17
+ * Add support for named closures
18
+
19
+ # 2.14.13 (2022-04-06)
20
+
21
+ * Enable bytecode invalidation when auto_reload is enabled
22
+
23
+ # 2.14.12 (2022-03-25)
24
+
25
+ * Fix custom escapers when using multiple Twig environments
26
+ * Do not reuse internally generated variable names during parsing
27
+
28
+ # 2.14.11 (2022-02-04)
29
+
30
+ * Fix a security issue when in a sandbox: the `sort` filter must require a Closure for the `arrow` parameter
31
+ * Fix deprecation notice on `round`
32
+ * Fix call to deprecated `convertToHtml` method
33
+
34
+ # 2.14.10 (2022-01-03)
35
+
36
+ * Allow more null arguments when Twig expects a string (for better 8.1 support)
37
+
38
+ # 2.14.9 (2022-01-03)
39
+
40
+ * Allow null when Twig expects a string (for better 8.1 support)
41
+ * Add support for PHP 7.1 back
42
+ * Make some performance optimizations
43
+ * Allow Symfony translation contract v3+
44
+
45
+ # 2.14.8 (2021-11-25)
46
+
47
+ * Bump minimum supported Symfony component versions
48
+ * Fix a deprecated message
49
+
50
+ # 2.14.7 (2021-09-17)
51
+
52
+ * Allow Symfony 6
53
+ * Improve compatibility with PHP 8.1
54
+ * Explicitly specify the encoding for mb_ord in JS escaper
55
+
56
+ # 2.14.6 (2021-05-16)
57
+
58
+ * Revert "Throw a proper exception when a template name is an absolute path (as it has never been supported)"
59
+
60
+ # 2.14.5 (2021-05-12)
61
+
62
+ * Fix PHP 8.1 compatibility
63
+ * Throw a proper exception when a template name is an absolute path (as it has never been supported)
64
+
65
+ # 2.14.4 (2021-03-10)
66
+
67
+ * Add the slug filter
68
+
69
+ # 2.14.3 (2021-01-05)
70
+
71
+ * Fix extra bundle compat with older versions of Symfony
72
+
73
+ # 2.14.2 (2021-01-05)
74
+
75
+ * Fix "odd" not working for negative numbers
76
+
77
+ # 2.14.1 (2020-10-27)
78
+
79
+ * Fix "include(template_from_string())"
80
+
81
+ # 2.14.0 (2020-10-21)
82
+
83
+ * Fix sandbox support when using "include(template_from_string())"
84
+ * Make round brackets optional for one argument tests like "same as" or "divisible by"
85
+ * Add support for ES2015 style object initialisation shortcut { a } is the same as { 'a': a }
86
+ * Drop PHP 7.1 support
87
+
88
+ # 2.13.1 (2020-08-05)
89
+
90
+ * Fix sandbox not disabled if syntax error occurs within {% sandbox %} tag
91
+ * Fix a regression when not using a space before an operator
92
+ * Restrict callables to closures in filters
93
+ * Allow trailing commas in argument lists (in calls as well as definitions)
94
+
95
+ # 2.13.0 (2020-07-05)
96
+
97
+ * Fix options not taken into account when using "Michelf\MarkdownExtra"
98
+ * Fix "Twig\Extra\Intl\IntlExtension::getCountryName()" to accept "null" as a first argument
99
+ * Drop support for PHP 7.0
100
+ * Throw exception in case non-Traversable data is passed to "filter"
101
+ * Fix context optimization on PHP 7.4
102
+ * Fix PHP 8 compatibility
103
+ * Fix ambiguous syntax parsing
104
+
105
+ # 2.12.5 (2020-02-11)
106
+
107
+ * Add a check to ensure that iconv() is defined
108
+
109
+ # 2.12.4 (2020-02-11)
110
+
111
+ * Avoid exceptions when an intl resource is not found
112
  * Fix implementation of case-insensitivity for method names
113
 
114
+ # 2.12.3 (2019-12-28)
115
 
116
+ * fixed Symfony 5.0 support for the HTML extra extension
117
+ * fixed number formatter in Intl extra extension when using a formatter prototype
118
 
119
+ # 2.12.2 (2019-11-11)
120
 
121
+ * added supported for exponential numbers
122
+
123
+ # 2.12.1 (2019-10-17)
124
+
125
+ * added the String extension in the "extra" repositories: "u" filter
126
+
127
+ # 2.12.0 (2019-10-05)
128
+
129
+ * added the spaceship operator ("<=>"), useful when using an arrow function in the "sort" filter
130
+ * added support for an "arrow" function on the "sort" filter
131
+ * added the CssInliner extension in the "extra" repositories: "inline_css"
132
+ filter
133
+ * added the Inky extension in the "extra" repositories: "inky_to_html" filter
134
+ * added Intl extension in the "extra" repositories: "country_name",
135
+ "currency_name", "currency_symbol", "language_name", "locale_name",
136
+ "timezone_name", "format_currency", "format_number",
137
+ "format_*_number", "format_datetime", "format_date", and "format_time"
138
+ filters, and the "country_timezones" function
139
+ * added the Markdown extension in the "extra" repositories: "markdown_to_html",
140
+ and "html_to_markdown" filters
141
+ * added the HtmlExtension extension in the "extra" repositories: "date_uri"
142
+ filter, and "html_classes" function
143
+ * optimized "block('foo') ?? 'bar'"
144
+ * fixed the empty test on Traversable instances
145
+ * fixed array_key_exists() on objects
146
  * fixed cache when opcache is installed but disabled
147
+ * fixed using macros in arrow functions
148
+ * fixed split filter on edge case
149
+
150
+ # 2.11.3 (2019-06-18)
151
 
152
+ * display partial output (PHP buffer) when an error occurs in debug mode
153
+ * fixed the filter filter (allow the result to be used several times)
154
+ * fixed macro auto-import when a template contains only macros
155
 
156
+ # 2.11.2 (2019-06-05)
157
 
158
+ * fixed macro auto-import
159
+
160
+ # 2.11.1 (2019-06-04)
161
 
162
  * added support for "Twig\Markup" instances in the "in" test (again)
163
  * allowed string operators as variables names in assignments
164
+ * fixed support for macros defined in parent templates
165
 
166
+ # 2.11.0 (2019-05-31)
167
 
168
+ * added the possibility to register classes/interfaces as being safe for the escaper ("EscaperExtension::addSafeClass()")
169
+ * deprecated CoreExtension::setEscaper() and CoreExtension::getEscapers() in favor of the same methods on EscaperExtension
170
+ * macros are now auto-imported in the template they are defined (under the ``_self`` variable)
171
+ * added support for macros on "is defined" tests
172
+ * fixed macros "import" when using the same name in the parent and child templates
173
+ * fixed recursive macros
174
+ * macros imported "globally" in a template are now available in macros without re-importing them
175
  * fixed the "filter" filter when the argument is \Traversable but does not implement \Iterator (\SimpleXmlElement for instance)
176
  * fixed a PHP fatal error when calling a macro imported in a block in a nested block
177
  * fixed a PHP fatal error when calling a macro imported in the template in another macro
178
  * fixed wrong error message on "import" and "from"
179
 
180
+ # 2.10.0 (2019-05-14)
181
 
182
+ * deprecated "if" conditions on "for" tags
183
  * added "filter", "map", and "reduce" filters (and support for arrow functions)
184
  * fixed partial output leak when a PHP fatal error occurs
185
  * optimized context access on PHP 7.4
186
 
187
+ # 2.9.0 (2019-04-28)
 
 
 
 
188
 
189
+ * deprecated returning "false" to remove a Node from NodeVisitorInterface::leaveNode()
190
  * allowed Twig\NodeVisitor\NodeVisitorInterface::leaveNode() to return "null" instead of "false" (same meaning)
191
+ * deprecated the "filter" tag (use the "apply" tag instead)
192
  * added the "apply" tag as a replacement for the "filter" tag
193
  * allowed Twig\Loader\FilesystemLoader::findTemplate() to return "null" instead of "false" (same meaning)
194
  * added support for "Twig\Markup" instances in the "in" test
 
195
  * fixed "import" when macros are stored in a template string
196
+ * fixed Lexer when using custom options containing the # char
197
+ * added template line number to twig_get_attribute()
198
 
199
+ # 2.8.1 (2019-04-16)
200
 
201
  * fixed EscaperNodeVisitor
202
+ * deprecated passing a 3rd, 4th, and 5th arguments to the Sandbox exception classes
203
+ * deprecated Node::setTemplateName() in favor of Node::setSourceContext()
204
 
205
+ # 2.8.0 (2019-04-16)
206
 
207
  * added Traversable support for the length filter
208
  * fixed some wrong location in error messages
212
  * fixed the "with" behavior to always include the globals (for consistency with the "include" and "embed" tags)
213
  * fixed "include" with "ignore missing" when an error loading occurs in the included template
214
  * added support for a new whitespace trimming option ({%~ ~%}, {{~ ~}}, {#~ ~#})
215
+ * added the "column" filter
216
 
217
+ # 2.7.4 (2019-03-23)
218
 
219
+ * fixed variadic support
220
  * fixed CheckToStringNode implementation (broken when a function/filter is variadic)
221
 
222
+ # 2.7.3 (2019-03-21)
223
 
224
  * fixed the spaceless filter so that it behaves like the spaceless tag
225
  * fixed BC break on Environment::resolveTemplate()
226
+ * allowed Traversable objects to be used in the "with" tag
227
  * allowed Traversable objects to be used in the "with" tag
228
  * allowed Traversable objects to be used in the "with" argument of the "include" and "embed" tags
229
 
230
+ # 2.7.2 (2019-03-12)
231
 
232
  * added TemplateWrapper::getTemplateName()
233
 
234
+ # 2.7.1 (2019-03-12)
235
 
236
  * fixed class aliases
237
 
238
+ # 2.7.0 (2019-03-12)
239
 
240
  * fixed sandbox security issue (under some circumstances, calling the
241
  __toString() method on an object was possible even if not allowed by the
243
  * fixed batch filter clobbers array keys when fill parameter is used
244
  * added preserveKeys support for the batch filter
245
  * fixed "embed" support when used from "template_from_string"
246
+ * deprecated passing a Twig\Template to Twig\Environment::load()/Twig\Environment::resolveTemplate()
247
  * added the possibility to pass a TemplateWrapper to Twig\Environment::load()
248
+ * marked Twig\Environment::getTemplateClass() as internal (implementation detail)
249
  * improved the performance of the sandbox
250
+ * deprecated the spaceless tag
251
  * added a spaceless filter
252
  * added max value to the "random" function
253
+ * deprecated Twig\Extension\InitRuntimeInterface
254
+ * deprecated Twig\Loader\ExistsLoaderInterface
255
+ * deprecated PSR-0 classes in favor of namespaced ones
256
  * made namespace classes the default classes (PSR-0 ones are aliases now)
 
257
  * added Twig\Loader\ChainLoader::getLoaders()
258
+ * removed duplicated directory separator in FilesystemLoader
259
+ * deprecated the "base_template_class" option on Twig\Environment
260
+ * deprecated the Twig\Environment::getBaseTemplateClass() and
261
+ Twig\Environment::setBaseTemplateClass() methods
262
  * changed internal code to use the namespaced classes as much as possible
263
+ * deprecated Twig_Parser::isReservedMacroName()
264
 
265
+ # 2.6.2 (2019-01-14)
266
 
267
  * fixed regression (key exists check for non ArrayObject objects)
 
268
 
269
+ # 2.6.1 (2019-01-14)
270
 
271
  * fixed ArrayObject access with a null value
272
  * fixed embedded templates starting with a BOM
273
  * fixed using a Twig_TemplateWrapper instance as an argument to extends
274
+ * fixed error location when calling an undefined block
275
+ * deprecated passing a string as a source on Twig_Error
276
  * switched generated code to use the PHP short array notation
 
277
  * fixed float representation in compiled templates
278
  * added a second argument to the join filter (last separator configuration)
279
 
280
+ # 2.6.0 (2018-12-16)
281
 
282
  * made sure twig_include returns a string
283
  * fixed multi-byte UFT-8 in escape('html_attr')
286
  * fixed GlobalsInterface extended class
287
  * fixed filesystem loader throwing an exception instead of returning false
288
 
289
+ # 2.5.0 (2018-07-13)
290
 
291
+ * deprecated using the spaceless tag at the root level of a child template (noop anyway)
292
+ * deprecated the possibility to define a block in a non-capturing block in a child template
293
  * added the Symfony ctype polyfill as a dependency
294
+ * fixed reporting the proper location for errors compiled in templates
295
+ * fixed the error handling for the optimized extension-based function calls
296
+ * ensured that syntax errors are triggered with the right line
297
  * "js" filter now produces valid JSON
298
 
299
+ # 2.4.8 (2018-04-02)
300
 
301
+ * fixed a regression when using the "default" filter or the "defined" test on non-existing arrays
302
+
303
+ # 2.4.7 (2018-03-20)
304
+
305
+ * optimized runtime performance
306
+ * optimized parser performance by inlining the constant values
307
  * fixed block names unicity
308
  * fixed counting children of SimpleXMLElement objects
309
  * added missing else clause to avoid infinite loops
310
  * fixed .. (range operator) in sandbox policy
311
 
312
+ # 2.4.6 (2018-03-03)
313
 
314
  * fixed a regression in the way the profiler is registered in templates
315
 
316
+ # 2.4.5 (2018-03-02)
317
 
318
+ * optimized the performance of calling an extension method at runtime
319
+ * optimized the performance of the dot operator for array and method calls
320
  * added an exception when using "===" instead of "same as"
321
  * fixed possible array to string conversion concealing actual error
322
  * made variable names deterministic in compiled templates
323
  * fixed length filter when passing an instance of IteratorAggregate
324
  * fixed Environment::resolveTemplate to accept instances of TemplateWrapper
325
 
326
+ # 2.4.4 (2017-09-27)
327
 
328
  * added Twig_Profiler_Profile::reset()
329
  * fixed use TokenParser to return an empty Node
330
  * added RuntimeExtensionInterface
331
  * added circular reference detection when loading templates
 
 
 
332
  * added support for runtime loaders in IntegrationTestCase
333
  * fixed deprecation when using Twig_Profiler_Dumper_Html
334
+ * removed @final from Twig_Profiler_Dumper_Text
335
 
336
+ # 2.4.3 (2017-06-07)
337
 
338
  * fixed namespaces introduction
339
 
340
+ # 2.4.2 (2017-06-05)
341
 
342
  * fixed namespaces introduction
343
 
344
+ # 2.4.1 (2017-06-05)
345
 
346
  * fixed namespaces introduction
347
 
348
+ # 2.4.0 (2017-06-05)
349
 
350
  * added support for PHPUnit 6 when testing extensions
351
  * fixed PHP 7.2 compatibility
352
  * fixed template name generation in Twig_Environment::createTemplate()
353
  * removed final tag on Twig_TokenParser_Include
 
354
  * dropped HHVM support
355
+ * added namespaced aliases for all (non-deprecated) classes and interfaces
356
+ * marked Twig_Filter, Twig_Function, Twig_Test, Twig_Node_Module and Twig_Profiler_Profile as final via the @final annotation
357
 
358
+ # 2.3.2 (2017-04-20)
359
 
360
  * fixed edge case in the method cache for Twig attributes
361
 
362
+ # 2.3.1 (2017-04-18)
363
 
364
  * fixed the empty() test
365
 
366
+ # 2.3.0 (2017-03-22)
367
 
368
  * fixed a race condition handling when writing cache files
369
  * "length" filter now returns string length when applied to an object that does
371
  * "empty" test will now consider the return value of the __toString() method for
372
  objects implement __toString() but not \Countable
373
  * fixed JS escaping for unicode characters with higher code points
374
+ * added error message when calling `parent()` in a block that doesn't exist in the parent template
375
 
376
+ # 2.2.0 (2017-02-26)
377
 
 
378
  * added a PSR-11 compatible runtime loader
379
  * added `side` argument to `trim` to allow left or right trimming only.
380
 
381
+ # 2.1.0 (2017-01-11)
382
 
383
+ * fixed twig_get_attribute()
384
  * added Twig_NodeCaptureInterface for nodes that capture all output
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
385
 
386
+ # 2.0.0 (2017-01-05)
387
+
388
+ * removed the C extension
389
+ * moved Twig_Environment::getAttribute() to twig_get_attribute()
390
+ * removed Twig_Environment::getLexer(), Twig_Environment::getParser(), Twig_Environment::getCompiler()
391
+ * removed Twig_Compiler::getFilename()
392
+ * added hasser support in Twig_Template::getAttribute()
393
+ * sped up the json_encode filter
394
+ * removed reserved macro names; all names can be used as macro
395
+ * removed Twig_Template::getEnvironment()
396
+ * changed _self variable to return the current template name
397
+ * made the loader a required argument of Twig_Environment constructor
398
+ * removed Twig_Environment::clearTemplateCache()
399
+ * removed Twig_Autoloader (use Composer instead)
400
+ * removed `true` as an equivalent to `html` for the auto-escaping strategy
401
+ * removed pre-1.8 autoescape tag syntax
402
+ * dropped support for PHP 5.x
403
+ * removed the ability to register a global variable after the runtime or the extensions have been initialized
404
+ * improved the performance of the filesystem loader
405
+ * removed features that were deprecated in 1.x
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/LICENSE CHANGED
@@ -1,29 +1,27 @@
1
- Copyright (c) 2009-2020 by the Twig Team.
2
 
3
- Redistribution and use in source and binary forms, with or without
4
- modification, are permitted provided that the following conditions are
5
- met:
6
 
7
- * Redistributions of source code must retain the above copyright
8
- notice, this list of conditions and the following disclaimer.
9
 
10
- * Redistributions in binary form must reproduce the above
11
- copyright notice, this list of conditions and the following
12
- disclaimer in the documentation and/or other materials provided
13
- with the distribution.
14
-
15
- * The names of the contributors may not be used to endorse or
16
- promote products derived from this software without specific
17
- prior written permission.
18
 
19
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1
+ Copyright (c) 2009-2022 by the Twig Team.
2
 
3
+ All rights reserved.
 
 
4
 
5
+ Redistribution and use in source and binary forms, with or without modification,
6
+ are permitted provided that the following conditions are met:
7
 
8
+ * Redistributions of source code must retain the above copyright notice,
9
+ this list of conditions and the following disclaimer.
10
+ * Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+ * Neither the name of Twig nor the names of its contributors
14
+ may be used to endorse or promote products derived from this software
15
+ without specific prior written permission.
16
 
17
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
vendor/twig/twig/README.rst CHANGED
@@ -1,8 +1,7 @@
1
  Twig, the flexible, fast, and secure template language for PHP
2
  ==============================================================
3
 
4
- Twig is a template language for PHP, released under the new BSD license (code
5
- and documentation).
6
 
7
  Twig uses a syntax similar to the Django and Jinja template languages which
8
  inspired the Twig runtime environment.
1
  Twig, the flexible, fast, and secure template language for PHP
2
  ==============================================================
3
 
4
+ Twig is a template language for PHP.
 
5
 
6
  Twig uses a syntax similar to the Django and Jinja template languages which
7
  inspired the Twig runtime environment.
vendor/twig/twig/composer.json CHANGED
@@ -5,6 +5,7 @@
5
  "keywords": ["templating"],
6
  "homepage": "https://twig.symfony.com",
7
  "license": "BSD-3-Clause",
 
8
  "authors": [
9
  {
10
  "name": "Fabien Potencier",
@@ -23,11 +24,13 @@
23
  }
24
  ],
25
  "require": {
26
- "php": ">=5.5.0",
27
- "symfony/polyfill-ctype": "^1.8"
 
 
28
  },
29
  "require-dev": {
30
- "symfony/phpunit-bridge": "^4.4|^5.0",
31
  "psr/container": "^1.0"
32
  },
33
  "autoload": {
@@ -40,12 +43,12 @@
40
  },
41
  "autoload-dev": {
42
  "psr-4" : {
43
- "Twig\\Tests\\" : "tests"
44
  }
45
  },
46
  "extra": {
47
  "branch-alias": {
48
- "dev-master": "1.42-dev"
49
  }
50
  }
51
  }
5
  "keywords": ["templating"],
6
  "homepage": "https://twig.symfony.com",
7
  "license": "BSD-3-Clause",
8
+ "minimum-stability": "dev",
9
  "authors": [
10
  {
11
  "name": "Fabien Potencier",
24
  }
25
  ],
26
  "require": {
27
+ "php": ">=7.1.3",
28
+ "symfony/polyfill-mbstring": "^1.3",
29
+ "symfony/polyfill-ctype": "^1.8",
30
+ "symfony/polyfill-php72": "^1.8"
31
  },
32
  "require-dev": {
33
+ "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0",
34
  "psr/container": "^1.0"
35
  },
36
  "autoload": {
43
  },
44
  "autoload-dev": {
45
  "psr-4" : {
46
+ "Twig\\Tests\\" : "tests/"
47
  }
48
  },
49
  "extra": {
50
  "branch-alias": {
51
+ "dev-master": "2.15-dev"
52
  }
53
  }
54
  }
vendor/twig/twig/doc/advanced.rst DELETED
@@ -1,957 +0,0 @@
1
- Extending Twig
2
- ==============
3
-
4
- .. caution::
5
-
6
- This section describes how to extend Twig as of **Twig 1.12**. If you are
7
- using an older version, read the :doc:`legacy<advanced_legacy>` chapter
8
- instead.
9
-
10
- Twig can be extended in many ways; you can add extra tags, filters, tests,
11
- operators, global variables, and functions. You can even extend the parser
12
- itself with node visitors.
13
-
14
- .. note::
15
-
16
- The first section of this chapter describes how to extend Twig. If you want
17
- to reuse your changes in different projects or if you want to share them
18
- with others, you should then create an extension as described in the
19
- following section.
20
-
21
- .. caution::
22
-
23
- When extending Twig without creating an extension, Twig won't be able to
24
- recompile your templates when the PHP code is updated. To see your changes
25
- in real-time, either disable template caching or package your code into an
26
- extension (see the next section of this chapter).
27
-
28
- Before extending Twig, you must understand the differences between all the
29
- different possible extension points and when to use them.
30
-
31
- First, remember that Twig has two main language constructs:
32
-
33
- * ``{{ }}``: used to print the result of an expression evaluation;
34
-
35
- * ``{% %}``: used to execute statements.
36
-
37
- To understand why Twig exposes so many extension points, let's see how to
38
- implement a *Lorem ipsum* generator (it needs to know the number of words to
39
- generate).
40
-
41
- You can use a ``lipsum`` *tag*:
42
-
43
- .. code-block:: twig
44
-
45
- {% lipsum 40 %}
46
-
47
- That works, but using a tag for ``lipsum`` is not a good idea for at least
48
- three main reasons:
49
-
50
- * ``lipsum`` is not a language construct;
51
- * The tag outputs something;
52
- * The tag is not flexible as you cannot use it in an expression:
53
-
54
- .. code-block:: twig
55
-
56
- {{ 'some text' ~ {% lipsum 40 %} ~ 'some more text' }}
57
-
58
- In fact, you rarely need to create tags; and that's good news because tags are
59
- the most complex extension point.
60
-
61
- Now, let's use a ``lipsum`` *filter*:
62
-
63
- .. code-block:: twig
64
-
65
- {{ 40|lipsum }}
66
-
67
- Again, it works. But a filter should transform the passed value to something
68
- else. Here, we use the value to indicate the number of words to generate (so,
69
- ``40`` is an argument of the filter, not the value we want to transform).
70
-
71
- Next, let's use a ``lipsum`` *function*:
72
-
73
- .. code-block:: twig
74
-
75
- {{ lipsum(40) }}
76
-
77
- Here we go. For this specific example, the creation of a function is the
78
- extension point to use. And you can use it anywhere an expression is accepted:
79
-
80
- .. code-block:: twig
81
-
82
- {{ 'some text' ~ lipsum(40) ~ 'some more text' }}
83
-
84
- {% set lipsum = lipsum(40) %}
85
-
86
- Lastly, you can also use a *global* object with a method able to generate lorem
87
- ipsum text:
88
-
89
- .. code-block:: twig
90
-
91
- {{ text.lipsum(40) }}
92
-
93
- As a rule of thumb, use functions for frequently used features and global
94
- objects for everything else.
95
-
96
- Keep in mind the following when you want to extend Twig:
97
-
98
- ========== ========================== ========== =========================
99
- What? Implementation difficulty? How often? When?
100
- ========== ========================== ========== =========================
101
- *macro* simple frequent Content generation
102
- *global* simple frequent Helper object
103
- *function* simple frequent Content generation
104
- *filter* simple frequent Value transformation
105
- *tag* complex rare DSL language construct
106
- *test* simple rare Boolean decision
107
- *operator* simple rare Values transformation
108
- ========== ========================== ========== =========================
109
-
110
- Globals
111
- -------
112
-
113
- A global variable is like any other template variable, except that it's
114
- available in all templates and macros::
115
-
116
- $twig = new \Twig\Environment($loader);
117
- $twig->addGlobal('text', new Text());
118
-
119
- You can then use the ``text`` variable anywhere in a template:
120
-
121
- .. code-block:: twig
122
-
123
- {{ text.lipsum(40) }}
124
-
125
- Filters
126
- -------
127
-
128
- Creating a filter consists of associating a name with a PHP callable::
129
-
130
- // an anonymous function
131
- $filter = new \Twig\TwigFilter('rot13', function ($string) {
132
- return str_rot13($string);
133
- });
134
-
135
- // or a simple PHP function
136
- $filter = new \Twig\TwigFilter('rot13', 'str_rot13');
137
-
138
- // or a class static method
139
- $filter = new \Twig\TwigFilter('rot13', ['SomeClass', 'rot13Filter']);
140
- $filter = new \Twig\TwigFilter('rot13', 'SomeClass::rot13Filter');
141
-
142
- // or a class method
143
- $filter = new \Twig\TwigFilter('rot13', [$this, 'rot13Filter']);
144
- // the one below needs a runtime implementation (see below for more information)
145
- $filter = new \Twig\TwigFilter('rot13', ['SomeClass', 'rot13Filter']);
146
-
147
- The first argument passed to the ``\Twig\TwigFilter`` constructor is the name
148
- of the filter you will use in templates and the second one is the PHP callable
149
- to associate with it.
150
-
151
- Then, add the filter to the Twig environment::
152
-
153
- $twig = new \Twig\Environment($loader);
154
- $twig->addFilter($filter);
155
-
156
- And here is how to use it in a template:
157
-
158
- .. code-block:: twig
159
-
160
- {{ 'Twig'|rot13 }}
161
-
162
- {# will output Gjvt #}
163
-
164
- When called by Twig, the PHP callable receives the left side of the filter
165
- (before the pipe ``|``) as the first argument and the extra arguments passed
166
- to the filter (within parentheses ``()``) as extra arguments.
167
-
168
- For instance, the following code:
169
-
170
- .. code-block:: twig
171
-
172
- {{ 'TWIG'|lower }}
173
- {{ now|date('d/m/Y') }}
174
-
175
- is compiled to something like the following::
176
-
177
- <?php echo strtolower('TWIG') ?>
178
- <?php echo twig_date_format_filter($now, 'd/m/Y') ?>
179
-
180
- The ``\Twig\TwigFilter`` class takes an array of options as its last
181
- argument::
182
-
183
- $filter = new \Twig\TwigFilter('rot13', 'str_rot13', $options);
184
-
185
- Environment-aware Filters
186
- ~~~~~~~~~~~~~~~~~~~~~~~~~
187
-
188
- If you want to access the current environment instance in your filter, set the
189
- ``needs_environment`` option to ``true``; Twig will pass the current
190
- environment as the first argument to the filter call::
191
-
192
- $filter = new \Twig\TwigFilter('rot13', function (Twig_Environment $env, $string) {
193
- // get the current charset for instance
194
- $charset = $env->getCharset();
195
-
196
- return str_rot13($string);
197
- }, ['needs_environment' => true]);
198
-
199
- Context-aware Filters
200
- ~~~~~~~~~~~~~~~~~~~~~
201
-
202
- If you want to access the current context in your filter, set the
203
- ``needs_context`` option to ``true``; Twig will pass the current context as
204
- the first argument to the filter call (or the second one if
205
- ``needs_environment`` is also set to ``true``)::
206
-
207
- $filter = new \Twig\TwigFilter('rot13', function ($context, $string) {
208
- // ...
209
- }, ['needs_context' => true]);
210
-
211
- $filter = new \Twig\TwigFilter('rot13', function (Twig_Environment $env, $context, $string) {
212
- // ...
213
- }, ['needs_context' => true, 'needs_environment' => true]);
214
-
215
- Automatic Escaping
216
- ~~~~~~~~~~~~~~~~~~
217
-
218
- If automatic escaping is enabled, the output of the filter may be escaped
219
- before printing. If your filter acts as an escaper (or explicitly outputs HTML
220
- or JavaScript code), you will want the raw output to be printed. In such a
221
- case, set the ``is_safe`` option::
222
-
223
- $filter = new \Twig\TwigFilter('nl2br', 'nl2br', ['is_safe' => ['html']]);
224
-
225
- Some filters may need to work on input that is already escaped or safe, for
226
- example when adding (safe) HTML tags to originally unsafe output. In such a
227
- case, set the ``pre_escape`` option to escape the input data before it is run
228
- through your filter::
229
-
230
- $filter = new \Twig\TwigFilter('somefilter', 'somefilter', ['pre_escape' => 'html', 'is_safe' => ['html']]);
231
-
232
- Variadic Filters
233
- ~~~~~~~~~~~~~~~~
234
-
235
- .. versionadded:: 1.19
236
- Support for variadic filters was added in Twig 1.19.
237
-
238
- When a filter should accept an arbitrary number of arguments, set the
239
- ``is_variadic`` option to ``true``; Twig will pass the extra arguments as the
240
- last argument to the filter call as an array::
241
-
242
- $filter = new \Twig\TwigFilter('thumbnail', function ($file, array $options = []) {
243
- // ...
244
- }, ['is_variadic' => true]);
245
-
246
- Be warned that :ref:`named arguments <named-arguments>` passed to a variadic
247
- filter cannot be checked for validity as they will automatically end up in the
248
- option array.
249
-
250
- Dynamic Filters
251
- ~~~~~~~~~~~~~~~
252
-
253
- A filter name containing the special ``*`` character is a dynamic filter and
254
- the ``*`` part will match any string::
255
-
256
- $filter = new \Twig\TwigFilter('*_path', function ($name, $arguments) {
257
- // ...
258
- });
259
-
260
- The following filters are matched by the above defined dynamic filter:
261
-
262
- * ``product_path``
263
- * ``category_path``
264
-
265
- A dynamic filter can define more than one dynamic parts::
266
-
267
- $filter = new \Twig\TwigFilter('*_path_*', function ($name, $suffix, $arguments) {
268
- // ...
269
- });
270
-
271
- The filter receives all dynamic part values before the normal filter arguments,
272
- but after the environment and the context. For instance, a call to
273
- ``'foo'|a_path_b()`` will result in the following arguments to be passed to the
274
- filter: ``('a', 'b', 'foo')``.
275
-
276
- Deprecated Filters
277
- ~~~~~~~~~~~~~~~~~~
278
-
279
- .. versionadded:: 1.21
280
- Support for deprecated filters was added in Twig 1.21.
281
-
282
- You can mark a filter as being deprecated by setting the ``deprecated`` option
283
- to ``true``. You can also give an alternative filter that replaces the
284
- deprecated one when that makes sense::
285
-
286
- $filter = new \Twig\TwigFilter('obsolete', function () {
287
- // ...
288
- }, ['deprecated' => true, 'alternative' => 'new_one']);
289
-
290
- When a filter is deprecated, Twig emits a deprecation notice when compiling a
291
- template using it. See :ref:`deprecation-notices` for more information.
292
-
293
- Functions
294
- ---------
295
-
296
- Functions are defined in the exact same way as filters, but you need to create
297
- an instance of ``\Twig\TwigFunction``::
298
-
299
- $twig = new \Twig\Environment($loader);
300
- $function = new \Twig\TwigFunction('function_name', function () {
301
- // ...
302
- });
303
- $twig->addFunction($function);
304
-
305
- Functions support the same features as filters, except for the ``pre_escape``
306
- and ``preserves_safety`` options.
307
-
308
- Tests
309
- -----
310
-
311
- Tests are defined in the exact same way as filters and functions, but you need
312
- to create an instance of ``\Twig\TwigTest``::
313
-
314
- $twig = new \Twig\Environment($loader);
315
- $test = new \Twig\TwigTest('test_name', function () {
316
- // ...
317
- });
318
- $twig->addTest($test);
319
-
320
- Tests allow you to create custom application specific logic for evaluating
321
- boolean conditions. As a simple example, let's create a Twig test that checks if
322
- objects are 'red'::
323
-
324
- $twig = new \Twig\Environment($loader);
325
- $test = new \Twig\TwigTest('red', function ($value) {
326
- if (isset($value->color) && $value->color == 'red') {
327
- return true;
328
- }
329
- if (isset($value->paint) && $value->paint == 'red') {
330
- return true;
331
- }
332
- return false;
333
- });
334
- $twig->addTest($test);
335
-
336
- Test functions must always return ``true``/``false``.
337
-
338
- When creating tests you can use the ``node_class`` option to provide custom test
339
- compilation. This is useful if your test can be compiled into PHP primitives.
340
- This is used by many of the tests built into Twig::
341
-
342
- $twig = new \Twig\Environment($loader);
343
- $test = new \Twig\TwigTest(
344
- 'odd',
345
- null,
346
- ['node_class' => '\Twig\Node\Expression\Test\OddTest']);
347
- $twig->addTest($test);
348
-
349
- class Twig_Node_Expression_Test_Odd extends \Twig\Node\Expression\TestExpression
350
- {
351
- public function compile(\Twig\Compiler $compiler)
352
- {
353
- $compiler
354
- ->raw('(')
355
- ->subcompile($this->getNode('node'))
356
- ->raw(' % 2 == 1')
357
- ->raw(')')
358
- ;
359
- }
360
- }
361
-
362
- The above example shows how you can create tests that use a node class. The node
363
- class has access to one sub-node called ``node``. This sub-node contains the
364
- value that is being tested. When the ``odd`` filter is used in code such as:
365
-
366
- .. code-block:: twig
367
-
368
- {% if my_value is odd %}
369
-
370
- The ``node`` sub-node will contain an expression of ``my_value``. Node-based
371
- tests also have access to the ``arguments`` node. This node will contain the
372
- various other arguments that have been provided to your test.
373
-
374
- .. versionadded:: 1.36
375
- Dynamic tests support was added in Twig 1.36.
376
-
377
- If you want to pass a variable number of positional or named arguments to the
378
- test, set the ``is_variadic`` option to ``true``. Tests support dynamic
379
- names (see dynamic filters for the syntax).
380
-
381
- Tags
382
- ----
383
-
384
- One of the most exciting features of a template engine like Twig is the
385
- possibility to define new **language constructs**. This is also the most complex
386
- feature as you need to understand how Twig's internals work.
387
-
388
- Most of the time though, a tag is not needed:
389
-
390
- * If your tag generates some output, use a **function** instead.
391
-
392
- * If your tag modifies some content and returns it, use a **filter** instead.
393
-
394
- For instance, if you want to create a tag that converts a Markdown formatted
395
- text to HTML, create a ``markdown`` filter instead:
396
-
397
- .. code-block:: twig
398
-
399
- {{ '**markdown** text'|markdown }}
400
-
401
- If you want use this filter on large amounts of text, wrap it with the
402
- :doc:`apply <tags/apply>` tag:
403
-
404
- .. code-block:: twig
405
-
406
- {% apply markdown %}
407
- Title
408
- =====
409
-
410
- Much better than creating a tag as you can **compose** filters.
411
- {% endapply %}
412
-
413
- .. note::
414
-
415
- The ``apply`` tag was introduced in Twig 1.40; use the ``filter`` tag with
416
- previous versions.
417
-
418
- * If your tag does not output anything, but only exists because of a side
419
- effect, create a **function** that returns nothing and call it via the
420
- :doc:`filter <tags/do>` tag.
421
-
422
- For instance, if you want to create a tag that logs text, create a ``log``
423
- function instead and call it via the :doc:`do <tags/do>` tag:
424
-
425
- .. code-block:: twig
426
-
427
- {% do log('Log some things') %}
428
-
429
- If you still want to create a tag for a new language construct, great!
430
-
431
- Let's create a ``set`` tag that allows the definition of simple variables from
432
- within a template. The tag can be used like follows:
433
-
434
- .. code-block:: twig
435
-
436
- {% set name = "value" %}
437
-
438
- {{ name }}
439
-
440
- {# should output value #}
441
-
442
- .. note::
443
-
444
- The ``set`` tag is part of the Core extension and as such is always
445
- available. The built-in version is slightly more powerful and supports
446
- multiple assignments by default.
447
-
448
- Three steps are needed to define a new tag:
449
-
450
- * Defining a Token Parser class (responsible for parsing the template code);
451
-
452
- * Defining a Node class (responsible for converting the parsed code to PHP);
453
-
454
- * Registering the tag.
455
-
456
- Registering a new tag
457
- ~~~~~~~~~~~~~~~~~~~~~
458
-
459
- Add a tag by calling the ``addTokenParser`` method on the ``\Twig\Environment``
460
- instance::
461
-
462
- $twig = new \Twig\Environment($loader);
463
- $twig->addTokenParser(new Project_Set_TokenParser());
464
-
465
- Defining a Token Parser
466
- ~~~~~~~~~~~~~~~~~~~~~~~
467
-
468
- Now, let's see the actual code of this class::
469
-
470
- class Project_Set_TokenParser extends \Twig\TokenParser\AbstractTokenParser
471
- {
472
- public function parse(\Twig\Token $token)
473
- {
474
- $parser = $this->parser;
475
- $stream = $parser->getStream();
476
-
477
- $name = $stream->expect(\Twig\Token::NAME_TYPE)->getValue();
478
- $stream->expect(\Twig\Token::OPERATOR_TYPE, '=');
479
- $value = $parser->getExpressionParser()->parseExpression();
480
- $stream->expect(\Twig\Token::BLOCK_END_TYPE);
481
-
482
- return new Project_Set_Node($name, $value, $token->getLine(), $this->getTag());
483
- }
484
-
485
- public function getTag()
486
- {
487
- return 'set';
488
- }
489
- }
490
-
491
- The ``getTag()`` method must return the tag we want to parse, here ``set``.
492
-
493
- The ``parse()`` method is invoked whenever the parser encounters a ``set``
494
- tag. It should return a ``\Twig\Node\Node`` instance that represents the node (the
495
- ``Project_Set_Node`` calls creating is explained in the next section).
496
-
497
- The parsing process is simplified thanks to a bunch of methods you can call
498
- from the token stream (``$this->parser->getStream()``):
499
-
500
- * ``getCurrent()``: Gets the current token in the stream.
501
-
502
- * ``next()``: Moves to the next token in the stream, *but returns the old one*.
503
-
504
- * ``test($type)``, ``test($value)`` or ``test($type, $value)``: Determines whether
505
- the current token is of a particular type or value (or both). The value may be an
506
- array of several possible values.
507
-
508
- * ``expect($type[, $value[, $message]])``: If the current token isn't of the given
509
- type/value a syntax error is thrown. Otherwise, if the type and value are correct,
510
- the token is returned and the stream moves to the next token.
511
-
512
- * ``look()``: Looks at the next token without consuming it.
513
-
514
- Parsing expressions is done by calling the ``parseExpression()`` like we did for
515
- the ``set`` tag.
516
-
517
- .. tip::
518
-
519
- Reading the existing ``TokenParser`` classes is the best way to learn all
520
- the nitty-gritty details of the parsing process.
521
-
522
- Defining a Node
523
- ~~~~~~~~~~~~~~~
524
-
525
- The ``Project_Set_Node`` class itself is quite short::
526
-
527
- class Project_Set_Node extends \Twig\Node\Node
528
- {
529
- public function __construct($name, \Twig\Node\Expression\AbstractExpression $value, $line, $tag = null)
530
- {
531
- parent::__construct(['value' => $value], ['name' => $name], $line, $tag);
532
- }
533
-
534
- public function compile(\Twig\Compiler $compiler)
535
- {
536
- $compiler
537
- ->addDebugInfo($this)
538
- ->write('$context[\''.$this->getAttribute('name').'\'] = ')
539
- ->subcompile($this->getNode('value'))
540
- ->raw(";\n")
541
- ;
542
- }
543
- }
544
-
545
- The compiler implements a fluid interface and provides methods that helps the
546
- developer generate beautiful and readable PHP code:
547
-
548
- * ``subcompile()``: Compiles a node.
549
-
550
- * ``raw()``: Writes the given string as is.
551
-
552
- * ``write()``: Writes the given string by adding indentation at the beginning
553
- of each line.
554
-
555
- * ``string()``: Writes a quoted string.
556
-
557
- * ``repr()``: Writes a PHP representation of a given value (see
558
- ``\Twig\Node\ForNode`` for a usage example).
559
-
560
- * ``addDebugInfo()``: Adds the line of the original template file related to
561
- the current node as a comment.
562
-
563
- * ``indent()``: Indents the generated code (see ``\Twig\Node\BlockNode`` for a
564
- usage example).
565
-
566
- * ``outdent()``: Outdents the generated code (see ``\Twig\Node\BlockNode`` for a
567
- usage example).
568
-
569
- .. _creating_extensions:
570
-
571
- Creating an Extension
572
- ---------------------
573
-
574
- The main motivation for writing an extension is to move often used code into a
575
- reusable class like adding support for internationalization. An extension can
576
- define tags, filters, tests, operators, functions, and node visitors.
577
-
578
- Most of the time, it is useful to create a single extension for your project,
579
- to host all the specific tags and filters you want to add to Twig.
580
-
581
- .. tip::
582
-
583
- When packaging your code into an extension, Twig is smart enough to
584
- recompile your templates whenever you make a change to it (when
585
- ``auto_reload`` is enabled).
586
-
587
- An extension is a class that implements the following interface::
588
-
589
- interface Twig_ExtensionInterface
590
- {
591
- /**
592
- * Initializes the runtime environment.
593
- *
594
- * This is where you can load some file that contains filter functions for instance.
595
- *
596
- * @deprecated since 1.23 (to be removed in 2.0), implement \Twig\Extension\InitRuntimeInterface instead
597
- */
598
- function initRuntime(\Twig\Environment $environment);
599
-
600
- /**
601
- * Returns the token parser instances to add to the existing list.
602
- *
603
- * @return (Twig_TokenParserInterface|Twig_TokenParserBrokerInterface)[]
604
- */
605
- function getTokenParsers();
606
-
607
- /**
608
- * Returns the node visitor instances to add to the existing list.
609
- *
610
- * @return \Twig\NodeVisitor\NodeVisitorInterface[]
611
- */
612
- function getNodeVisitors();
613
-
614
- /**
615
- * Returns a list of filters to add to the existing list.
616
- *
617
- * @return \Twig\TwigFilter[]
618
- */
619
- function getFilters();
620
-
621
- /**
622
- * Returns a list of tests to add to the existing list.
623
- *
624
- * @return \Twig\TwigTest[]
625
- */
626
- function getTests();
627
-
628
- /**
629
- * Returns a list of functions to add to the existing list.
630
- *
631
- * @return \Twig\TwigFunction[]
632
- */
633
- function getFunctions();
634
-
635
- /**
636
- * Returns a list of operators to add to the existing list.
637
- *
638
- * @return array<array> First array of unary operators, second array of binary operators
639
- */
640
- function getOperators();
641
-
642
- /**
643
- * Returns a list of global variables to add to the existing list.
644
- *
645
- * @return array An array of global variables
646
- *
647
- * @deprecated since 1.23 (to be removed in 2.0), implement \Twig\Extension\GlobalsInterface instead
648
- */
649
- function getGlobals();
650
-
651
- /**
652
- * Returns the name of the extension.
653
- *
654
- * @return string The extension name
655
- *
656
- * @deprecated since 1.26 (to be removed in 2.0), not used anymore internally
657
- */
658
- function getName();
659
- }
660
-
661
- To keep your extension class clean and lean, inherit from the built-in
662
- ``\Twig\Extension\AbstractExtension`` class instead of implementing the interface as it provides
663
- empty implementations for all methods::
664
-
665
- class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
666
- {
667
- }
668
-
669
- This extension does nothing for now. We will customize it in the next sections.
670
-
671
- .. note::
672
-
673
- Prior to Twig 1.26, you must implement the ``getName()`` method which must
674
- return a unique identifier for the extension.
675
-
676
- You can save your extension anywhere on the filesystem, as all extensions must
677
- be registered explicitly to be available in your templates.
678
-
679
- You can register an extension by using the ``addExtension()`` method on your
680
- main ``Environment`` object::
681
-
682
- $twig = new \Twig\Environment($loader);
683
- $twig->addExtension(new Project_Twig_Extension());
684
-
685
- .. tip::
686
-
687
- The Twig core extensions are great examples of how extensions work.
688
-
689
- Globals
690
- ~~~~~~~
691
-
692
- Global variables can be registered in an extension via the ``getGlobals()``
693
- method::
694
-
695
- class Project_Twig_Extension extends \Twig\Extension\AbstractExtension implements \Twig\Extension\GlobalsInterface
696
- {
697
- public function getGlobals()
698
- {
699
- return [
700
- 'text' => new Text(),
701
- ];
702
- }
703
-
704
- // ...
705
- }
706
-
707
- Functions
708
- ~~~~~~~~~
709
-
710
- Functions can be registered in an extension via the ``getFunctions()``
711
- method::
712
-
713
- class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
714
- {
715
- public function getFunctions()
716
- {
717
- return [
718
- new \Twig\TwigFunction('lipsum', 'generate_lipsum'),
719
- ];
720
- }
721
-
722
- // ...
723
- }
724
-
725
- Filters
726
- ~~~~~~~
727
-
728
- To add a filter to an extension, you need to override the ``getFilters()``
729
- method. This method must return an array of filters to add to the Twig
730
- environment::
731
-
732
- class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
733
- {
734
- public function getFilters()
735
- {
736
- return [
737
- new \Twig\TwigFilter('rot13', 'str_rot13'),
738
- ];
739
- }
740
-
741
- // ...
742
- }
743
-
744
- Tags
745
- ~~~~
746
-
747
- Adding a tag in an extension can be done by overriding the
748
- ``getTokenParsers()`` method. This method must return an array of tags to add
749
- to the Twig environment::
750
-
751
- class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
752
- {
753
- public function getTokenParsers()
754
- {
755
- return [new Project_Set_TokenParser()];
756
- }
757
-
758
- // ...
759
- }
760
-
761
- In the above code, we have added a single new tag, defined by the
762
- ``Project_Set_TokenParser`` class. The ``Project_Set_TokenParser`` class is
763
- responsible for parsing the tag and compiling it to PHP.
764
-
765
- Operators
766
- ~~~~~~~~~
767
-
768
- The ``getOperators()`` methods lets you add new operators. Here is how to add
769
- the ``!``, ``||``, and ``&&`` operators::
770
-
771
- class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
772
- {
773
- public function getOperators()
774
- {
775
- return [
776
- [
777
- '!' => ['precedence' => 50, 'class' => '\Twig\Node\Expression\Unary\NotUnary'],
778
- ],
779
- [
780
- '||' => ['precedence' => 10, 'class' => '\Twig\Node\Expression\Binary\OrBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT],
781
- '&&' => ['precedence' => 15, 'class' => '\Twig\Node\Expression\Binary\AndBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT],
782
- ],
783
- ];
784
- }
785
-
786
- // ...
787
- }
788
-
789
- Tests
790
- ~~~~~
791
-
792
- The ``getTests()`` method lets you add new test functions::
793
-
794
- class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
795
- {
796
- public function getTests()
797
- {
798
- return [
799
- new \Twig\TwigTest('even', 'twig_test_even'),
800
- ];
801
- }
802
-
803
- // ...
804
- }
805
-
806
- Definition vs Runtime
807
- ~~~~~~~~~~~~~~~~~~~~~
808
-
809
- Twig filters, functions, and tests runtime implementations can be defined as
810
- any valid PHP callable:
811
-
812
- * **functions/static methods**: Simple to implement and fast (used by all Twig
813
- core extensions); but it is hard for the runtime to depend on external
814
- objects;
815
-
816
- * **closures**: Simple to implement;
817
-
818
- * **object methods**: More flexible and required if your runtime code depends
819
- on external objects.
820
-
821
- The simplest way to use methods is to define them on the extension itself::
822
-
823
- class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
824
- {
825
- private $rot13Provider;
826
-
827
- public function __construct($rot13Provider)
828
- {
829
- $this->rot13Provider = $rot13Provider;
830
- }
831
-
832
- public function getFunctions()
833
- {
834
- return [
835
- new \Twig\TwigFunction('rot13', [$this, 'rot13']),
836
- ];
837
- }
838
-
839
- public function rot13($value)
840
- {
841
- return $this->rot13Provider->rot13($value);
842
- }
843
- }
844
-
845
- This is very convenient but not recommended as it makes template compilation
846
- depend on runtime dependencies even if they are not needed (think for instance
847
- as a dependency that connects to a database engine).
848
-
849
- As of Twig 1.26, you can decouple the extension definitions from their
850
- runtime implementations by registering a ``\Twig\RuntimeLoader\RuntimeLoaderInterface``
851
- instance on the environment that knows how to instantiate such runtime classes
852
- (runtime classes must be autoload-able)::
853
-
854
- class RuntimeLoader implements \Twig\RuntimeLoader\RuntimeLoaderInterface
855
- {
856
- public function load($class)
857
- {
858
- // implement the logic to create an instance of $class
859
- // and inject its dependencies
860
- // most of the time, it means using your dependency injection container
861
- if ('Project_Twig_RuntimeExtension' === $class) {
862
- return new $class(new Rot13Provider());
863
- } else {
864
- // ...
865
- }
866
- }
867
- }
868
-
869
- $twig->addRuntimeLoader(new RuntimeLoader());
870
-
871
- .. note::
872
-
873
- As of Twig 1.32, Twig comes with a PSR-11 compatible runtime loader
874
- (``\Twig\RuntimeLoader\ContainerRuntimeLoader``).
875
-
876
- It is now possible to move the runtime logic to a new
877
- ``Project_Twig_RuntimeExtension`` class and use it directly in the extension::
878
-
879
- class Project_Twig_RuntimeExtension
880
- {
881
- private $rot13Provider;
882
-
883
- public function __construct($rot13Provider)
884
- {
885
- $this->rot13Provider = $rot13Provider;
886
- }
887
-
888
- public function rot13($value)
889
- {
890
- return $this->rot13Provider->rot13($value);
891
- }
892
- }
893
-
894
- class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
895
- {
896
- public function getFunctions()
897
- {
898
- return [
899
- new \Twig\TwigFunction('rot13', ['Project_Twig_RuntimeExtension', 'rot13']),
900
- // or
901
- new \Twig\TwigFunction('rot13', 'Project_Twig_RuntimeExtension::rot13'),
902
- ];
903
- }
904
- }
905
-
906
- Testing an Extension
907
- --------------------
908
-
909
- Functional Tests
910
- ~~~~~~~~~~~~~~~~
911
-
912
- You can create functional tests for extensions by creating the following file
913
- structure in your test directory::
914
-
915
- Fixtures/
916
- filters/
917
- foo.test
918
- bar.test
919
- functions/
920
- foo.test
921
- bar.test
922
- tags/
923
- foo.test
924
- bar.test
925
- IntegrationTest.php
926
-
927
- The ``IntegrationTest.php`` file should look like this::
928
-
929
- class Project_Tests_IntegrationTest extends \Twig\Test\IntegrationTestCase
930
- {
931
- public function getExtensions()
932
- {
933
- return [
934
- new Project_Twig_Extension1(),
935
- new Project_Twig_Extension2(),
936
- ];
937
- }
938
-
939
- public function getFixturesDir()
940
- {
941
- return __DIR__.'/Fixtures/';
942
- }
943
- }
944
-
945
- Fixtures examples can be found within the Twig repository
946
- `tests/Twig/Fixtures`_ directory.
947
-
948
- Node Tests
949
- ~~~~~~~~~~
950
-
951
- Testing the node visitors can be complex, so extend your test cases from
952
- ``\Twig\Test\NodeTestCase``. Examples can be found in the Twig repository
953
- `tests/Twig/Node`_ directory.
954
-
955
- .. _`rot13`: https://secure.php.net/manual/en/function.str-rot13.php
956
- .. _`tests/Twig/Fixtures`: https://github.com/twigphp/Twig/tree/1.x/tests/Fixtures
957
- .. _`tests/Twig/Node`: https://github.com/twigphp/Twig/tree/1.x/tests/Node
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/advanced_legacy.rst DELETED
@@ -1,877 +0,0 @@
1
- Extending Twig
2
- ==============
3
-
4
- .. caution::
5
-
6
- This section describes how to extends Twig for versions **older than
7
- 1.12**. If you are using a newer version, read the :doc:`newer<advanced>`
8
- chapter instead.
9
-
10
- Twig can be extended in many ways; you can add extra tags, filters, tests,
11
- operators, global variables, and functions. You can even extend the parser
12
- itself with node visitors.
13
-
14
- .. note::
15
-
16
- The first section of this chapter describes how to extend Twig. If
17
- you want to reuse your changes in different projects or if you want to
18
- share them with others, you should then create an extension as described
19
- in the following section.
20
-
21
- .. caution::
22
-
23
- When extending Twig by calling methods on the Twig environment instance,
24
- Twig won't be able to recompile your templates when the PHP code is
25
- updated. To see your changes in real-time, either disable template caching
26
- or package your code into an extension (see the next section of this
27
- chapter).
28
-
29
- Before extending Twig, you must understand the differences between all the
30
- different possible extension points and when to use them.
31
-
32
- First, remember that Twig has two main language constructs:
33
-
34
- * ``{{ }}``: used to print the result of an expression evaluation;
35
-
36
- * ``{% %}``: used to execute statements.
37
-
38
- To understand why Twig exposes so many extension points, let's see how to
39
- implement a *Lorem ipsum* generator (it needs to know the number of words to
40
- generate).
41
-
42
- You can use a ``lipsum`` *tag*:
43
-
44
- .. code-block:: twig
45
-
46
- {% lipsum 40 %}
47
-
48
- That works, but using a tag for ``lipsum`` is not a good idea for at least
49
- three main reasons:
50
-
51
- * ``lipsum`` is not a language construct;
52
- * The tag outputs something;
53
- * The tag is not flexible as you cannot use it in an expression:
54
-
55
- .. code-block:: twig
56
-
57
- {{ 'some text' ~ {% lipsum 40 %} ~ 'some more text' }}
58
-
59
- In fact, you rarely need to create tags; and that's good news because tags are
60
- the most complex extension point of Twig.
61
-
62
- Now, let's use a ``lipsum`` *filter*:
63
-
64
- .. code-block:: twig
65
-
66
- {{ 40|lipsum }}
67
-
68
- Again, it works, but it looks weird. A filter transforms the passed value to
69
- something else but here we use the value to indicate the number of words to
70
- generate (so, ``40`` is an argument of the filter, not the value we want to
71
- transform).
72
-
73
- Next, let's use a ``lipsum`` *function*:
74
-
75
- .. code-block:: twig
76
-
77
- {{ lipsum(40) }}
78
-
79
- Here we go. For this specific example, the creation of a function is the
80
- extension point to use. And you can use it anywhere an expression is accepted:
81
-
82
- .. code-block:: twig
83
-
84
- {{ 'some text' ~ ipsum(40) ~ 'some more text' }}
85
-
86
- {% set ipsum = ipsum(40) %}
87
-
88
- Last but not the least, you can also use a *global* object with a method able
89
- to generate lorem ipsum text:
90
-
91
- .. code-block:: twig
92
-
93
- {{ text.lipsum(40) }}
94
-
95
- As a rule of thumb, use functions for frequently used features and global
96
- objects for everything else.
97
-
98
- Keep in mind the following when you want to extend Twig:
99
-
100
- ========== ========================== ========== =========================
101
- What? Implementation difficulty? How often? When?
102
- ========== ========================== ========== =========================
103
- *macro* trivial frequent Content generation
104
- *global* trivial frequent Helper object
105
- *function* trivial frequent Content generation
106
- *filter* trivial frequent Value transformation
107
- *tag* complex rare DSL language construct
108
- *test* trivial rare Boolean decision
109
- *operator* trivial rare Values transformation
110
- ========== ========================== ========== =========================
111
-
112
- Globals
113
- -------
114
-
115
- A global variable is like any other template variable, except that it's
116
- available in all templates and macros::
117
-
118
- $twig = new \Twig\Environment($loader);
119
- $twig->addGlobal('text', new Text());
120
-
121
- You can then use the ``text`` variable anywhere in a template:
122
-
123
- .. code-block:: twig
124
-
125
- {{ text.lipsum(40) }}
126
-
127
- Filters
128
- -------
129
-
130
- A filter is a regular PHP function or an object method that takes the left
131
- side of the filter (before the pipe ``|``) as first argument and the extra
132
- arguments passed to the filter (within parentheses ``()``) as extra arguments.
133
-
134
- Defining a filter is as easy as associating the filter name with a PHP
135
- callable. For instance, let's say you have the following code in a template:
136
-
137
- .. code-block:: twig
138
-
139
- {{ 'TWIG'|lower }}
140
-
141
- When compiling this template to PHP, Twig looks for the PHP callable
142
- associated with the ``lower`` filter. The ``lower`` filter is a built-in Twig
143
- filter, and it is mapped directly to the PHP ``strtolower()`` function. After
144
- compilation, the generated PHP code is roughly equivalent to:
145
-
146
- .. code-block:: html+php
147
-
148
- <?php echo strtolower('TWIG') ?>
149
-
150
- As you can see, the ``'TWIG'`` string is passed as a first argument to the PHP
151
- function.
152
-
153
- A filter can also take extra arguments like in the following example:
154
-
155
- .. code-block:: twig
156
-
157
- {{ now|date('d/m/Y') }}
158
-
159
- In this case, the extra arguments are passed to the function after the main
160
- argument, and the compiled code is equivalent to:
161
-
162
- .. code-block:: html+php
163
-
164
- <?php echo twig_date_format_filter($now, 'd/m/Y') ?>
165
-
166
- Let's see how to create a new filter.
167
-
168
- In this section, we will create a ``rot13`` filter, which should return the
169
- `rot13`_ transformation of a string. Here is an example of its usage and the
170
- expected output:
171
-
172
- .. code-block:: twig
173
-
174
- {{ "Twig"|rot13 }}
175
-
176
- {# should displays Gjvt #}
177
-
178
- Adding a filter is as simple as calling the ``addFilter()`` method on the
179
- ``\Twig\Environment`` instance::
180
-
181
- $twig = new \Twig\Environment($loader);
182
- $twig->addFilter('rot13', new Twig_Filter_Function('str_rot13'));
183
-
184
- The second argument of ``addFilter()`` is an instance of ``Twig_Filter``.
185
- Here, we use ``Twig_Filter_Function`` as the filter is a PHP function. The
186
- first argument passed to the ``Twig_Filter_Function`` constructor is the name
187
- of the PHP function to call, here ``str_rot13``, a native PHP function.
188
-
189
- Let's say I now want to be able to add a prefix before the converted string:
190
-
191
- .. code-block:: twig
192
-
193
- {{ "Twig"|rot13('prefix_') }}
194
-
195
- {# should displays prefix_Gjvt #}
196
-
197
- As the PHP ``str_rot13()`` function does not support this requirement, let's
198
- create a new PHP function::
199
-
200
- function project_compute_rot13($string, $prefix = '')
201
- {
202
- return $prefix.str_rot13($string);
203
- }
204
-
205
- As you can see, the ``prefix`` argument of the filter is passed as an extra
206
- argument to the ``project_compute_rot13()`` function.
207
-
208
- Adding this filter is as easy as before::
209
-
210
- $twig->addFilter('rot13', new Twig_Filter_Function('project_compute_rot13'));
211
-
212
- For better encapsulation, a filter can also be defined as a static method of a
213
- class. The ``Twig_Filter_Function`` class can also be used to register such
214
- static methods as filters::
215
-
216
- $twig->addFilter('rot13', new Twig_Filter_Function('SomeClass::rot13Filter'));
217
-
218
- .. tip::
219
-
220
- In an extension, you can also define a filter as a static method of the
221
- extension class.
222
-
223
- Environment aware Filters
224
- ~~~~~~~~~~~~~~~~~~~~~~~~~
225
-
226
- The ``Twig_Filter`` classes take options as their last argument. For instance,
227
- if you want access to the current environment instance in your filter, set the
228
- ``needs_environment`` option to ``true``::
229
-
230
- $filter = new Twig_Filter_Function('str_rot13', ['needs_environment' => true]);
231
-
232
- Twig will then pass the current environment as the first argument to the
233
- filter call::
234
-
235
- function twig_compute_rot13(\Twig\Environment $env, $string)
236
- {
237
- // get the current charset for instance
238
- $charset = $env->getCharset();
239
-
240
- return str_rot13($string);
241
- }
242
-
243
- Automatic Escaping
244
- ~~~~~~~~~~~~~~~~~~
245
-
246
- If automatic escaping is enabled, the output of the filter may be escaped
247
- before printing. If your filter acts as an escaper (or explicitly outputs HTML
248
- or JavaScript code), you will want the raw output to be printed. In such a
249
- case, set the ``is_safe`` option::
250
-
251
- $filter = new Twig_Filter_Function('nl2br', ['is_safe' => ['html']]);
252
-
253
- Some filters may need to work on input that is already escaped or safe, for
254
- example when adding (safe) HTML tags to originally unsafe output. In such a
255
- case, set the ``pre_escape`` option to escape the input data before it is run
256
- through your filter::
257
-
258
- $filter = new Twig_Filter_Function('somefilter', ['pre_escape' => 'html', 'is_safe' => ['html']]);
259
-
260
- Dynamic Filters
261
- ~~~~~~~~~~~~~~~
262
-
263
- .. versionadded:: 1.5
264
- Dynamic filters support was added in Twig 1.5.
265
-
266
- A filter name containing the special ``*`` character is a dynamic filter as
267
- the ``*`` can be any string::
268
-
269
- $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path'));
270
-
271
- function twig_path($name, $arguments)
272
- {
273
- // ...
274
- }
275
-
276
- The following filters will be matched by the above defined dynamic filter:
277
-
278
- * ``product_path``
279
- * ``category_path``
280
-
281
- A dynamic filter can define more than one dynamic parts::
282
-
283
- $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path'));
284
-
285
- function twig_path($name, $suffix, $arguments)
286
- {
287
- // ...
288
- }
289
-
290
- The filter will receive all dynamic part values before the normal filters
291
- arguments. For instance, a call to ``'foo'|a_path_b()`` will result in the
292
- following PHP call: ``twig_path('a', 'b', 'foo')``.
293
-
294
- Functions
295
- ---------
296
-
297
- A function is a regular PHP function or an object method that can be called from
298
- templates.
299
-
300
- .. code-block:: twig
301
-
302
- {{ constant("DATE_W3C") }}
303
-
304
- When compiling this template to PHP, Twig looks for the PHP callable
305
- associated with the ``constant`` function. The ``constant`` function is a built-in Twig
306
- function, and it is mapped directly to the PHP ``constant()`` function. After
307
- compilation, the generated PHP code is roughly equivalent to:
308
-
309
- .. code-block:: html+php
310
-
311
- <?php echo constant('DATE_W3C') ?>
312
-
313
- Adding a function is similar to adding a filter. This can be done by calling the
314
- ``addFunction()`` method on the ``\Twig\Environment`` instance::
315
-
316
- $twig = new \Twig\Environment($loader);
317
- $twig->addFunction('functionName', new Twig_Function_Function('someFunction'));
318
-
319
- You can also expose extension methods as functions in your templates::
320
-
321
- // $this is an object that implements \Twig\Extension\ExtensionInterface.
322
- $twig = new \Twig\Environment($loader);
323
- $twig->addFunction('otherFunction', new Twig_Function_Method($this, 'someMethod'));
324
-
325
- Functions also support ``needs_environment`` and ``is_safe`` parameters.
326
-
327
- Dynamic Functions
328
- ~~~~~~~~~~~~~~~~~
329
-
330
- .. versionadded:: 1.5
331
- Dynamic functions support was added in Twig 1.5.
332
-
333
- A function name containing the special ``*`` character is a dynamic function
334
- as the ``*`` can be any string::
335
-
336
- $twig->addFunction('*_path', new Twig_Function_Function('twig_path'));
337
-
338
- function twig_path($name, $arguments)
339
- {
340
- // ...
341
- }
342
-
343
- The following functions will be matched by the above defined dynamic function:
344
-
345
- * ``product_path``
346
- * ``category_path``
347
-
348
- A dynamic function can define more than one dynamic parts::
349
-
350
- $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path'));
351
-
352
- function twig_path($name, $suffix, $arguments)
353
- {
354
- // ...
355
- }
356
-
357
- The function will receive all dynamic part values before the normal functions
358
- arguments. For instance, a call to ``a_path_b('foo')`` will result in the
359
- following PHP call: ``twig_path('a', 'b', 'foo')``.
360
-
361
- Tags
362
- ----
363
-
364
- One of the most exciting feature of a template engine like Twig is the
365
- possibility to define new language constructs. This is also the most complex
366
- feature as you need to understand how Twig's internals work.
367
-
368
- Let's create a simple ``set`` tag that allows the definition of simple
369
- variables from within a template. The tag can be used like follows:
370
-
371
- .. code-block:: twig
372
-
373
- {% set name = "value" %}
374
-
375
- {{ name }}
376
-
377
- {# should output value #}
378
-
379
- .. note::
380
-
381
- The ``set`` tag is part of the Core extension and as such is always
382
- available. The built-in version is slightly more powerful and supports
383
- multiple assignments by default (cf. the template designers chapter for
384
- more information).
385
-
386
- Three steps are needed to define a new tag:
387
-
388
- * Defining a Token Parser class (responsible for parsing the template code);
389
-
390
- * Defining a Node class (responsible for converting the parsed code to PHP);
391
-
392
- * Registering the tag.
393
-
394
- Registering a new tag
395
- ~~~~~~~~~~~~~~~~~~~~~
396
-
397
- Adding a tag is as simple as calling the ``addTokenParser`` method on the
398
- ``\Twig\Environment`` instance::
399
-
400
- $twig = new \Twig\Environment($loader);
401
- $twig->addTokenParser(new Project_Set_TokenParser());
402
-
403
- Defining a Token Parser
404
- ~~~~~~~~~~~~~~~~~~~~~~~
405
-
406
- Now, let's see the actual code of this class::
407
-
408
- class Project_Set_TokenParser extends \Twig\TokenParser\AbstractTokenParser
409
- {
410
- public function parse(\Twig\Token $token)
411
- {
412
- $lineno = $token->getLine();
413
- $name = $this->parser->getStream()->expect(\Twig\Token::NAME_TYPE)->getValue();
414
- $this->parser->getStream()->expect(\Twig\Token::OPERATOR_TYPE, '=');
415
- $value = $this->parser->getExpressionParser()->parseExpression();
416
-
417
- $this->parser->getStream()->expect(\Twig\Token::BLOCK_END_TYPE);
418
-
419
- return new Project_Set_Node($name, $value, $lineno, $this->getTag());
420
- }
421
-
422
- public function getTag()
423
- {
424
- return 'set';
425
- }
426
- }
427
-
428
- The ``getTag()`` method must return the tag we want to parse, here ``set``.
429
-
430
- The ``parse()`` method is invoked whenever the parser encounters a ``set``
431
- tag. It should return a ``\Twig\Node\Node`` instance that represents the node (the
432
- ``Project_Set_Node`` calls creating is explained in the next section).
433
-
434
- The parsing process is simplified thanks to a bunch of methods you can call
435
- from the token stream (``$this->parser->getStream()``):
436
-
437
- * ``getCurrent()``: Gets the current token in the stream.
438
-
439
- * ``next()``: Moves to the next token in the stream, *but returns the old one*.
440
-
441
- * ``test($type)``, ``test($value)`` or ``test($type, $value)``: Determines whether
442
- the current token is of a particular type or value (or both). The value may be an
443
- array of several possible values.
444
-
445
- * ``expect($type[, $value[, $message]])``: If the current token isn't of the given
446
- type/value a syntax error is thrown. Otherwise, if the type and value are correct,
447
- the token is returned and the stream moves to the next token.
448
-
449
- * ``look()``: Looks a the next token without consuming it.
450
-
451
- Parsing expressions is done by calling the ``parseExpression()`` like we did for
452
- the ``set`` tag.
453
-
454
- .. tip::
455
-
456
- Reading the existing ``TokenParser`` classes is the best way to learn all
457
- the nitty-gritty details of the parsing process.
458
-
459
- Defining a Node
460
- ~~~~~~~~~~~~~~~
461
-
462
- The ``Project_Set_Node`` class itself is rather simple::
463
-
464
- class Project_Set_Node extends \Twig\Node\Node
465
- {
466
- public function __construct($name, \Twig\Node\Expression\AbstractExpression $value, $lineno, $tag = null)
467
- {
468
- parent::__construct(['value' => $value], ['name' => $name], $lineno, $tag);
469
- }
470
-
471
- public function compile(\Twig\Compiler $compiler)
472
- {
473
- $compiler
474
- ->addDebugInfo($this)
475
- ->write('$context[\''.$this->getAttribute('name').'\'] = ')
476
- ->subcompile($this->getNode('value'))
477
- ->raw(";\n")
478
- ;
479
- }
480
- }
481
-
482
- The compiler implements a fluid interface and provides methods that helps the
483
- developer generate beautiful and readable PHP code:
484
-
485
- * ``subcompile()``: Compiles a node.
486
-
487
- * ``raw()``: Writes the given string as is.
488
-
489
- * ``write()``: Writes the given string by adding indentation at the beginning
490
- of each line.
491
-
492
- * ``string()``: Writes a quoted string.
493
-
494
- * ``repr()``: Writes a PHP representation of a given value (see
495
- ``\Twig\Node\ForNode`` for a usage example).
496
-
497
- * ``addDebugInfo()``: Adds the line of the original template file related to
498
- the current node as a comment.
499
-
500
- * ``indent()``: Indents the generated code (see ``\Twig\Node\BlockNode`` for a
501
- usage example).
502
-
503
- * ``outdent()``: Outdents the generated code (see ``\Twig\Node\BlockNode`` for a
504
- usage example).
505
-
506
- Creating an Extension
507
- ---------------------
508
-
509
- The main motivation for writing an extension is to move often used code into a
510
- reusable class like adding support for internationalization. An extension can
511
- define tags, filters, tests, operators, global variables, functions, and node
512
- visitors.
513
-
514
- Creating an extension also makes for a better separation of code that is
515
- executed at compilation time and code needed at runtime. As such, it makes
516
- your code faster.
517
-
518
- Most of the time, it is useful to create a single extension for your project,
519
- to host all the specific tags and filters you want to add to Twig.
520
-
521
- .. tip::
522
-
523
- When packaging your code into an extension, Twig is smart enough to
524
- recompile your templates whenever you make a change to it (when the
525
- ``auto_reload`` is enabled).
526
-
527
- An extension is a class that implements the following interface::
528
-
529
- interface Twig_ExtensionInterface
530
- {
531
- /**
532
- * Initializes the runtime environment.
533
- *
534
- * This is where you can load some file that contains filter functions for instance.
535
- */
536
- function initRuntime(\Twig\Environment $environment);
537
-
538
- /**
539
- * Returns the token parser instances to add to the existing list.
540
- *
541
- * @return (Twig_TokenParserInterface|Twig_TokenParserBrokerInterface)[]
542
- */
543
- function getTokenParsers();
544
-
545
- /**
546
- * Returns the node visitor instances to add to the existing list.
547
- *
548
- * @return \Twig\NodeVisitor\NodeVisitorInterface[]
549
- */
550
- function getNodeVisitors();
551
-
552
- /**
553
- * Returns a list of filters to add to the existing list.
554
- *
555
- * @return \Twig\TwigFilter[]
556
- */
557
- function getFilters();
558
-
559
- /**
560
- * Returns a list of tests to add to the existing list.
561
- *
562
- * @return \Twig\TwigTest[]
563
- */
564
- function getTests();
565
-
566
- /**
567
- * Returns a list of functions to add to the existing list.
568
- *
569
- * @return \Twig\TwigFunction[]
570
- */
571
- function getFunctions();
572
-
573
- /**
574
- * Returns a list of operators to add to the existing list.
575
- *
576
- * @return array<array> First array of unary operators, second array of binary operators
577
- */
578
- function getOperators();
579
-
580
- /**
581
- * Returns a list of global variables to add to the existing list.
582
- *
583
- * @return array An array of global variables
584
- */
585
- function getGlobals();
586
-
587
- /**
588
- * Returns the name of the extension.
589
- *
590
- * @return string The extension name
591
- */
592
- function getName();
593
- }
594
-
595
- To keep your extension class clean and lean, it can inherit from the built-in
596
- ``\Twig\Extension\AbstractExtension`` class instead of implementing the whole interface. That
597
- way, you just need to implement the ``getName()`` method as the
598
- ``\Twig\Extension\AbstractExtension`` provides empty implementations for all other methods.
599
-
600
- The ``getName()`` method must return a unique identifier for your extension.
601
-
602
- Now, with this information in mind, let's create the most basic extension
603
- possible::
604
-
605
- class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
606
- {
607
- public function getName()
608
- {
609
- return 'project';
610
- }
611
- }
612
-
613
- .. note::
614
-
615
- This extension does nothing for now. We will customize it in the next sections.
616
-
617
- Twig does not care where you save your extension on the filesystem, as all
618
- extensions must be registered explicitly to be available in your templates.
619
-
620
- You can register an extension by using the ``addExtension()`` method on your
621
- main ``Environment`` object::
622
-
623
- $twig = new \Twig\Environment($loader);
624
- $twig->addExtension(new Project_Twig_Extension());
625
-
626
- Don't forget to load first the extension file by either using ``require_once()``
627
- or by using an autoloader (see `spl_autoload_register()`_).
628
-
629
- .. tip::
630
-
631
- The bundled extensions are great examples of how extensions work.
632
-
633
- Globals
634
- ~~~~~~~
635
-
636
- Global variables can be registered in an extension via the ``getGlobals()``
637
- method::
638
-
639
- class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
640
- {
641
- public function getGlobals()
642
- {
643
- return [
644
- 'text' => new Text(),
645
- ];
646
- }
647
-
648
- // ...
649
- }
650
-
651
- Functions
652
- ~~~~~~~~~
653
-
654
- Functions can be registered in an extension via the ``getFunctions()``
655
- method::
656
-
657
- class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
658
- {
659
- public function getFunctions()
660
- {
661
- return [
662
- 'lipsum' => new Twig_Function_Function('generate_lipsum'),
663
- ];
664
- }
665
-
666
- // ...
667
- }
668
-
669
- Filters
670
- ~~~~~~~
671
-
672
- To add a filter to an extension, you need to override the ``getFilters()``
673
- method. This method must return an array of filters to add to the Twig
674
- environment::
675
-
676
- class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
677
- {
678
- public function getFilters()
679
- {
680
- return [
681
- 'rot13' => new Twig_Filter_Function('str_rot13'),
682
- ];
683
- }
684
-
685
- // ...
686
- }
687
-
688
- As you can see in the above code, the ``getFilters()`` method returns an array
689
- where keys are the name of the filters (``rot13``) and the values the
690
- definition of the filter (``new Twig_Filter_Function('str_rot13')``).
691
-
692
- As seen in the previous chapter, you can also define filters as static methods
693
- on the extension class::
694
-
695
- $twig->addFilter('rot13', new Twig_Filter_Function('Project_Twig_Extension::rot13Filter'));
696
-
697
- You can also use ``Twig_Filter_Method`` instead of ``Twig_Filter_Function``
698
- when defining a filter to use a method::
699
-
700
- class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
701
- {
702
- public function getFilters()
703
- {
704
- return [
705
- 'rot13' => new Twig_Filter_Method($this, 'rot13Filter'),
706
- ];
707
- }
708
-
709
- public function rot13Filter($string)
710
- {
711
- return str_rot13($string);
712
- }
713
-
714
- // ...
715
- }
716
-
717
- The first argument of the ``Twig_Filter_Method`` constructor is always
718
- ``$this``, the current extension object. The second one is the name of the
719
- method to call.
720
-
721
- Using methods for filters is a great way to package your filter without
722
- polluting the global namespace. This also gives the developer more flexibility
723
- at the cost of a small overhead.
724
-
725
- Overriding default Filters
726
- ..........................
727
-
728
- If some default core filters do not suit your needs, you can override
729
- them by creating your own extension. Just use the same names as the one you
730
- want to override::
731
-
732
- class MyCoreExtension extends \Twig\Extension\AbstractExtension
733
- {
734
- public function getFilters()
735
- {
736
- return [
737
- 'date' => new Twig_Filter_Method($this, 'dateFilter'),
738
- // ...
739
- ];
740
- }
741
-
742
- public function dateFilter($timestamp, $format = 'F j, Y H:i')
743
- {
744
- return '...'.twig_date_format_filter($timestamp, $format);
745
- }
746
-
747
- public function getName()
748
- {
749
- return 'project';
750
- }
751
- }
752
-
753
- Here, we override the ``date`` filter with a custom one. Using this extension
754
- is as simple as registering the ``MyCoreExtension`` extension by calling the
755
- ``addExtension()`` method on the environment instance::
756
-
757
- $twig = new \Twig\Environment($loader);
758
- $twig->addExtension(new MyCoreExtension());
759
-
760
- Tags
761
- ~~~~
762
-
763
- Adding a tag in an extension can be done by overriding the
764
- ``getTokenParsers()`` method. This method must return an array of tags to add
765
- to the Twig environment::
766
-
767
- class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
768
- {
769
- public function getTokenParsers()
770
- {
771
- return [new Project_Set_TokenParser()];
772
- }
773
-
774
- // ...
775
- }
776
-
777
- In the above code, we have added a single new tag, defined by the
778
- ``Project_Set_TokenParser`` class. The ``Project_Set_TokenParser`` class is
779
- responsible for parsing the tag and compiling it to PHP.
780
-
781
- Operators
782
- ~~~~~~~~~
783
-
784
- The ``getOperators()`` methods allows to add new operators. Here is how to add
785
- ``!``, ``||``, and ``&&`` operators::
786
-
787
- class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
788
- {
789
- public function getOperators()
790
- {
791
- return [
792
- [
793
- '!' => ['precedence' => 50, 'class' => '\Twig\Node\Expression\Unary\NotUnary'],
794
- ),
795
- [
796
- '||' => ['precedence' => 10, 'class' => '\Twig\Node\Expression\Binary\OrBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT],
797
- '&&' => ['precedence' => 15, 'class' => '\Twig\Node\Expression\Binary\AndBinary', 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT],
798
- ],
799
- ];
800
- }
801
-
802
- // ...
803
- }
804
-
805
- Tests
806
- ~~~~~
807
-
808
- The ``getTests()`` methods allows to add new test functions::
809
-
810
- class Project_Twig_Extension extends \Twig\Extension\AbstractExtension
811
- {
812
- public function getTests()
813
- {
814
- return [
815
- 'even' => new Twig_Test_Function('twig_test_even'),
816
- ];
817
- }
818
-
819
- // ...
820
- }
821
-
822
- Testing an Extension
823
- --------------------
824
-
825
- .. versionadded:: 1.10
826
- Support for functional tests was added in Twig 1.10.
827
-
828
- Functional Tests
829
- ~~~~~~~~~~~~~~~~
830
-
831
- You can create functional tests for extensions by creating the
832
- following file structure in your test directory::
833
-
834
- Fixtures/
835
- filters/
836
- foo.test
837
- bar.test
838
- functions/
839
- foo.test
840
- bar.test
841
- tags/
842
- foo.test
843
- bar.test
844
- IntegrationTest.php
845
-
846
- The ``IntegrationTest.php`` file should look like this::
847
-
848
- class Project_Tests_IntegrationTest extends \Twig\Test\IntegrationTestCase
849
- {
850
- public function getExtensions()
851
- {
852
- return [
853
- new Project_Twig_Extension1(),
854
- new Project_Twig_Extension2(),
855
- ];
856
- }
857
-
858
- public function getFixturesDir()
859
- {
860
- return __DIR__.'/Fixtures/';
861
- }
862
- }
863
-
864
- Fixtures examples can be found within the Twig repository
865
- `tests/Twig/Fixtures`_ directory.
866
-
867
- Node Tests
868
- ~~~~~~~~~~
869
-
870
- Testing the node visitors can be complex, so extend your test cases from
871
- ``\Twig\Test\NodeTestCase``. Examples can be found in the Twig repository
872
- `tests/Twig/Node`_ directory.
873
-
874
- .. _`spl_autoload_register()`: https://secure.php.net/spl_autoload_register
875
- .. _`rot13`: https://secure.php.net/manual/en/function.str-rot13.php
876
- .. _`tests/Twig/Fixtures`: https://github.com/twigphp/Twig/tree/1.x/tests/Fixtures
877
- .. _`tests/Twig/Node`: https://github.com/twigphp/Twig/tree/1.x/tests/Node
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/api.rst DELETED
@@ -1,593 +0,0 @@
1
- Twig for Developers
2
- ===================
3
-
4
- This chapter describes the API to Twig and not the template language. It will
5
- be most useful as reference to those implementing the template interface to
6
- the application and not those who are creating Twig templates.
7
-
8
- Basics
9
- ------
10
-
11
- Twig uses a central object called the **environment** (of class
12
- ``\Twig\Environment``). Instances of this class are used to store the
13
- configuration and extensions, and are used to load templates.
14
-
15
- Most applications create one ``\Twig\Environment`` object on application
16
- initialization and use that to load templates. In some cases, it might be useful
17
- to have multiple environments side by side, with different configurations.
18
-
19
- The typical way to configure Twig to load templates for an application looks
20
- roughly like this::
21
-
22
- require_once '/path/to/vendor/autoload.php';
23
-
24
- $loader = new \Twig\Loader\FilesystemLoader('/path/to/templates');
25
- $twig = new \Twig\Environment($loader, [
26
- 'cache' => '/path/to/compilation_cache',
27
- ]);
28
-
29
- This creates a template environment with a default configuration and a loader
30
- that looks up templates in the ``/path/to/templates/`` directory. Different
31
- loaders are available and you can also write your own if you want to load
32
- templates from a database or other resources.
33
-
34
- .. note::
35
-
36
- Notice that the second argument of the environment is an array of options.
37
- The ``cache`` option is a compilation cache directory, where Twig caches
38
- the compiled templates to avoid the parsing phase for sub-sequent
39
- requests. It is very different from the cache you might want to add for
40
- the evaluated templates. For such a need, you can use any available PHP
41
- cache library.
42
-
43
- Rendering Templates
44
- -------------------
45
-
46
- To load a template from a Twig environment, call the ``load()`` method which
47
- returns a ``\Twig\TemplateWrapper`` instance::
48
-
49
- $template = $twig->load('index.html');
50
-
51
- .. note::
52
-
53
- Before Twig 1.28, use ``loadTemplate()`` instead which returns a
54
- ``\Twig\Template`` instance.
55
-
56
- To render the template with some variables, call the ``render()`` method::
57
-
58
- echo $template->render(['the' => 'variables', 'go' => 'here']);
59
-
60
- .. note::
61
-
62
- The ``display()`` method is a shortcut to output the rendered template.
63
-
64
- You can also load and render the template in one fell swoop::
65
-
66
- echo $twig->render('index.html', ['the' => 'variables', 'go' => 'here']);
67
-
68
- .. versionadded:: 1.28
69
- The possibility to render blocks from the API was added in Twig 1.28.
70
-
71
- If a template defines blocks, they can be rendered individually via the
72
- ``renderBlock()`` call::
73
-
74
- echo $template->renderBlock('block_name', ['the' => 'variables', 'go' => 'here']);
75
-
76
- .. _environment_options:
77
-
78
- Environment Options
79
- -------------------
80
-
81
- When creating a new ``\Twig\Environment`` instance, you can pass an array of
82
- options as the constructor second argument::
83
-
84
- $twig = new \Twig\Environment($loader, ['debug' => true]);
85
-
86
- The following options are available:
87
-
88
- * ``debug`` *boolean*
89
-
90
- When set to ``true``, the generated templates have a
91
- ``__toString()`` method that you can use to display the generated nodes
92
- (default to ``false``).
93
-
94
- * ``charset`` *string* (defaults to ``utf-8``)
95
-
96
- The charset used by the templates.
97
-
98
- * ``base_template_class`` *string* (defaults to ``\Twig\Template``)
99
-
100
- The base template class to use for generated
101
- templates.
102
-
103
- * ``cache`` *string* or ``false``
104
-
105
- An absolute path where to store the compiled templates, or
106
- ``false`` to disable caching (which is the default).
107
-
108
- * ``auto_reload`` *boolean*
109
-
110
- When developing with Twig, it's useful to recompile the
111
- template whenever the source code changes. If you don't provide a value for
112
- the ``auto_reload`` option, it will be determined automatically based on the
113
- ``debug`` value.
114
-
115
- * ``strict_variables`` *boolean*
116
-
117
- If set to ``false``, Twig will silently ignore invalid
118
- variables (variables and or attributes/methods that do not exist) and
119
- replace them with a ``null`` value. When set to ``true``, Twig throws an
120
- exception instead (default to ``false``).
121
-
122
- * ``autoescape`` *string* or *boolean*
123
-
124
- If set to ``true``, HTML auto-escaping will be enabled by
125
- default for all templates (default to ``true``).
126
-
127
- As of Twig 1.8, you can set the escaping strategy to use (``html``, ``js``,
128
- ``false`` to disable).
129
-
130
- As of Twig 1.9, you can set the escaping strategy to use (``css``, ``url``,
131
- ``html_attr``, or a PHP callback that takes the template name and must
132
- return the escaping strategy to use -- the callback cannot be a function name
133
- to avoid collision with built-in escaping strategies).
134
-
135
- As of Twig 1.17, the ``filename`` escaping strategy (renamed to ``name`` as
136
- of Twig 1.27) determines the escaping strategy to use for a template based on
137
- the template filename extension (this strategy does not incur any overhead at
138
- runtime as auto-escaping is done at compilation time.)
139
-
140
- * ``optimizations`` *integer*
141
-
142
- A flag that indicates which optimizations to apply
143
- (default to ``-1`` -- all optimizations are enabled; set it to ``0`` to
144
- disable).
145
-
146
- Loaders
147
- -------
148
-
149
- Loaders are responsible for loading templates from a resource such as the file
150
- system.
151
-
152
- Compilation Cache
153
- ~~~~~~~~~~~~~~~~~
154
-
155
- All template loaders can cache the compiled templates on the filesystem for
156
- future reuse. It speeds up Twig a lot as templates are only compiled once; and
157
- the performance boost is even larger if you use a PHP accelerator such as
158
- OPCache. See the ``cache`` and ``auto_reload`` options of ``\Twig\Environment``
159
- above for more information.
160
-
161
- Built-in Loaders
162
- ~~~~~~~~~~~~~~~~
163
-
164
- Here is a list of the built-in loaders:
165
-
166
- ``\Twig\Loader\FilesystemLoader``
167
- .................................
168
-
169
- .. versionadded:: 1.10
170
- The ``prependPath()`` and support for namespaces were added in Twig 1.10.
171
-
172
- .. versionadded:: 1.27
173
- Relative paths support was added in Twig 1.27.
174
-
175
- ``\Twig\Loader\FilesystemLoader`` loads templates from the file system. This loader
176
- can find templates in folders on the file system and is the preferred way to
177
- load them::
178
-
179
- $loader = new \Twig\Loader\FilesystemLoader($templateDir);
180
-
181
- It can also look for templates in an array of directories::
182
-
183
- $loader = new \Twig\Loader\FilesystemLoader([$templateDir1, $templateDir2]);
184
-
185
- With such a configuration, Twig will first look for templates in
186
- ``$templateDir1`` and if they do not exist, it will fallback to look for them
187
- in the ``$templateDir2``.
188
-
189
- You can add or prepend paths via the ``addPath()`` and ``prependPath()``
190
- methods::
191
-
192
- $loader->addPath($templateDir3);
193
- $loader->prependPath($templateDir4);
194
-
195
- The filesystem loader also supports namespaced templates. This allows to group
196
- your templates under different namespaces which have their own template paths.
197
-
198
- When using the ``setPaths()``, ``addPath()``, and ``prependPath()`` methods,
199
- specify the namespace as the second argument (when not specified, these
200
- methods act on the "main" namespace)::
201
-
202
- $loader->addPath($templateDir, 'admin');
203
-
204
- Namespaced templates can be accessed via the special
205
- ``@namespace_name/template_path`` notation::
206
-
207
- $twig->render('@admin/index.html', []);
208
-
209
- ``\Twig\Loader\FilesystemLoader`` support absolute and relative paths. Using relative
210
- paths is preferred as it makes the cache keys independent of the project root
211
- directory (for instance, it allows warming the cache from a build server where
212
- the directory might be different from the one used on production servers)::
213
-
214
- $loader = new \Twig\Loader\FilesystemLoader('templates', getcwd().'/..');
215
-
216
- .. note::
217
-
218
- When not passing the root path as a second argument, Twig uses ``getcwd()``
219
- for relative paths.
220
-
221
- ``\Twig\Loader\ArrayLoader``
222
- ............................
223
-
224
- ``\Twig\Loader\ArrayLoader`` loads a template from a PHP array. It is passed an
225
- array of strings bound to template names::
226
-
227
- $loader = new \Twig\Loader\ArrayLoader([
228
- 'index.html' => 'Hello {{ name }}!',
229
- ]);
230
- $twig = new \Twig\Environment($loader);
231
-
232
- echo $twig->render('index.html', ['name' => 'Fabien']);
233
-
234
- This loader is very useful for unit testing. It can also be used for small
235
- projects where storing all templates in a single PHP file might make sense.
236
-
237
- .. tip::
238
-
239
- When using the ``Array`` loaders with a cache mechanism, you should know
240
- that a new cache key is generated each time a template content "changes"
241
- (the cache key being the source code of the template). If you don't want to
242
- see your cache grows out of control, you need to take care of clearing the
243
- old cache file by yourself.
244
-
245
- ``\Twig\Loader\ChainLoader``
246
- ............................
247
-
248
- ``\Twig\Loader\ChainLoader`` delegates the loading of templates to other loaders::
249
-
250
- $loader1 = new \Twig\Loader\ArrayLoader([
251
- 'base.html' => '{% block content %}{% endblock %}',
252
- ]);
253
- $loader2 = new \Twig\Loader\ArrayLoader([
254
- 'index.html' => '{% extends "base.html" %}{% block content %}Hello {{ name }}{% endblock %}',
255
- 'base.html' => 'Will never be loaded',
256
- ]);
257
-
258
- $loader = new \Twig\Loader\ChainLoader([$loader1, $loader2]);
259
-
260
- $twig = new \Twig\Environment($loader);
261
-
262
- When looking for a template, Twig tries each loader in turn and returns as soon
263
- as the template is found. When rendering the ``index.html`` template from the
264
- above example, Twig will load it with ``$loader2`` but the ``base.html``
265
- template will be loaded from ``$loader1``.
266
-
267
- .. note::
268
-
269
- You can also add loaders via the ``addLoader()`` method.
270
-
271
- Create your own Loader
272
- ~~~~~~~~~~~~~~~~~~~~~~
273
-
274
- All loaders implement the ``\Twig\Loader\LoaderInterface``::
275
-
276
- interface Twig_LoaderInterface
277
- {
278
- /**
279
- * Gets the source code of a template, given its name.
280
- *
281
- * @param string $name string The name of the template to load
282
- *
283
- * @return string The template source code
284
- *
285
- * @deprecated since 1.27 (to be removed in 2.0), implement \Twig\Loader\SourceContextLoaderInterface
286
- */
287
- function getSource($name);
288
-
289
- /**
290
- * Gets the cache key to use for the cache for a given template name.
291
- *
292
- * @param string $name string The name of the template to load
293
- *
294
- * @return string The cache key
295
- */
296
- function getCacheKey($name);
297
-
298
- /**
299
- * Returns true if the template is still fresh.
300
- *
301
- * @param string $name The template name
302
- * @param timestamp $time The last modification time of the cached template
303
- */
304
- function isFresh($name, $time);
305
- }
306
-
307
- The ``isFresh()`` method must return ``true`` if the current cached template
308
- is still fresh, given the last modification time, or ``false`` otherwise.
309
-
310
- .. note::
311
-
312
- As of Twig 1.27, you should also implement
313
- ``\Twig\Loader\SourceContextLoaderInterface`` to avoid deprecation notices.
314
-
315
- .. tip::
316
-
317
- As of Twig 1.11.0, you can also implement ``\Twig\Loader\ExistsLoaderInterface``
318
- to make your loader faster when used with the chain loader.
319
-
320
- Using Extensions
321
- ----------------
322
-
323
- Twig extensions are packages that add new features to Twig. Register an
324
- extension via the ``addExtension()`` method::
325
-
326
- $twig->addExtension(new \Twig\Extension\SandboxExtension());
327
-
328
- Twig comes bundled with the following extensions:
329
-
330
- * *Twig\Extension\CoreExtension*: Defines all the core features of Twig.
331
-
332
- * *Twig\Extension\DebugExtension*: Defines the ``dump`` function to help debug
333
- template variables.
334
-
335
- * *Twig\Extension\EscaperExtension*: Adds automatic output-escaping and the
336
- possibility to escape/unescape blocks of code.
337
-
338
- * *Twig\Extension\SandboxExtension*: Adds a sandbox mode to the default Twig
339
- environment, making it safe to evaluate untrusted code.
340
-
341
- * *Twig\Extension\ProfilerExtension*: Enabled the built-in Twig profiler (as of
342
- Twig 1.18).
343
-
344
- * *Twig\Extension\OptimizerExtension*: Optimizes the node tree before
345
- compilation.
346
-
347
- * *Twig\Extension\StringLoaderExtension*: Defined the ``template_from_string``
348
- function to allow loading templates from string in a template.
349
-
350
- The Core, Escaper, and Optimizer extensions are registered by default.
351
-
352
- Built-in Extensions
353
- -------------------
354
-
355
- This section describes the features added by the built-in extensions.
356
-
357
- .. tip::
358
-
359
- Read the chapter about :doc:`extending Twig <advanced>` to learn how to
360
- create your own extensions.
361
-
362
- Core Extension
363
- ~~~~~~~~~~~~~~
364
-
365
- The ``core`` extension defines all the core features of Twig:
366
-
367
- * :doc:`Tags <tags/index>`;
368
- * :doc:`Filters <filters/index>`;
369
- * :doc:`Functions <functions/index>`;
370
- * :doc:`Tests <tests/index>`.
371
-
372
- Escaper Extension
373
- ~~~~~~~~~~~~~~~~~
374
-
375
- The ``escaper`` extension adds automatic output escaping to Twig. It defines a
376
- tag, ``autoescape``, and a filter, ``raw``.
377
-
378
- When creating the escaper extension, you can switch on or off the global
379
- output escaping strategy::
380
-
381
- $escaper = new \Twig\Extension\EscaperExtension('html');
382
- $twig->addExtension($escaper);
383
-
384
- If set to ``html``, all variables in templates are escaped (using the ``html``
385
- escaping strategy), except those using the ``raw`` filter:
386
-
387
- .. code-block:: twig
388
-
389
- {{ article.to_html|raw }}
390
-
391
- You can also change the escaping mode locally by using the ``autoescape`` tag
392
- (see the :doc:`autoescape<tags/autoescape>` doc for the syntax used before
393
- Twig 1.8):
394
-
395
- .. code-block:: twig
396
-
397
- {% autoescape 'html' %}
398
- {{ var }}
399
- {{ var|raw }} {# var won't be escaped #}
400
- {{ var|escape }} {# var won't be double-escaped #}
401
- {% endautoescape %}
402
-
403
- .. warning::
404
-
405
- The ``autoescape`` tag has no effect on included files.
406
-
407
- The escaping rules are implemented as follows:
408
-
409
- * Literals (integers, booleans, arrays, ...) used in the template directly as
410
- variables or filter arguments are never automatically escaped:
411
-
412
- .. code-block:: twig
413
-
414
- {{ "Twig<br />" }} {# won't be escaped #}
415
-
416
- {% set text = "Twig<br />" %}
417
- {{ text }} {# will be escaped #}
418
-
419
- * Expressions which the result is a literal or a variable marked safe
420
- are never automatically escaped:
421
-
422
- .. code-block:: twig
423
-
424
- {{ foo ? "Twig<br />" : "<br />Twig" }} {# won't be escaped #}
425
-
426
- {% set text = "Twig<br />" %}
427
- {{ true ? text : "<br />Twig" }} {# will be escaped #}
428
- {{ false ? text : "<br />Twig" }} {# won't be escaped #}
429
-
430
- {% set text = "Twig<br />" %}
431
- {{ foo ? text|raw : "<br />Twig" }} {# won't be escaped #}
432
-
433
- * Escaping is applied before printing, after any other filter is applied:
434
-
435
- .. code-block:: twig
436
-
437
- {{ var|upper }} {# is equivalent to {{ var|upper|escape }} #}
438
-
439
- * The `raw` filter should only be used at the end of the filter chain:
440
-
441
- .. code-block:: twig
442
-
443
- {{ var|raw|upper }} {# will be escaped #}
444
-
445
- {{ var|upper|raw }} {# won't be escaped #}
446
-
447
- * Automatic escaping is not applied if the last filter in the chain is marked
448
- safe for the current context (e.g. ``html`` or ``js``). ``escape`` and
449
- ``escape('html')`` are marked safe for HTML, ``escape('js')`` is marked
450
- safe for JavaScript, ``raw`` is marked safe for everything.
451
-
452
- .. code-block:: twig
453
-
454
- {% autoescape 'js' %}
455
- {{ var|escape('html') }} {# will be escaped for HTML and JavaScript #}
456
- {{ var }} {# will be escaped for JavaScript #}
457
- {{ var|escape('js') }} {# won't be double-escaped #}
458
- {% endautoescape %}
459
-
460
- .. note::
461
-
462
- Note that autoescaping has some limitations as escaping is applied on
463
- expressions after evaluation. For instance, when working with
464
- concatenation, ``{{ foo|raw ~ bar }}`` won't give the expected result as
465
- escaping is applied on the result of the concatenation, not on the
466
- individual variables (so, the ``raw`` filter won't have any effect here).
467
-
468
- Sandbox Extension
469
- ~~~~~~~~~~~~~~~~~
470
-
471
- The ``sandbox`` extension can be used to evaluate untrusted code. Access to
472
- unsafe attributes and methods is prohibited. The sandbox security is managed
473
- by a policy instance. By default, Twig comes with one policy class:
474
- ``\Twig\Sandbox\SecurityPolicy``. This class allows you to white-list some
475
- tags, filters, properties, and methods::
476
-
477
- $tags = ['if'];
478
- $filters = ['upper'];
479
- $methods = [
480
- 'Article' => ['getTitle', 'getBody'],
481
- ];
482
- $properties = [
483
- 'Article' => ['title', 'body'],
484
- ];
485
- $functions = ['range'];
486
- $policy = new \Twig\Sandbox\SecurityPolicy($tags, $filters, $methods, $properties, $functions);
487
-
488
- With the previous configuration, the security policy will only allow usage of
489
- the ``if`` tag, and the ``upper`` filter. Moreover, the templates will only be
490
- able to call the ``getTitle()`` and ``getBody()`` methods on ``Article``
491
- objects, and the ``title`` and ``body`` public properties. Everything else
492
- won't be allowed and will generate a ``\Twig\Sandbox\SecurityError`` exception.
493
-
494
- The policy object is the first argument of the sandbox constructor::
495
-
496
- $sandbox = new \Twig\Extension\SandboxExtension($policy);
497
- $twig->addExtension($sandbox);
498
-
499
- By default, the sandbox mode is disabled and should be enabled when including
500
- untrusted template code by using the ``sandbox`` tag:
501
-
502
- .. code-block:: twig
503
-
504
- {% sandbox %}
505
- {% include 'user.html' %}
506
- {% endsandbox %}
507
-
508
- You can sandbox all templates by passing ``true`` as the second argument of
509
- the extension constructor::
510
-
511
- $sandbox = new \Twig\Extension\SandboxExtension($policy, true);
512
-
513
- Profiler Extension
514
- ~~~~~~~~~~~~~~~~~~
515
-
516
- .. versionadded:: 1.18
517
- The Profile extension was added in Twig 1.18.
518
-
519
- The ``profiler`` extension enables a profiler for Twig templates; it should
520
- only be used on your development machines as it adds some overhead::
521
-
522
- $profile = new \Twig\Profiler\Profile();
523
- $twig->addExtension(new \Twig\Extension\ProfilerExtension($profile));
524
-
525
- $dumper = new \Twig\Profiler\Dumper\TextDumper();
526
- echo $dumper->dump($profile);
527
-
528
- A profile contains information about time and memory consumption for template,
529
- block, and macro executions.
530
-
531
- You can also dump the data in a `Blackfire.io <https://blackfire.io/>`_
532
- compatible format::
533
-
534
- $dumper = new \Twig\Profiler\Dumper\BlackfireDumper();
535
- file_put_contents('/path/to/profile.prof', $dumper->dump($profile));
536
-
537
- Upload the profile to visualize it (create a `free account
538
- <https://blackfire.io/signup?utm_source=twig&utm_medium=doc&utm_campaign=profiler>`_
539
- first):
540
-
541
- .. code-block:: sh
542
-
543
- blackfire --slot=7 upload /path/to/profile.prof
544
-
545
- Optimizer Extension
546
- ~~~~~~~~~~~~~~~~~~~
547
-
548
- The ``optimizer`` extension optimizes the node tree before compilation::
549
-
550
- $twig->addExtension(new \Twig\Extension\OptimizerExtension());
551
-
552
- By default, all optimizations are turned on. You can select the ones you want
553
- to enable by passing them to the constructor::
554
-
555
- $optimizer = new \Twig\Extension\OptimizerExtension(\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_FOR);
556
-
557
- $twig->addExtension($optimizer);
558
-
559
- Twig supports the following optimizations:
560
-
561
- * ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_ALL``, enables all optimizations
562
- (this is the default value).
563
-
564
- * ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_NONE``, disables all optimizations.
565
- This reduces the compilation time, but it can increase the execution time
566
- and the consumed memory.
567
-
568
- * ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_FOR``, optimizes the ``for`` tag by
569
- removing the ``loop`` variable creation whenever possible.
570
-
571
- * ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_RAW_FILTER``, removes the ``raw``
572
- filter whenever possible.
573
-
574
- * ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_VAR_ACCESS``, simplifies the creation
575
- and access of variables in the compiled templates whenever possible.
576
-
577
- Exceptions
578
- ----------
579
-
580
- Twig can throw exceptions:
581
-
582
- * ``\Twig\Error\Error``: The base exception for all errors.
583
-
584
- * ``\Twig\Error\SyntaxError``: Thrown to tell the user that there is a problem with
585
- the template syntax.
586
-
587
- * ``\Twig\Error\RuntimeError``: Thrown when an error occurs at runtime (when a filter
588
- does not exist for instance).
589
-
590
- * ``\Twig\Error\LoaderError``: Thrown when an error occurs during template loading.
591
-
592
- * ``\Twig\Sandbox\SecurityError``: Thrown when an unallowed tag, filter, or
593
- method is called in a sandboxed template.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/coding_standards.rst DELETED
@@ -1,101 +0,0 @@
1
- Coding Standards
2
- ================
3
-
4
- When writing Twig templates, we recommend you to follow these official coding
5
- standards:
6
-
7
- * Put one (and only one) space after the start of a delimiter (``{{``, ``{%``,
8
- and ``{#``) and before the end of a delimiter (``}}``, ``%}``, and ``#}``):
9
-
10
- .. code-block:: twig
11
-
12
- {{ foo }}
13
- {# comment #}
14
- {% if foo %}{% endif %}
15
-
16
- When using the whitespace control character, do not put any spaces between
17
- it and the delimiter:
18
-
19
- .. code-block:: twig
20
-
21
- {{- foo -}}
22
- {#- comment -#}
23
- {%- if foo -%}{%- endif -%}
24
-
25
- * Put one (and only one) space before and after the following operators:
26
- comparison operators (``==``, ``!=``, ``<``, ``>``, ``>=``, ``<=``), math
27
- operators (``+``, ``-``, ``/``, ``*``, ``%``, ``//``, ``**``), logic
28
- operators (``not``, ``and``, ``or``), ``~``, ``is``, ``in``, and the ternary
29
- operator (``?:``):
30
-
31
- .. code-block:: twig
32
-
33
- {{ 1 + 2 }}
34
- {{ foo ~ bar }}
35
- {{ true ? true : false }}
36
-
37
- * Put one (and only one) space after the ``:`` sign in hashes and ``,`` in
38
- arrays and hashes:
39
-
40
- .. code-block:: twig
41
-
42
- {{ [1, 2, 3] }}
43
- {{ {'foo': 'bar'} }}
44
-
45
- * Do not put any spaces after an opening parenthesis and before a closing
46
- parenthesis in expressions:
47
-
48
- .. code-block:: twig
49
-
50
- {{ 1 + (2 * 3) }}
51
-
52
- * Do not put any spaces before and after string delimiters:
53
-
54
- .. code-block:: twig
55
-
56
- {{ 'foo' }}
57
- {{ "foo" }}
58
-
59
- * Do not put any spaces before and after the following operators: ``|``,
60
- ``.``, ``..``, ``[]``:
61
-
62
- .. code-block:: twig
63
-
64
- {{ foo|upper|lower }}
65
- {{ user.name }}
66
- {{ user[name] }}
67
- {% for i in 1..12 %}{% endfor %}
68
-
69
- * Do not put any spaces before and after the parenthesis used for filter and
70
- function calls:
71
-
72
- .. code-block:: twig
73
-
74
- {{ foo|default('foo') }}
75
- {{ range(1..10) }}
76
-
77
- * Do not put any spaces before and after the opening and the closing of arrays
78
- and hashes:
79
-
80
- .. code-block:: twig
81
-
82
- {{ [1, 2, 3] }}
83
- {{ {'foo': 'bar'} }}
84
-
85
- * Use lower cased and underscored variable names:
86
-
87
- .. code-block:: twig
88
-
89
- {% set foo = 'foo' %}
90
- {% set foo_bar = 'foo' %}
91
-
92
- * Indent your code inside tags (use the same indentation as the one used for
93
- the target language of the rendered template):
94
-
95
- .. code-block:: twig
96
-
97
- {% block foo %}
98
- {% if true %}
99
- true
100
- {% endif %}
101
- {% endblock %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/deprecated.rst DELETED
@@ -1,224 +0,0 @@
1
- Deprecated Features
2
- ===================
3
-
4
- This document lists all deprecated features in Twig. Deprecated features are
5
- kept for backward compatibility and removed in the next major release (a
6
- feature that was deprecated in Twig 1.x is removed in Twig 2.0).
7
-
8
- Deprecation Notices
9
- -------------------
10
-
11
- As of Twig 1.21, Twig generates deprecation notices when a template uses
12
- deprecated features. See :ref:`deprecation-notices` for more information.
13
-
14
- Macros
15
- ------
16
-
17
- As of Twig 2.0, macros imported in a file are not available in child templates
18
- anymore (via an ``include`` call for instance). You need to import macros
19
- explicitly in each file where you are using them.
20
-
21
- Token Parsers
22
- -------------
23
-
24
- * As of Twig 1.x, the token parser broker sub-system is deprecated. The
25
- following class and interface will be removed in 2.0:
26
-
27
- * ``Twig_TokenParserBrokerInterface``
28
- * ``Twig_TokenParserBroker``
29
-
30
- * As of Twig 1.27, ``\Twig\Parser::getFilename()`` is deprecated. From a token
31
- parser, use ``$this->parser->getStream()->getSourceContext()->getPath()`` instead.
32
-
33
- * As of Twig 1.27, ``\Twig\Parser::getEnvironment()`` is deprecated.
34
-
35
- Extensions
36
- ----------
37
-
38
- * As of Twig 1.x, the ability to remove an extension is deprecated and the
39
- ``\Twig\Environment::removeExtension()`` method will be removed in 2.0.
40
-
41
- * As of Twig 1.23, the ``\Twig\Extension\ExtensionInterface::initRuntime()`` method is
42
- deprecated. You have two options to avoid the deprecation notice: if you
43
- implement this method to store the environment for your custom filters,
44
- functions, or tests, use the ``needs_environment`` option instead; if you
45
- have more complex needs, explicitly implement
46
- ``\Twig\Extension\InitRuntimeInterface`` (not recommended).
47
-
48
- * As of Twig 1.23, the ``\Twig\Extension\ExtensionInterface::getGlobals()`` method is
49
- deprecated. Implement ``\Twig\Extension\GlobalsInterface`` to avoid
50
- deprecation notices.
51
-
52
- * As of Twig 1.26, the ``\Twig\Extension\ExtensionInterface::getName()`` method is
53
- deprecated and it is not used internally anymore.
54
-
55
- PEAR
56
- ----
57
-
58
- PEAR support has been discontinued in Twig 1.15.1, and no PEAR packages are
59
- provided anymore. Use Composer instead.
60
-
61
- Filters
62
- -------
63
-
64
- * As of Twig 1.x, use ``\Twig\TwigFilter`` to add a filter. The following
65
- classes and interfaces will be removed in 2.0:
66
-
67
- * ``Twig_FilterInterface``
68
- * ``Twig_FilterCallableInterface``
69
- * ``Twig_Filter``
70
- * ``Twig_Filter_Function``
71
- * ``Twig_Filter_Method``
72
- * ``Twig_Filter_Node``
73
-
74
- * As of Twig 2.x, the ``Twig_SimpleFilter`` class is deprecated and will be
75
- removed in Twig 3.x (use ``\Twig\TwigFilter`` instead). In Twig 2.x,
76
- ``Twig_SimpleFilter`` is just an alias for ``\Twig\TwigFilter``.
77
-
78
- Functions
79
- ---------
80
-
81
- * As of Twig 1.x, use ``\Twig\TwigFunction`` to add a function. The following
82
- classes and interfaces will be removed in 2.0:
83
-
84
- * ``Twig_FunctionInterface``
85
- * ``Twig_FunctionCallableInterface``
86
- * ``Twig_Function``
87
- * ``Twig_Function_Function``
88
- * ``Twig_Function_Method``
89
- * ``Twig_Function_Node``
90
-
91
- * As of Twig 2.x, the ``Twig_SimpleFunction`` class is deprecated and will be
92
- removed in Twig 3.x (use ``\Twig\TwigFunction`` instead). In Twig 2.x,
93
- ``Twig_SimpleFunction`` is just an alias for ``\Twig\TwigFunction``.
94
-
95
- Tests
96
- -----
97
-
98
- * As of Twig 1.x, use ``\Twig\TwigTest`` to add a test. The following classes
99
- and interfaces will be removed in 2.0:
100
-
101
- * ``Twig_TestInterface``
102
- * ``Twig_TestCallableInterface``
103
- * ``Twig_Test``
104
- * ``Twig_Test_Function``
105
- * ``Twig_Test_Method``
106
- * ``Twig_Test_Node``
107
-
108
- * As of Twig 2.x, the ``Twig_SimpleTest`` class is deprecated and will be
109
- removed in Twig 3.x (use ``\Twig\TwigTest`` instead). In Twig 2.x,
110
- ``Twig_SimpleTest`` is just an alias for ``\Twig\TwigTest``.
111
-
112
- * The ``sameas`` and ``divisibleby`` tests are deprecated in favor of ``same
113
- as`` and ``divisible by`` respectively.
114
-
115
- Tags
116
- ----
117
-
118
- * As of Twig 1.x, the ``raw`` tag is deprecated. You should use ``verbatim``
119
- instead.
120
-
121
- Nodes
122
- -----
123
-
124
- * As of Twig 1.x, ``Node::toXml()`` is deprecated and will be removed in Twig
125
- 2.0.
126
-
127
- * As of Twig 1.26, ``Node::$nodes`` should only contains ``\Twig\Node\Node``
128
- instances, storing a ``null`` value is deprecated and won't be possible in
129
- Twig 2.x.
130
-
131
- * As of Twig 1.27, the ``filename`` attribute on ``\Twig\Node\ModuleNode`` is
132
- deprecated. Use ``getName()`` instead.
133
-
134
- * As of Twig 1.27, the ``\Twig\Node\Node::getFilename()/\Twig\Node\Node::getLine()``
135
- methods are deprecated, use
136
- ``\Twig\Node\Node::getTemplateName()/\Twig\Node\Node::getTemplateLine()`` instead.
137
-
138
- Interfaces
139
- ----------
140
-
141
- * As of Twig 2.x, the following interfaces are deprecated and empty (they will
142
- be removed in Twig 3.0):
143
-
144
- * ``Twig_CompilerInterface`` (use ``\Twig\Compiler`` instead)
145
- * ``Twig_LexerInterface`` (use ``\Twig\Lexer`` instead)
146
- * ``Twig_NodeInterface`` (use ``\Twig\Node\Node`` instead)
147
- * ``Twig_ParserInterface`` (use ``\Twig\Parser`` instead)
148
- * ``\Twig\Loader\ExistsLoaderInterface`` (merged with ``\Twig\Loader\LoaderInterface``)
149
- * ``\Twig\Loader\SourceContextLoaderInterface`` (merged with ``\Twig\Loader\LoaderInterface``)
150
- * ``Twig_TemplateInterface`` (use ``\Twig\Template`` instead, and use
151
- those constants \Twig\Template::ANY_CALL, \Twig\Template::ARRAY_CALL,
152
- \Twig\Template::METHOD_CALL)
153
-
154
- Compiler
155
- --------
156
-
157
- * As of Twig 1.26, the ``\Twig\Compiler::getFilename()`` has been deprecated.
158
- You should not use it anyway as its values is not reliable.
159
-
160
- * As of Twig 1.27, the ``\Twig\Compiler::addIndentation()`` has been deprecated.
161
- Use ``\Twig\Compiler::write('')`` instead.
162
-
163
- Loaders
164
- -------
165
-
166
- * As of Twig 1.x, ``Twig_Loader_String`` is deprecated and will be removed in
167
- 2.0. You can render a string via ``\Twig\Environment::createTemplate()``.
168
-
169
- * As of Twig 1.27, ``\Twig\Loader\LoaderInterface::getSource()`` is deprecated.
170
- Implement ``\Twig\Loader\SourceContextLoaderInterface`` instead and use
171
- ``getSourceContext()``.
172
-
173
- Node Visitors
174
- -------------
175
-
176
- * Because of the removal of ``Twig_NodeInterface`` in 2.0, you need to extend
177
- ``\Twig\NodeVisitor\AbstractNodeVisitor`` instead of implementing ``\Twig\NodeVisitor\NodeVisitorInterface``
178
- directly to make your node visitors compatible with both Twig 1.x and 2.x.
179
-
180
- Globals
181
- -------
182
-
183
- * As of Twig 2.x, the ability to register a global variable after the runtime
184
- or the extensions have been initialized is not possible anymore (but
185
- changing the value of an already registered global is possible).
186
-
187
- * As of Twig 1.x, using the ``_self`` global variable to get access to the
188
- current ``\Twig\Template`` instance is deprecated; most usages only need the
189
- current template name, which will continue to work in Twig 2.0. In Twig 2.0,
190
- ``_self`` returns the current template name instead of the current
191
- ``\Twig\Template`` instance. If you are using ``{{ _self.templateName }}``,
192
- just replace it with ``{{ _self }}``.
193
-
194
- Miscellaneous
195
- -------------
196
-
197
- * As of Twig 1.x, ``\Twig\Environment::clearTemplateCache()``,
198
- ``\Twig\Environment::writeCacheFile()``,
199
- ``\Twig\Environment::clearCacheFiles()``,
200
- ``\Twig\Environment::getCacheFilename()``,
201
- ``\Twig\Environment::getTemplateClassPrefix()``,
202
- ``\Twig\Environment::getLexer()``, ``\Twig\Environment::getParser()``, and
203
- ``\Twig\Environment::getCompiler()`` are deprecated and will be removed in 2.0.
204
-
205
- * As of Twig 1.x, ``\Twig\Template::getEnvironment()`` and
206
- ``Twig_TemplateInterface::getEnvironment()`` are deprecated and will be
207
- removed in 2.0.
208
-
209
- * As of Twig 1.21, setting the environment option ``autoescape`` to ``true`` is
210
- deprecated and will be removed in 2.0. Use ``"html"`` instead.
211
-
212
- * As of Twig 1.27, ``\Twig\Error\Error::getTemplateFile()`` and
213
- ``\Twig\Error\Error::setTemplateFile()`` are deprecated. Use
214
- ``\Twig\Error\Error::getTemplateName()`` and ``\Twig\Error\Error::setTemplateName()``
215
- instead.
216
-
217
- * As of Twig 1.27, ``\Twig\Template::getSource()`` is deprecated. Use
218
- ``\Twig\Template::getSourceContext()`` instead.
219
-
220
- * As of Twig 1.27, ``\Twig\Parser::addHandler()`` and
221
- ``\Twig\Parser::addNodeVisitor()`` are deprecated and will be removed in 2.0.
222
-
223
- * As of Twig 1.29, some classes are marked as being final via the `@final`
224
- annotation. Those classes will be marked as final in 2.0.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/abs.rst DELETED
@@ -1,18 +0,0 @@
1
- ``abs``
2
- =======
3
-
4
- The ``abs`` filter returns the absolute value.
5
-
6
- .. code-block:: twig
7
-
8
- {# number = -5 #}
9
-
10
- {{ number|abs }}
11
-
12
- {# outputs 5 #}
13
-
14
- .. note::
15
-
16
- Internally, Twig uses the PHP `abs`_ function.
17
-
18
- .. _`abs`: https://secure.php.net/abs
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/batch.rst DELETED
@@ -1,52 +0,0 @@
1
- ``batch``
2
- =========
3
-
4
- .. versionadded:: 1.12.3
5
- The ``batch`` filter was added in Twig 1.12.3.
6
-
7
- The ``batch`` filter "batches" items by returning a list of lists with the
8
- given number of items. A second parameter can be provided and used to fill in
9
- missing items:
10
-
11
- .. code-block:: twig
12
-
13
- {% set items = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] %}
14
-
15
- <table>
16
- {% for row in items|batch(3, 'No item') %}
17
- <tr>
18
- {% for column in row %}
19
- <td>{{ column }}</td>
20
- {% endfor %}
21
- </tr>
22
- {% endfor %}
23
- </table>
24
-
25
- The above example will be rendered as:
26
-
27
- .. code-block:: twig
28
-
29
- <table>
30
- <tr>
31
- <td>a</td>
32
- <td>b</td>
33
- <td>c</td>
34
- </tr>
35
- <tr>
36
- <td>d</td>
37
- <td>e</td>
38
- <td>f</td>
39
- </tr>
40
- <tr>
41
- <td>g</td>
42
- <td>No item</td>
43
- <td>No item</td>
44
- </tr>
45
- </table>
46
-
47
- Arguments
48
- ---------
49
-
50
- * ``size``: The size of the batch; fractional numbers will be rounded up
51
- * ``fill``: Used to fill in missing items
52
- * ``preserve_keys``: Whether to preserve keys or not
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/capitalize.rst DELETED
@@ -1,11 +0,0 @@
1
- ``capitalize``
2
- ==============
3
-
4
- The ``capitalize`` filter capitalizes a value. The first character will be
5
- uppercase, all others lowercase:
6
-
7
- .. code-block:: twig
8
-
9
- {{ 'my first car'|capitalize }}
10
-
11
- {# outputs 'My first car' #}
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/convert_encoding.rst DELETED
@@ -1,28 +0,0 @@
1
- ``convert_encoding``
2
- ====================
3
-
4
- .. versionadded:: 1.4
5
- The ``convert_encoding`` filter was added in Twig 1.4.
6
-
7
- The ``convert_encoding`` filter converts a string from one encoding to
8
- another. The first argument is the expected output charset and the second one
9
- is the input charset:
10
-
11
- .. code-block:: twig
12
-
13
- {{ data|convert_encoding('UTF-8', 'iso-2022-jp') }}
14
-
15
- .. note::
16
-
17
- This filter relies on the `iconv`_ or `mbstring`_ extension, so one of
18
- them must be installed. In case both are installed, `mbstring`_ is used by
19
- default (Twig before 1.8.1 uses `iconv`_ by default).
20
-
21
- Arguments
22
- ---------
23
-
24
- * ``to``: The output charset
25
- * ``from``: The input charset
26
-
27
- .. _`iconv`: https://secure.php.net/iconv
28
- .. _`mbstring`: https://secure.php.net/mbstring
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/date.rst DELETED
@@ -1,100 +0,0 @@
1
- ``date``
2
- ========
3
-
4
- .. versionadded:: 1.1
5
- The timezone support has been added in Twig 1.1.
6
-
7
- .. versionadded:: 1.5
8
- The default date format support has been added in Twig 1.5.
9
-
10
- .. versionadded:: 1.6.1
11
- The default timezone support has been added in Twig 1.6.1.
12
-
13
- .. versionadded:: 1.11.0
14
- The introduction of the false value for the timezone was introduced in Twig 1.11.0
15
-
16
- The ``date`` filter formats a date to a given format:
17
-
18
- .. code-block:: twig
19
-
20
- {{ post.published_at|date("m/d/Y") }}
21
-
22
- The format specifier is the same as supported by `date`_,
23
- except when the filtered data is of type `DateInterval`_, when the format must conform to
24
- `DateInterval::format`_ instead.
25
-
26
- The ``date`` filter accepts strings (it must be in a format supported by the
27
- `strtotime`_ function), `DateTime`_ instances, or `DateInterval`_ instances. For
28
- instance, to display the current date, filter the word "now":
29
-
30
- .. code-block:: twig
31
-
32
- {{ "now"|date("m/d/Y") }}
33
-
34
- To escape words and characters in the date format use ``\\`` in front of each
35
- character:
36
-
37
- .. code-block:: twig
38
-
39
- {{ post.published_at|date("F jS \\a\\t g:ia") }}
40
-
41
- If the value passed to the ``date`` filter is ``null``, it will return the
42
- current date by default. If an empty string is desired instead of the current
43
- date, use a ternary operator:
44
-
45
- .. code-block:: twig
46
-
47
- {{ post.published_at is empty ? "" : post.published_at|date("m/d/Y") }}
48
-
49
- If no format is provided, Twig will use the default one: ``F j, Y H:i``. This
50
- default can be changed by calling the ``setDateFormat()`` method on the
51
- ``core`` extension instance. The first argument is the default format for
52
- dates and the second one is the default format for date intervals:
53
-
54
- .. code-block:: php
55
-
56
- $twig = new \Twig\Environment($loader);
57
- $twig->getExtension('\Twig\Extension\CoreExtension')->setDateFormat('d/m/Y', '%d days');
58
-
59
- // before Twig 1.26
60
- $twig->getExtension('core')->setDateFormat('d/m/Y', '%d days');
61
-
62
- Timezone
63
- --------
64
-
65
- By default, the date is displayed by applying the default timezone (the one
66
- specified in php.ini or declared in Twig -- see below), but you can override
67
- it by explicitly specifying a timezone:
68
-
69
- .. code-block:: twig
70
-
71
- {{ post.published_at|date("m/d/Y", "Europe/Paris") }}
72
-
73
- If the date is already a DateTime object, and if you want to keep its current
74
- timezone, pass ``false`` as the timezone value:
75
-
76
- .. code-block:: twig
77
-
78
- {{ post.published_at|date("m/d/Y", false) }}
79
-
80
- The default timezone can also be set globally by calling ``setTimezone()``:
81
-
82
- .. code-block:: php
83
-
84
- $twig = new \Twig\Environment($loader);
85
- $twig->getExtension('\Twig\Extension\CoreExtension')->setTimezone('Europe/Paris');
86
-
87
- // before Twig 1.26
88
- $twig->getExtension('core')->setTimezone('Europe/Paris');
89
-
90
- Arguments
91
- ---------
92
-
93
- * ``format``: The date format
94
- * ``timezone``: The date timezone
95
-
96
- .. _`strtotime`: https://secure.php.net/strtotime
97
- .. _`DateTime`: https://secure.php.net/DateTime
98
- .. _`DateInterval`: https://secure.php.net/DateInterval
99
- .. _`date`: https://secure.php.net/date
100
- .. _`DateInterval::format`: https://secure.php.net/DateInterval.format
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/date_modify.rst DELETED
@@ -1,23 +0,0 @@
1
- ``date_modify``
2
- ===============
3
-
4
- .. versionadded:: 1.9.0
5
- The date_modify filter has been added in Twig 1.9.0.
6
-
7
- The ``date_modify`` filter modifies a date with a given modifier string:
8
-
9
- .. code-block:: twig
10
-
11
- {{ post.published_at|date_modify("+1 day")|date("m/d/Y") }}
12
-
13
- The ``date_modify`` filter accepts strings (it must be in a format supported
14
- by the `strtotime`_ function) or `DateTime`_ instances. You can combine
15
- it with the :doc:`date<date>` filter for formatting.
16
-
17
- Arguments
18
- ---------
19
-
20
- * ``modifier``: The modifier
21
-
22
- .. _`strtotime`: https://secure.php.net/strtotime
23
- .. _`DateTime`: https://secure.php.net/DateTime
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/default.rst DELETED
@@ -1,33 +0,0 @@
1
- ``default``
2
- ===========
3
-
4
- The ``default`` filter returns the passed default value if the value is
5
- undefined or empty, otherwise the value of the variable:
6
-
7
- .. code-block:: twig
8
-
9
- {{ var|default('var is not defined') }}
10
-
11
- {{ var.foo|default('foo item on var is not defined') }}
12
-
13
- {{ var['foo']|default('foo item on var is not defined') }}
14
-
15
- {{ ''|default('passed var is empty') }}
16
-
17
- When using the ``default`` filter on an expression that uses variables in some
18
- method calls, be sure to use the ``default`` filter whenever a variable can be
19
- undefined:
20
-
21
- .. code-block:: twig
22
-
23
- {{ var.method(foo|default('foo'))|default('foo') }}
24
-
25
- .. note::
26
-
27
- Read the documentation for the :doc:`defined<../tests/defined>` and
28
- :doc:`empty<../tests/empty>` tests to learn more about their semantics.
29
-
30
- Arguments
31
- ---------
32
-
33
- * ``default``: The default value
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/escape.rst DELETED
@@ -1,129 +0,0 @@
1
- ``escape``
2
- ==========
3
-
4
- .. versionadded:: 1.9.0
5
- The ``css``, ``url``, and ``html_attr`` strategies were added in Twig
6
- 1.9.0.
7
-
8
- .. versionadded:: 1.14.0
9
- The ability to define custom escapers was added in Twig 1.14.0.
10
-
11
- The ``escape`` filter escapes a string using strategies that depend on the
12
- context.
13
-
14
- By default, it uses the HTML escaping strategy:
15
-
16
- .. code-block:: html+twig
17
-
18
- <p>
19
- {{ user.username|escape }}
20
- </p>
21
-
22
- For convenience, the ``e`` filter is defined as an alias:
23
-
24
- .. code-block:: html+twig
25
-
26
- <p>
27
- {{ user.username|e }}
28
- </p>
29
-
30
- The ``escape`` filter can also be used in other contexts than HTML thanks to
31
- an optional argument which defines the escaping strategy to use:
32
-
33
- .. code-block:: twig
34
-
35
- {{ user.username|e }}
36
- {# is equivalent to #}
37
- {{ user.username|e('html') }}
38
-
39
- And here is how to escape variables included in JavaScript code:
40
-
41
- .. code-block:: twig
42
-
43
- {{ user.username|escape('js') }}
44
- {{ user.username|e('js') }}
45
-
46
- The ``escape`` filter supports the following escaping strategies for HTML
47
- documents:
48
-
49
- * ``html``: escapes a string for the **HTML body** context.
50
-
51
- * ``js``: escapes a string for the **JavaScript** context.
52
-
53
- * ``css``: escapes a string for the **CSS** context. CSS escaping can be
54
- applied to any string being inserted into CSS and escapes everything except
55
- alphanumerics.
56
-
57
- * ``url``: escapes a string for the **URI or parameter** contexts. This should
58
- not be used to escape an entire URI; only a subcomponent being inserted.
59
-
60
- * ``html_attr``: escapes a string for the **HTML attribute** context.
61
-
62
- Note that doing contextual escaping in HTML documents is hard and choosing the
63
- right escaping strategy depends on a lot of factors. Please, read related
64
- documentation like `the OWASP prevention cheat sheet
65
- <https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.md>`_
66
- to learn more about this topic.
67
-
68
- .. note::
69
-
70
- Internally, ``escape`` uses the PHP native `htmlspecialchars`_ function
71
- for the HTML escaping strategy.
72
-
73
- .. caution::
74
-
75
- When using automatic escaping, Twig tries to not double-escape a variable
76
- when the automatic escaping strategy is the same as the one applied by the
77
- escape filter; but that does not work when using a variable as the
78
- escaping strategy:
79
-
80
- .. code-block:: twig
81
-
82
- {% set strategy = 'html' %}
83
-
84
- {% autoescape 'html' %}
85
- {{ var|escape('html') }} {# won't be double-escaped #}
86
- {{ var|escape(strategy) }} {# will be double-escaped #}
87
- {% endautoescape %}
88
-
89
- When using a variable as the escaping strategy, you should disable
90
- automatic escaping:
91
-
92
- .. code-block:: twig
93
-
94
- {% set strategy = 'html' %}
95
-
96
- {% autoescape 'html' %}
97
- {{ var|escape(strategy)|raw }} {# won't be double-escaped #}
98
- {% endautoescape %}
99
-
100
- Custom Escapers
101
- ---------------
102
-
103
- You can define custom escapers by calling the ``setEscaper()`` method on the
104
- ``core`` extension instance. The first argument is the escaper name (to be
105
- used in the ``escape`` call) and the second one must be a valid PHP callable:
106
-
107
- .. code-block:: php
108
-
109
- $twig = new \Twig\Environment($loader);
110
- $twig->getExtension('\Twig\Extension\CoreExtension')->setEscaper('csv', 'csv_escaper');
111
-
112
- // before Twig 1.26
113
- $twig->getExtension('core')->setEscaper('csv', 'csv_escaper');
114
-
115
- When called by Twig, the callable receives the Twig environment instance, the
116
- string to escape, and the charset.
117
-
118
- .. note::
119
-
120
- Built-in escapers cannot be overridden mainly because they should be
121
- considered as the final implementation and also for better performance.
122
-
123
- Arguments
124
- ---------
125
-
126
- * ``strategy``: The escaping strategy
127
- * ``charset``: The string charset
128
-
129
- .. _`htmlspecialchars`: https://secure.php.net/htmlspecialchars
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/filter.rst DELETED
@@ -1,58 +0,0 @@
1
- ``filter``
2
- ==========
3
-
4
- .. versionadded:: 1.41
5
- The ``filter`` filter was added in Twig 1.41 and 2.10.
6
-
7
- The ``filter`` filter filters elements of a sequence or a mapping using an arrow
8
- function. The arrow function receives the value of the sequence or mapping:
9
-
10
- .. code-block:: twig
11
-
12
- {% set sizes = [34, 36, 38, 40, 42] %}
13
-
14
- {{ sizes|filter(v => v > 38)|join(', ') }}
15
- {# output 40, 42 #}
16
-
17
- Combined with the ``for`` tag, it allows to filter the items to iterate over:
18
-
19
- .. code-block:: twig
20
-
21
- {% for v in sizes|filter(v => v > 38) -%}
22
- {{ v }}
23
- {% endfor %}
24
- {# output 40 42 #}
25
-
26
- It also works with mappings:
27
-
28
- .. code-block:: twig
29
-
30
- {% set sizes = {
31
- xs: 34,
32
- s: 36,
33
- m: 38,
34
- l: 40,
35
- xl: 42,
36
- } %}
37
-
38
- {% for k, v in sizes|filter(v => v > 38) -%}
39
- {{ k }} = {{ v }}
40
- {% endfor %}
41
- {# output l = 40 xl = 42 #}
42
-
43
- The arrow function also receives the key as a second argument:
44
-
45
- .. code-block:: twig
46
-
47
- {% for k, v in sizes|filter((v, k) => v > 38 and k != "xl") -%}
48
- {{ k }} = {{ v }}
49
- {% endfor %}
50
- {# output l = 40 #}
51
-
52
- Note that the arrow function has access to the current context.
53
-
54
- Arguments
55
- ---------
56
-
57
- * ``array``: The sequence or mapping
58
- * ``arrow``: The arrow function
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/first.rst DELETED
@@ -1,25 +0,0 @@
1
- ``first``
2
- =========
3
-
4
- .. versionadded:: 1.12.2
5
- The ``first`` filter was added in Twig 1.12.2.
6
-
7
- The ``first`` filter returns the first "element" of a sequence, a mapping, or
8
- a string:
9
-
10
- .. code-block:: twig
11
-
12
- {{ [1, 2, 3, 4]|first }}
13
- {# outputs 1 #}
14
-
15
- {{ { a: 1, b: 2, c: 3, d: 4 }|first }}
16
- {# outputs 1 #}
17
-
18
- {{ '1234'|first }}
19
- {# outputs 1 #}
20
-
21
- .. note::
22
-
23
- It also works with objects implementing the `Traversable`_ interface.
24
-
25
- .. _`Traversable`: https://secure.php.net/manual/en/class.traversable.php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/format.rst DELETED
@@ -1,16 +0,0 @@
1
- ``format``
2
- ==========
3
-
4
- The ``format`` filter formats a given string by replacing the placeholders
5
- (placeholders follows the `sprintf`_ notation):
6
-
7
- .. code-block:: twig
8
-
9
- {{ "I like %s and %s."|format(foo, "bar") }}
10
-
11
- {# outputs I like foo and bar
12
- if the foo parameter equals to the foo string. #}
13
-
14
- .. _`sprintf`: https://secure.php.net/sprintf
15
-
16
- .. seealso:: :doc:`replace<replace>`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/index.rst DELETED
@@ -1,41 +0,0 @@
1
- Filters
2
- =======
3
-
4
- .. toctree::
5
- :maxdepth: 1
6
-
7
- abs
8
- batch
9
- capitalize
10
- convert_encoding
11
- date
12
- date_modify
13
- default
14
- escape
15
- filter
16
- first
17
- format
18
- join
19
- json_encode
20
- keys
21
- last
22
- length
23
- lower
24
- map
25
- merge
26
- nl2br
27
- number_format
28
- raw
29
- reduce
30
- replace
31
- reverse
32
- round
33
- slice
34
- sort
35
- spaceless
36
- split
37
- striptags
38
- title
39
- trim
40
- upper
41
- url_encode
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/join.rst DELETED
@@ -1,35 +0,0 @@
1
- ``join``
2
- ========
3
-
4
- .. versionadded:: 1.37 and 2.6.1
5
- The ``and`` argument was added in Twig 1.37 and 2.6.1.
6
-
7
- The ``join`` filter returns a string which is the concatenation of the items
8
- of a sequence:
9
-
10
- .. code-block:: twig
11
-
12
- {{ [1, 2, 3]|join }}
13
- {# returns 123 #}
14
-
15
- The separator between elements is an empty string per default, but you can
16
- define it with the optional first parameter:
17
-
18
- .. code-block:: twig
19
-
20
- {{ [1, 2, 3]|join('|') }}
21
- {# outputs 1|2|3 #}
22
-
23
- A second parameter can also be provided that will be the separator used between
24
- the last two items of the sequence:
25
-
26
- .. code-block:: twig
27
-
28
- {{ [1, 2, 3]|join(', ', ' and ') }}
29
- {# outputs 1, 2 and 3 #}
30
-
31
- Arguments
32
- ---------
33
-
34
- * ``glue``: The separator
35
- * ``and``: The separator for the last pair of input items
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/json_encode.rst DELETED
@@ -1,23 +0,0 @@
1
- ``json_encode``
2
- ===============
3
-
4
- The ``json_encode`` filter returns the JSON representation of a value:
5
-
6
- .. code-block:: twig
7
-
8
- {{ data|json_encode() }}
9
-
10
- .. note::
11
-
12
- Internally, Twig uses the PHP `json_encode`_ function.
13
-
14
- Arguments
15
- ---------
16
-
17
- * ``options``: A bitmask of `json_encode options`_: ``{{
18
- data|json_encode(constant('JSON_PRETTY_PRINT')) }}``.
19
- Combine constants using :ref:`bitwise operators<template_logic>`:
20
- ``{{ data|json_encode(constant('JSON_PRETTY_PRINT') b-or constant('JSON_HEX_QUOT')) }}``
21
-
22
- .. _`json_encode`: https://secure.php.net/json_encode
23
- .. _`json_encode options`: https://secure.php.net/manual/en/json.constants.php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/keys.rst DELETED
@@ -1,11 +0,0 @@
1
- ``keys``
2
- ========
3
-
4
- The ``keys`` filter returns the keys of an array. It is useful when you want to
5
- iterate over the keys of an array:
6
-
7
- .. code-block:: twig
8
-
9
- {% for key in array|keys %}
10
- ...
11
- {% endfor %}
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/last.rst DELETED
@@ -1,25 +0,0 @@
1
- ``last``
2
- ========
3
-
4
- .. versionadded:: 1.12.2
5
- The ``last`` filter was added in Twig 1.12.2.
6
-
7
- The ``last`` filter returns the last "element" of a sequence, a mapping, or
8
- a string:
9
-
10
- .. code-block:: twig
11
-
12
- {{ [1, 2, 3, 4]|last }}
13
- {# outputs 4 #}
14
-
15
- {{ { a: 1, b: 2, c: 3, d: 4 }|last }}
16
- {# outputs 4 #}
17
-
18
- {{ '1234'|last }}
19
- {# outputs 4 #}
20
-
21
- .. note::
22
-
23
- It also works with objects implementing the `Traversable`_ interface.
24
-
25
- .. _`Traversable`: https://secure.php.net/manual/en/class.traversable.php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/length.rst DELETED
@@ -1,23 +0,0 @@
1
- ``length``
2
- ==========
3
-
4
- .. versionadded:: 1.33
5
-
6
- Support for the ``__toString()`` magic method has been added in Twig 1.33.
7
-
8
- The ``length`` filter returns the number of items of a sequence or mapping, or
9
- the length of a string.
10
-
11
- For objects that implement the ``Countable`` interface, ``length`` will use the
12
- return value of the ``count()`` method.
13
-
14
- For objects that implement the ``__toString()`` magic method (and not ``Countable``),
15
- it will return the length of the string provided by that method.
16
-
17
- For objects that implement the ``IteratorAggregate`` interface, ``length`` will use the return value of the ``iterator_count()`` method.
18
-
19
- .. code-block:: twig
20
-
21
- {% if users|length > 10 %}
22
- ...
23
- {% endif %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/lower.rst DELETED
@@ -1,10 +0,0 @@
1
- ``lower``
2
- =========
3
-
4
- The ``lower`` filter converts a value to lowercase:
5
-
6
- .. code-block:: twig
7
-
8
- {{ 'WELCOME'|lower }}
9
-
10
- {# outputs 'welcome' #}
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/map.rst DELETED
@@ -1,37 +0,0 @@
1
- ``map``
2
- =======
3
-
4
- .. versionadded:: 1.41
5
- The ``map`` filter was added in Twig 1.41 and 2.10.
6
-
7
- The ``map`` filter applies an arrow function to the elements of a sequence or a
8
- mapping. The arrow function receives the value of the sequence or mapping:
9
-
10
- .. code-block:: twig
11
-
12
- {% set people = [
13
- {first: "Bob", last: "Smith"},
14
- {first: "Alice", last: "Dupond"},
15
- ] %}
16
-
17
- {{ people|map(p => "#{p.first} #{p.last}")|join(', ') }}
18
- {# outputs Bob Smith, Alice Dupond #}
19
-
20
- The arrow function also receives the key as a second argument:
21
-
22
- .. code-block:: twig
23
-
24
- {% set people = {
25
- "Bob": "Smith",
26
- "Alice": "Dupond",
27
- } %}
28
-
29
- {{ people|map((last, first) => "#{first} #{last}")|join(', ') }}
30
- {# outputs Bob Smith, Alice Dupond #}
31
-
32
- Note that the arrow function has access to the current context.
33
-
34
- Arguments
35
- ---------
36
-
37
- * ``arrow``: The arrow function
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/merge.rst DELETED
@@ -1,48 +0,0 @@
1
- ``merge``
2
- =========
3
-
4
- The ``merge`` filter merges an array with another array:
5
-
6
- .. code-block:: twig
7
-
8
- {% set values = [1, 2] %}
9
-
10
- {% set values = values|merge(['apple', 'orange']) %}
11
-
12
- {# values now contains [1, 2, 'apple', 'orange'] #}
13
-
14
- New values are added at the end of the existing ones.
15
-
16
- The ``merge`` filter also works on hashes:
17
-
18
- .. code-block:: twig
19
-
20
- {% set items = { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'unknown' } %}
21
-
22
- {% set items = items|merge({ 'peugeot': 'car', 'renault': 'car' }) %}
23
-
24
- {# items now contains { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'car', 'renault': 'car' } #}
25
-
26
- For hashes, the merging process occurs on the keys: if the key does not
27
- already exist, it is added but if the key already exists, its value is
28
- overridden.
29
-
30
- .. tip::
31
-
32
- If you want to ensure that some values are defined in an array (by given
33
- default values), reverse the two elements in the call:
34
-
35
- .. code-block:: twig
36
-
37
- {% set items = { 'apple': 'fruit', 'orange': 'fruit' } %}
38
-
39
- {% set items = { 'apple': 'unknown' }|merge(items) %}
40
-
41
- {# items now contains { 'apple': 'fruit', 'orange': 'fruit' } #}
42
-
43
- .. note::
44
-
45
- Internally, Twig uses the PHP `array_merge`_ function. It supports
46
- Traversable objects by transforming those to arrays.
47
-
48
- .. _`array_merge`: https://secure.php.net/array_merge
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/nl2br.rst DELETED
@@ -1,22 +0,0 @@
1
- ``nl2br``
2
- =========
3
-
4
- .. versionadded:: 1.5
5
- The ``nl2br`` filter was added in Twig 1.5.
6
-
7
- The ``nl2br`` filter inserts HTML line breaks before all newlines in a string:
8
-
9
- .. code-block:: twig
10
-
11
- {{ "I like Twig.\nYou will like it too."|nl2br }}
12
- {# outputs
13
-
14
- I like Twig.<br />
15
- You will like it too.
16
-
17
- #}
18
-
19
- .. note::
20
-
21
- The ``nl2br`` filter pre-escapes the input before applying the
22
- transformation.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/number_format.rst DELETED
@@ -1,56 +0,0 @@
1
- ``number_format``
2
- =================
3
-
4
- .. versionadded:: 1.5
5
- The ``number_format`` filter was added in Twig 1.5
6
-
7
- The ``number_format`` filter formats numbers. It is a wrapper around PHP's
8
- `number_format`_ function:
9
-
10
- .. code-block:: twig
11
-
12
- {{ 200.35|number_format }}
13
-
14
- You can control the number of decimal places, decimal point, and thousands
15
- separator using the additional arguments:
16
-
17
- .. code-block:: twig
18
-
19
- {{ 9800.333|number_format(2, '.', ',') }}
20
-
21
- To format negative numbers, wrap the number with parentheses (needed because of
22
- Twig's :ref:`precedence of operators <twig-expressions>`:
23
-
24
- .. code-block:: twig
25
-
26
- {{ -9800.333|number_format(2, '.', ',') }} {# outputs : -9 #}
27
- {{ (-9800.333)|number_format(2, '.', ',') }} {# outputs : -9,800.33 #}
28
-
29
- If no formatting options are provided then Twig will use the default formatting
30
- options of:
31
-
32
- * 0 decimal places.
33
- * ``.`` as the decimal point.
34
- * ``,`` as the thousands separator.
35
-
36
- These defaults can be changed through the core extension:
37
-
38
- .. code-block:: php
39
-
40
- $twig = new \Twig\Environment($loader);
41
- $twig->getExtension('\Twig\Extension\CoreExtension')->setNumberFormat(3, '.', ',');
42
-
43
- // before Twig 1.26
44
- $twig->getExtension('core')->setNumberFormat(3, '.', ',');
45
-
46
- The defaults set for ``number_format`` can be over-ridden upon each call using the
47
- additional parameters.
48
-
49
- Arguments
50
- ---------
51
-
52
- * ``decimal``: The number of decimal points to display
53
- * ``decimal_point``: The character(s) to use for the decimal point
54
- * ``thousand_sep``: The character(s) to use for the thousands separator
55
-
56
- .. _`number_format`: https://secure.php.net/number_format
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/raw.rst DELETED
@@ -1,38 +0,0 @@
1
- ``raw``
2
- =======
3
-
4
- The ``raw`` filter marks the value as being "safe", which means that in an
5
- environment with automatic escaping enabled this variable will not be escaped
6
- if ``raw`` is the last filter applied to it:
7
-
8
- .. code-block:: twig
9
-
10
- {% autoescape %}
11
- {{ var|raw }} {# var won't be escaped #}
12
- {% endautoescape %}
13
-
14
- .. note::
15
-
16
- **This note only applies to Twig before versions 1.39 and 2.8**.
17
-
18
- Be careful when using the ``raw`` filter inside expressions:
19
-
20
- .. code-block:: twig
21
-
22
- {% autoescape %}
23
- {% set hello = '<strong>Hello</strong>' %}
24
- {% set hola = '<strong>Hola</strong>' %}
25
-
26
- {{ false ? '<strong>Hola</strong>' : hello|raw }}
27
- does not render the same as
28
- {{ false ? hola : hello|raw }}
29
- but renders the same as
30
- {{ (false ? hola : hello)|raw }}
31
- {% endautoescape %}
32
-
33
- The first ternary statement is not escaped: ``hello`` is marked as being
34
- safe and Twig does not escape static values (see
35
- :doc:`escape<../tags/autoescape>`). In the second ternary statement, even
36
- if ``hello`` is marked as safe, ``hola`` remains unsafe and so is the whole
37
- expression. The third ternary statement is marked as safe and the result is
38
- not escaped.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/reduce.rst DELETED
@@ -1,32 +0,0 @@
1
- ``reduce``
2
- ==========
3
-
4
- .. versionadded:: 1.41
5
- The ``reduce`` filter was added in Twig 1.41 and 2.10.
6
-
7
- The ``reduce`` filter iteratively reduces a sequence or a mapping to a single
8
- value using an arrow function, so as to reduce it to a single value. The arrow
9
- function receives the return value of the previous iteration and the current
10
- value of the sequence or mapping:
11
-
12
- .. code-block:: twig
13
-
14
- {% set numbers = [1, 2, 3] %}
15
-
16
- {{ numbers|reduce((carry, v) => carry + v) }}
17
- {# output 6 #}
18
-
19
- The ``reduce`` filter takes an ``initial`` value as a second argument:
20
-
21
- .. code-block:: twig
22
-
23
- {{ numbers|reduce((carry, v) => carry + v, 10) }}
24
- {# output 16 #}
25
-
26
- Note that the arrow function has access to the current context.
27
-
28
- Arguments
29
- ---------
30
-
31
- * ``arrow``: The arrow function
32
- * ``initial``: The initial value
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/replace.rst DELETED
@@ -1,25 +0,0 @@
1
- ``replace``
2
- ===========
3
-
4
- The ``replace`` filter formats a given string by replacing the placeholders
5
- (placeholders are free-form):
6
-
7
- .. code-block:: twig
8
-
9
- {{ "I like %this% and %that%."|replace({'%this%': foo, '%that%': "bar"}) }}
10
-
11
- {# outputs I like foo and bar
12
- if the foo parameter equals to the foo string. #}
13
-
14
- {# using % as a delimiter is purely conventional and optional #}
15
-
16
- {{ "I like this and --that--."|replace({'this': foo, '--that--': "bar"}) }}
17
-
18
- {# outputs I like foo and bar #}
19
-
20
- Arguments
21
- ---------
22
-
23
- * ``from``: The placeholder values
24
-
25
- .. seealso:: :doc:`format<format>`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/reverse.rst DELETED
@@ -1,47 +0,0 @@
1
- ``reverse``
2
- ===========
3
-
4
- .. versionadded:: 1.6
5
- Support for strings has been added in Twig 1.6.
6
-
7
- The ``reverse`` filter reverses a sequence, a mapping, or a string:
8
-
9
- .. code-block:: twig
10
-
11
- {% for user in users|reverse %}
12
- ...
13
- {% endfor %}
14
-
15
- {{ '1234'|reverse }}
16
-
17
- {# outputs 4321 #}
18
-
19
- .. tip::
20
-
21
- For sequences and mappings, numeric keys are not preserved. To reverse
22
- them as well, pass ``true`` as an argument to the ``reverse`` filter:
23
-
24
- .. code-block:: twig
25
-
26
- {% for key, value in {1: "a", 2: "b", 3: "c"}|reverse %}
27
- {{ key }}: {{ value }}
28
- {%- endfor %}
29
-
30
- {# output: 0: c 1: b 2: a #}
31
-
32
- {% for key, value in {1: "a", 2: "b", 3: "c"}|reverse(true) %}
33
- {{ key }}: {{ value }}
34
- {%- endfor %}
35
-
36
- {# output: 3: c 2: b 1: a #}
37
-
38
- .. note::
39
-
40
- It also works with objects implementing the `Traversable`_ interface.
41
-
42
- Arguments
43
- ---------
44
-
45
- * ``preserve_keys``: Preserve keys when reversing a mapping or a sequence.
46
-
47
- .. _`Traversable`: https://secure.php.net/Traversable
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/round.rst DELETED
@@ -1,37 +0,0 @@
1
- ``round``
2
- =========
3
-
4
- .. versionadded:: 1.15.0
5
- The ``round`` filter was added in Twig 1.15.0.
6
-
7
- The ``round`` filter rounds a number to a given precision:
8
-
9
- .. code-block:: twig
10
-
11
- {{ 42.55|round }}
12
- {# outputs 43 #}
13
-
14
- {{ 42.55|round(1, 'floor') }}
15
- {# outputs 42.5 #}
16
-
17
- The ``round`` filter takes two optional arguments; the first one specifies the
18
- precision (default is ``0``) and the second the rounding method (default is
19
- ``common``):
20
-
21
- * ``common`` rounds either up or down (rounds the value up to precision decimal
22
- places away from zero, when it is half way there -- making 1.5 into 2 and
23
- -1.5 into -2);
24
-
25
- * ``ceil`` always rounds up;
26
-
27
- * ``floor`` always rounds down.
28
-
29
- .. note::
30
-
31
- The ``//`` operator is equivalent to ``|round(0, 'floor')``.
32
-
33
- Arguments
34
- ---------
35
-
36
- * ``precision``: The rounding precision
37
- * ``method``: The rounding method
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/slice.rst DELETED
@@ -1,71 +0,0 @@
1
- ``slice``
2
- ===========
3
-
4
- .. versionadded:: 1.6
5
- The ``slice`` filter was added in Twig 1.6.
6
-
7
- The ``slice`` filter extracts a slice of a sequence, a mapping, or a string:
8
-
9
- .. code-block:: twig
10
-
11
- {% for i in [1, 2, 3, 4, 5]|slice(1, 2) %}
12
- {# will iterate over 2 and 3 #}
13
- {% endfor %}
14
-
15
- {{ '12345'|slice(1, 2) }}
16
-
17
- {# outputs 23 #}
18
-
19
- You can use any valid expression for both the start and the length:
20
-
21
- .. code-block:: twig
22
-
23
- {% for i in [1, 2, 3, 4, 5]|slice(start, length) %}
24
- {# ... #}
25
- {% endfor %}
26
-
27
- As syntactic sugar, you can also use the ``[]`` notation:
28
-
29
- .. code-block:: twig
30
-
31
- {% for i in [1, 2, 3, 4, 5][start:length] %}
32
- {# ... #}
33
- {% endfor %}
34
-
35
- {{ '12345'[1:2] }} {# will display "23" #}
36
-
37
- {# you can omit the first argument -- which is the same as 0 #}
38
- {{ '12345'[:2] }} {# will display "12" #}
39
-
40
- {# you can omit the last argument -- which will select everything till the end #}
41
- {{ '12345'[2:] }} {# will display "345" #}
42
-
43
- The ``slice`` filter works as the `array_slice`_ PHP function for arrays and
44
- `mb_substr`_ for strings with a fallback to `substr`_.
45
-
46
- If the start is non-negative, the sequence will start at that start in the
47
- variable. If start is negative, the sequence will start that far from the end
48
- of the variable.
49
-
50
- If length is given and is positive, then the sequence will have up to that
51
- many elements in it. If the variable is shorter than the length, then only the
52
- available variable elements will be present. If length is given and is
53
- negative then the sequence will stop that many elements from the end of the
54
- variable. If it is omitted, then the sequence will have everything from offset
55
- up until the end of the variable.
56
-
57
- .. note::
58
-
59
- It also works with objects implementing the `Traversable`_ interface.
60
-
61
- Arguments
62
- ---------
63
-
64
- * ``start``: The start of the slice
65
- * ``length``: The size of the slice
66
- * ``preserve_keys``: Whether to preserve key or not (when the input is an array)
67
-
68
- .. _`Traversable`: https://secure.php.net/manual/en/class.traversable.php
69
- .. _`array_slice`: https://secure.php.net/array_slice
70
- .. _`mb_substr` : https://secure.php.net/mb-substr
71
- .. _`substr`: https://secure.php.net/substr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/sort.rst DELETED
@@ -1,18 +0,0 @@
1
- ``sort``
2
- ========
3
-
4
- The ``sort`` filter sorts an array:
5
-
6
- .. code-block:: twig
7
-
8
- {% for user in users|sort %}
9
- ...
10
- {% endfor %}
11
-
12
- .. note::
13
-
14
- Internally, Twig uses the PHP `asort`_ function to maintain index
15
- association. It supports Traversable objects by transforming
16
- those to arrays.
17
-
18
- .. _`asort`: https://secure.php.net/asort
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/spaceless.rst DELETED
@@ -1,65 +0,0 @@
1
- ``spaceless``
2
- =============
3
-
4
- .. versionadded:: 1.38
5
-
6
- The ``spaceless`` filter was added in Twig 1.38.
7
-
8
- Use the ``spaceless`` filter to remove whitespace *between HTML tags*, not
9
- whitespace within HTML tags or whitespace in plain text:
10
-
11
- .. code-block:: twig
12
-
13
- {{
14
- "<div>
15
- <strong>foo</strong>
16
- </div>
17
- "|spaceless }}
18
-
19
- {# output will be <div><strong>foo</strong></div> #}
20
-
21
- You can combine ``spaceless`` with the ``apply`` tag to apply the transformation
22
- on large amounts of HTML:
23
-
24
- .. code-block:: twig
25
-
26
- {% apply spaceless %}
27
- <div>
28
- <strong>foo</strong>
29
- </div>
30
- {% endapply %}
31
-
32
- {# output will be <div><strong>foo</strong></div> #}
33
-
34
- .. note::
35
-
36
- The ``apply`` tag was introduced in Twig 1.40; use the ``filter`` tag with
37
- previous versions.
38
-
39
- This tag is not meant to "optimize" the size of the generated HTML content but
40
- merely to avoid extra whitespace between HTML tags to avoid browser rendering
41
- quirks under some circumstances.
42
-
43
- .. caution::
44
-
45
- As the filter uses a regular expression behind the scenes, its performance
46
- is directly related to the text size you are working on (remember that
47
- filters are executed at runtime).
48
-
49
- .. tip::
50
-
51
- If you want to optimize the size of the generated HTML content, gzip
52
- compress the output instead.
53
-
54
- .. tip::
55
-
56
- If you want to create a tag that actually removes all extra whitespace in
57
- an HTML string, be warned that this is not as easy as it seems to be
58
- (think of ``textarea`` or ``pre`` tags for instance). Using a third-party
59
- library like Tidy is probably a better idea.
60
-
61
- .. tip::
62
-
63
- For more information on whitespace control, read the
64
- :ref:`dedicated section <templates-whitespace-control>` of the documentation and learn how
65
- you can also use the whitespace control modifier on your tags.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/split.rst DELETED
@@ -1,53 +0,0 @@
1
- ``split``
2
- =========
3
-
4
- .. versionadded:: 1.10.3
5
- The ``split`` filter was added in Twig 1.10.3.
6
-
7
- The ``split`` filter splits a string by the given delimiter and returns a list
8
- of strings:
9
-
10
- .. code-block:: twig
11
-
12
- {% set foo = "one,two,three"|split(',') %}
13
- {# foo contains ['one', 'two', 'three'] #}
14
-
15
- You can also pass a ``limit`` argument:
16
-
17
- * If ``limit`` is positive, the returned array will contain a maximum of
18
- limit elements with the last element containing the rest of string;
19
-
20
- * If ``limit`` is negative, all components except the last -limit are
21
- returned;
22
-
23
- * If ``limit`` is zero, then this is treated as 1.
24
-
25
- .. code-block:: twig
26
-
27
- {% set foo = "one,two,three,four,five"|split(',', 3) %}
28
- {# foo contains ['one', 'two', 'three,four,five'] #}
29
-
30
- If the ``delimiter`` is an empty string, then value will be split by equal
31
- chunks. Length is set by the ``limit`` argument (one character by default).
32
-
33
- .. code-block:: twig
34
-
35
- {% set foo = "123"|split('') %}
36
- {# foo contains ['1', '2', '3'] #}
37
-
38
- {% set bar = "aabbcc"|split('', 2) %}
39
- {# bar contains ['aa', 'bb', 'cc'] #}
40
-
41
- .. note::
42
-
43
- Internally, Twig uses the PHP `explode`_ or `str_split`_ (if delimiter is
44
- empty) functions for string splitting.
45
-
46
- Arguments
47
- ---------
48
-
49
- * ``delimiter``: The delimiter
50
- * ``limit``: The limit argument
51
-
52
- .. _`explode`: https://secure.php.net/explode
53
- .. _`str_split`: https://secure.php.net/str_split
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/striptags.rst DELETED
@@ -1,29 +0,0 @@
1
- ``striptags``
2
- =============
3
-
4
- The ``striptags`` filter strips SGML/XML tags and replace adjacent whitespace
5
- by one space:
6
-
7
- .. code-block:: twig
8
-
9
- {{ some_html|striptags }}
10
-
11
- You can also provide tags which should not be stripped:
12
-
13
- .. code-block:: twig
14
-
15
- {{ some_html|striptags('<br><p>') }}
16
-
17
- In this example, the ``<br/>``, ``<br>``, ``<p>``, and ``</p>`` tags won't be
18
- removed from the string.
19
-
20
- .. note::
21
-
22
- Internally, Twig uses the PHP `strip_tags`_ function.
23
-
24
- Arguments
25
- ---------
26
-
27
- * ``allowable_tags``: Tags which should not be stripped
28
-
29
- .. _`strip_tags`: https://secure.php.net/strip_tags
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/title.rst DELETED
@@ -1,11 +0,0 @@
1
- ``title``
2
- =========
3
-
4
- The ``title`` filter returns a titlecased version of the value. Words will
5
- start with uppercase letters, all remaining characters are lowercase:
6
-
7
- .. code-block:: twig
8
-
9
- {{ 'my first car'|title }}
10
-
11
- {# outputs 'My First Car' #}
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/trim.rst DELETED
@@ -1,45 +0,0 @@
1
- ``trim``
2
- ========
3
-
4
- .. versionadded:: 1.32
5
- The ``side`` argument was added in Twig 1.32.
6
-
7
- .. versionadded:: 1.6.2
8
- The ``trim`` filter was added in Twig 1.6.2.
9
-
10
- The ``trim`` filter strips whitespace (or other characters) from the beginning
11
- and end of a string:
12
-
13
- .. code-block:: twig
14
-
15
- {{ ' I like Twig. '|trim }}
16
-
17
- {# outputs 'I like Twig.' #}
18
-
19
- {{ ' I like Twig.'|trim('.') }}
20
-
21
- {# outputs ' I like Twig' #}
22
-
23
- {{ ' I like Twig. '|trim(side='left') }}
24
-
25
- {# outputs 'I like Twig. ' #}
26
-
27
- {{ ' I like Twig. '|trim(' ', 'right') }}
28
-
29
- {# outputs ' I like Twig.' #}
30
-
31
- .. note::
32
-
33
- Internally, Twig uses the PHP `trim`_, `ltrim`_, and `rtrim`_ functions.
34
-
35
- Arguments
36
- ---------
37
-
38
- * ``character_mask``: The characters to strip
39
-
40
- * ``side``: The default is to strip from the left and the right (`both`) sides, but `left`
41
- and `right` will strip from either the left side or right side only
42
-
43
- .. _`trim`: https://secure.php.net/trim
44
- .. _`ltrim`: https://secure.php.net/ltrim
45
- .. _`rtrim`: https://secure.php.net/rtrim
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/upper.rst DELETED
@@ -1,10 +0,0 @@
1
- ``upper``
2
- =========
3
-
4
- The ``upper`` filter converts a value to uppercase:
5
-
6
- .. code-block:: twig
7
-
8
- {{ 'welcome'|upper }}
9
-
10
- {# outputs 'WELCOME' #}
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/filters/url_encode.rst DELETED
@@ -1,34 +0,0 @@
1
- ``url_encode``
2
- ==============
3
-
4
- .. versionadded:: 1.12.3
5
- Support for encoding an array as query string was added in Twig 1.12.3.
6
-
7
- .. versionadded:: 1.16.0
8
- The ``raw`` argument was removed in Twig 1.16.0. Twig now always encodes
9
- according to RFC 3986.
10
-
11
- The ``url_encode`` filter percent encodes a given string as URL segment
12
- or an array as query string:
13
-
14
- .. code-block:: twig
15
-
16
- {{ "path-seg*ment"|url_encode }}
17
- {# outputs "path-seg%2Ament" #}
18
-
19
- {{ "string with spaces"|url_encode }}
20
- {# outputs "string%20with%20spaces" #}
21
-
22
- {{ {'param': 'value', 'foo': 'bar'}|url_encode }}
23
- {# outputs "param=value&foo=bar" #}
24
-
25
- .. note::
26
-
27
- Internally, Twig uses the PHP `urlencode`_ (or `rawurlencode`_ if you pass
28
- ``true`` as the first parameter) or the `http_build_query`_ function. Note
29
- that as of Twig 1.16.0, ``urlencode`` **always** uses ``rawurlencode`` (the
30
- ``raw`` argument was removed.)
31
-
32
- .. _`urlencode`: https://secure.php.net/urlencode
33
- .. _`rawurlencode`: https://secure.php.net/rawurlencode
34
- .. _`http_build_query`: https://secure.php.net/http_build_query
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/functions/attribute.rst DELETED
@@ -1,26 +0,0 @@
1
- ``attribute``
2
- =============
3
-
4
- .. versionadded:: 1.2
5
- The ``attribute`` function was added in Twig 1.2.
6
-
7
- The ``attribute`` function can be used to access a "dynamic" attribute of a
8
- variable:
9
-
10
- .. code-block:: twig
11
-
12
- {{ attribute(object, method) }}
13
- {{ attribute(object, method, arguments) }}
14
- {{ attribute(array, item) }}
15
-
16
- In addition, the ``defined`` test can check for the existence of a dynamic
17
- attribute:
18
-
19
- .. code-block:: twig
20
-
21
- {{ attribute(object, method) is defined ? 'Method exists' : 'Method does not exist' }}
22
-
23
- .. note::
24
-
25
- The resolution algorithm is the same as the one used for the ``.``
26
- notation, except that the item can be any valid expression.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/functions/block.rst DELETED
@@ -1,41 +0,0 @@
1
- ``block``
2
- =========
3
-
4
- .. versionadded:: 1.28
5
- Using ``block`` with the ``defined`` test was added in Twig 1.28.
6
-
7
- .. versionadded:: 1.28
8
- Support for the template argument was added in Twig 1.28.
9
-
10
- When a template uses inheritance and if you want to print a block multiple
11
- times, use the ``block`` function:
12
-
13
- .. code-block:: twig
14
-
15
- <title>{% block title %}{% endblock %}</title>
16
-
17
- <h1>{{ block('title') }}</h1>
18
-
19
- {% block body %}{% endblock %}
20
-
21
- The ``block`` function can also be used to display one block from another
22
- template:
23
-
24
- .. code-block:: twig
25
-
26
- {{ block("title", "common_blocks.twig") }}
27
-
28
- Use the ``defined`` test to check if a block exists in the context of the
29
- current template:
30
-
31
- .. code-block:: twig
32
-
33
- {% if block("footer") is defined %}
34
- ...
35
- {% endif %}
36
-
37
- {% if block("footer", "common_blocks.twig") is defined %}
38
- ...
39
- {% endif %}
40
-
41
- .. seealso:: :doc:`extends<../tags/extends>`, :doc:`parent<../functions/parent>`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/functions/constant.rst DELETED
@@ -1,29 +0,0 @@
1
- ``constant``
2
- ============
3
-
4
- .. versionadded:: 1.12.1
5
- constant now accepts object instances as the second argument.
6
-
7
- .. versionadded:: 1.28
8
- Using ``constant`` with the ``defined`` test was added in Twig 1.28.
9
-
10
- ``constant`` returns the constant value for a given string:
11
-
12
- .. code-block:: twig
13
-
14
- {{ some_date|date(constant('DATE_W3C')) }}
15
- {{ constant('Namespace\\Classname::CONSTANT_NAME') }}
16
-
17
- As of 1.12.1 you can read constants from object instances as well:
18
-
19
- .. code-block:: twig
20
-
21
- {{ constant('RSS', date) }}
22
-
23
- Use the ``defined`` test to check if a constant is defined:
24
-
25
- .. code-block:: twig
26
-
27
- {% if constant('SOME_CONST') is defined %}
28
- ...
29
- {% endif %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/functions/cycle.rst DELETED
@@ -1,28 +0,0 @@
1
- ``cycle``
2
- =========
3
-
4
- The ``cycle`` function cycles on an array of values:
5
-
6
- .. code-block:: twig
7
-
8
- {% set start_year = date() | date('Y') %}
9
- {% set end_year = start_year + 5 %}
10
-
11
- {% for year in start_year..end_year %}
12
- {{ cycle(['odd', 'even'], loop.index0) }}
13
- {% endfor %}
14
-
15
- The array can contain any number of values:
16
-
17
- .. code-block:: twig
18
-
19
- {% set fruits = ['apple', 'orange', 'citrus'] %}
20
-
21
- {% for i in 0..10 %}
22
- {{ cycle(fruits, i) }}
23
- {% endfor %}
24
-
25
- Arguments
26
- ---------
27
-
28
- * ``position``: The cycle position
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/functions/date.rst DELETED
@@ -1,55 +0,0 @@
1
- ``date``
2
- ========
3
-
4
- .. versionadded:: 1.6
5
- The date function has been added in Twig 1.6.
6
-
7
- .. versionadded:: 1.6.1
8
- The default timezone support has been added in Twig 1.6.1.
9
-
10
- Converts an argument to a date to allow date comparison:
11
-
12
- .. code-block:: twig
13
-
14
- {% if date(user.created_at) < date('-2days') %}
15
- {# do something #}
16
- {% endif %}
17
-
18
- The argument must be in one of PHP’s supported `date and time formats`_.
19
-
20
- You can pass a timezone as the second argument:
21
-
22
- .. code-block:: twig
23
-
24
- {% if date(user.created_at) < date('-2days', 'Europe/Paris') %}
25
- {# do something #}
26
- {% endif %}
27
-
28
- If no argument is passed, the function returns the current date:
29
-
30
- .. code-block:: twig
31
-
32
- {% if date(user.created_at) < date() %}
33
- {# always! #}
34
- {% endif %}
35
-
36
- .. note::
37
-
38
- You can set the default timezone globally by calling ``setTimezone()`` on
39
- the ``core`` extension instance:
40
-
41
- .. code-block:: php
42
-
43
- $twig = new \Twig\Environment($loader);
44
- $twig->getExtension('\Twig\Extension\CoreExtension')->setTimezone('Europe/Paris');
45
-
46
- // before Twig 1.26
47
- $twig->getExtension('core')->setTimezone('Europe/Paris');
48
-
49
- Arguments
50
- ---------
51
-
52
- * ``date``: The date
53
- * ``timezone``: The timezone
54
-
55
- .. _`date and time formats`: https://secure.php.net/manual/en/datetime.formats.php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/functions/dump.rst DELETED
@@ -1,69 +0,0 @@
1
- ``dump``
2
- ========
3
-
4
- .. versionadded:: 1.5
5
- The ``dump`` function was added in Twig 1.5.
6
-
7
- The ``dump`` function dumps information about a template variable. This is
8
- mostly useful to debug a template that does not behave as expected by
9
- introspecting its variables:
10
-
11
- .. code-block:: twig
12
-
13
- {{ dump(user) }}
14
-
15
- .. note::
16
-
17
- The ``dump`` function is not available by default. You must add the
18
- ``\Twig\Extension\DebugExtension`` extension explicitly when creating your Twig
19
- environment::
20
-
21
- $twig = new \Twig\Environment($loader, [
22
- 'debug' => true,
23
- // ...
24
- ]);
25
- $twig->addExtension(new \Twig\Extension\DebugExtension());
26
-
27
- Even when enabled, the ``dump`` function won't display anything if the
28
- ``debug`` option on the environment is not enabled (to avoid leaking debug
29
- information on a production server).
30
-
31
- In an HTML context, wrap the output with a ``pre`` tag to make it easier to
32
- read:
33
-
34
- .. code-block:: twig
35
-
36
- <pre>
37
- {{ dump(user) }}
38
- </pre>
39
-
40
- .. tip::
41
-
42
- Using a ``pre`` tag is not needed when `XDebug`_ is enabled and
43
- ``html_errors`` is ``on``; as a bonus, the output is also nicer with
44
- XDebug enabled.
45
-
46
- You can debug several variables by passing them as additional arguments:
47
-
48
- .. code-block:: twig
49
-
50
- {{ dump(user, categories) }}
51
-
52
- If you don't pass any value, all variables from the current context are
53
- dumped:
54
-
55
- .. code-block:: twig
56
-
57
- {{ dump() }}
58
-
59
- .. note::
60
-
61
- Internally, Twig uses the PHP `var_dump`_ function.
62
-
63
- Arguments
64
- ---------
65
-
66
- * ``context``: The context to dump
67
-
68
- .. _`XDebug`: https://xdebug.org/docs/display
69
- .. _`var_dump`: https://secure.php.net/var_dump
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/functions/include.rst DELETED
@@ -1,84 +0,0 @@
1
- ``include``
2
- ===========
3
-
4
- .. versionadded:: 1.12
5
- The ``include`` function was added in Twig 1.12.
6
-
7
- The ``include`` function returns the rendered content of a template:
8
-
9
- .. code-block:: twig
10
-
11
- {{ include('template.html') }}
12
- {{ include(some_var) }}
13
-
14
- Included templates have access to the variables of the active context.
15
-
16
- If you are using the filesystem loader, the templates are looked for in the
17
- paths defined by it.
18
-
19
- The context is passed by default to the template but you can also pass
20
- additional variables:
21
-
22
- .. code-block:: twig
23
-
24
- {# template.html will have access to the variables from the current context and the additional ones provided #}
25
- {{ include('template.html', {foo: 'bar'}) }}
26
-
27
- You can disable access to the context by setting ``with_context`` to
28
- ``false``:
29
-
30
- .. code-block:: twig
31
-
32
- {# only the foo variable will be accessible #}
33
- {{ include('template.html', {foo: 'bar'}, with_context = false) }}
34
-
35
- .. code-block:: twig
36
-
37
- {# no variables will be accessible #}
38
- {{ include('template.html', with_context = false) }}
39
-
40
- And if the expression evaluates to a ``\Twig\Template`` or a
41
- ``\Twig\TemplateWrapper`` instance, Twig will use it directly::
42
-
43
- // {{ include(template) }}
44
-
45
- // deprecated as of Twig 1.28
46
- $template = $twig->loadTemplate('some_template.twig');
47
-
48
- // as of Twig 1.28
49
- $template = $twig->load('some_template.twig');
50
-
51
- $twig->display('template.twig', ['template' => $template]);
52
-
53
- When you set the ``ignore_missing`` flag, Twig will return an empty string if
54
- the template does not exist:
55
-
56
- .. code-block:: twig
57
-
58
- {{ include('sidebar.html', ignore_missing = true) }}
59
-
60
- You can also provide a list of templates that are checked for existence before
61
- inclusion. The first template that exists will be rendered:
62
-
63
- .. code-block:: twig
64
-
65
- {{ include(['page_detailed.html', 'page.html']) }}
66
-
67
- If ``ignore_missing`` is set, it will fall back to rendering nothing if none
68
- of the templates exist, otherwise it will throw an exception.
69
-
70
- When including a template created by an end user, you should consider
71
- sandboxing it:
72
-
73
- .. code-block:: twig
74
-
75
- {{ include('page.html', sandboxed = true) }}
76
-
77
- Arguments
78
- ---------
79
-
80
- * ``template``: The template to render
81
- * ``variables``: The variables to pass to the template
82
- * ``with_context``: Whether to pass the current context variables or not
83
- * ``ignore_missing``: Whether to ignore missing templates or not
84
- * ``sandboxed``: Whether to sandbox the template or not
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/functions/index.rst DELETED
@@ -1,20 +0,0 @@
1
- Functions
2
- =========
3
-
4
- .. toctree::
5
- :maxdepth: 1
6
-
7
- attribute
8
- block
9
- constant
10
- cycle
11
- date
12
- dump
13
- include
14
- max
15
- min
16
- parent
17
- random
18
- range
19
- source
20
- template_from_string
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/functions/max.rst DELETED
@@ -1,20 +0,0 @@
1
- ``max``
2
- =======
3
-
4
- .. versionadded:: 1.15
5
- The ``max`` function was added in Twig 1.15.
6
-
7
- ``max`` returns the biggest value of a sequence or a set of values:
8
-
9
- .. code-block:: twig
10
-
11
- {{ max(1, 3, 2) }}
12
- {{ max([1, 3, 2]) }}
13
-
14
- When called with a mapping, max ignores keys and only compares values:
15
-
16
- .. code-block:: twig
17
-
18
- {{ max({2: "e", 1: "a", 3: "b", 5: "d", 4: "c"}) }}
19
- {# returns "e" #}
20
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/functions/min.rst DELETED
@@ -1,20 +0,0 @@
1
- ``min``
2
- =======
3
-
4
- .. versionadded:: 1.15
5
- The ``min`` function was added in Twig 1.15.
6
-
7
- ``min`` returns the lowest value of a sequence or a set of values:
8
-
9
- .. code-block:: twig
10
-
11
- {{ min(1, 3, 2) }}
12
- {{ min([1, 3, 2]) }}
13
-
14
- When called with a mapping, min ignores keys and only compares values:
15
-
16
- .. code-block:: twig
17
-
18
- {{ min({2: "e", 3: "a", 1: "b", 5: "d", 4: "c"}) }}
19
- {# returns "a" #}
20
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/functions/parent.rst DELETED
@@ -1,20 +0,0 @@
1
- ``parent``
2
- ==========
3
-
4
- When a template uses inheritance, it's possible to render the contents of the
5
- parent block when overriding a block by using the ``parent`` function:
6
-
7
- .. code-block:: twig
8
-
9
- {% extends "base.html" %}
10
-
11
- {% block sidebar %}
12
- <h3>Table Of Contents</h3>
13
- ...
14
- {{ parent() }}
15
- {% endblock %}
16
-
17
- The ``parent()`` call will return the content of the ``sidebar`` block as
18
- defined in the ``base.html`` template.
19
-
20
- .. seealso:: :doc:`extends<../tags/extends>`, :doc:`block<../functions/block>`, :doc:`block<../tags/block>`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/functions/random.rst DELETED
@@ -1,36 +0,0 @@
1
- ``random``
2
- ==========
3
-
4
- .. versionadded:: 1.5
5
- The ``random`` function was added in Twig 1.5.
6
-
7
- .. versionadded:: 1.6
8
- String and integer handling was added in Twig 1.6.
9
-
10
- .. versionadded:: 1.38
11
- The "max" argument was added in Twig 1.38.
12
-
13
- The ``random`` function returns a random value depending on the supplied
14
- parameter type:
15
-
16
- * a random item from a sequence;
17
- * a random character from a string;
18
- * a random integer between 0 and the integer parameter (inclusive).
19
- * a random integer between the integer parameter (when negative) and 0 (inclusive).
20
- * a random integer between the first integer and the second integer parameter (inclusive).
21
-
22
- .. code-block:: twig
23
-
24
- {{ random(['apple', 'orange', 'citrus']) }} {# example output: orange #}
25
- {{ random('ABC') }} {# example output: C #}
26
- {{ random() }} {# example output: 15386094 (works as the native PHP mt_rand function) #}
27
- {{ random(5) }} {# example output: 3 #}
28
- {{ random(50, 100) }} {# example output: 63 #}
29
-
30
- Arguments
31
- ---------
32
-
33
- * ``values``: The values
34
- * ``max``: The max value when values is an integer
35
-
36
- .. _`mt_rand`: https://secure.php.net/mt_rand
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/functions/range.rst DELETED
@@ -1,58 +0,0 @@
1
- ``range``
2
- =========
3
-
4
- Returns a list containing an arithmetic progression of integers:
5
-
6
- .. code-block:: twig
7
-
8
- {% for i in range(0, 3) %}
9
- {{ i }},
10
- {% endfor %}
11
-
12
- {# outputs 0, 1, 2, 3, #}
13
-
14
- When step is given (as the third parameter), it specifies the increment (or
15
- decrement for negative values):
16
-
17
- .. code-block:: twig
18
-
19
- {% for i in range(0, 6, 2) %}
20
- {{ i }},
21
- {% endfor %}
22
-
23
- {# outputs 0, 2, 4, 6, #}
24
-
25
- .. note::
26
-
27
- Note that if the start is greater than the end, ``range`` assumes a step of
28
- ``-1``:
29
-
30
- .. code-block:: twig
31
-
32
- {% for i in range(3, 0) %}
33
- {{ i }},
34
- {% endfor %}
35
-
36
- {# outputs 3, 2, 1, 0, #}
37
-
38
- The Twig built-in ``..`` operator is just syntactic sugar for the ``range``
39
- function (with a step of ``1``, or ``-1`` if the start is greater than the end):
40
-
41
- .. code-block:: twig
42
-
43
- {% for i in 0..3 %}
44
- {{ i }},
45
- {% endfor %}
46
-
47
- .. tip::
48
-
49
- The ``range`` function works as the native PHP `range`_ function.
50
-
51
- Arguments
52
- ---------
53
-
54
- * ``low``: The first value of the sequence.
55
- * ``high``: The highest possible value of the sequence.
56
- * ``step``: The increment between elements of the sequence.
57
-
58
- .. _`range`: https://secure.php.net/range
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/functions/source.rst DELETED
@@ -1,32 +0,0 @@
1
- ``source``
2
- ==========
3
-
4
- .. versionadded:: 1.15
5
- The ``source`` function was added in Twig 1.15.
6
-
7
- .. versionadded:: 1.18.3
8
- The ``ignore_missing`` flag was added in Twig 1.18.3.
9
-
10
- The ``source`` function returns the content of a template without rendering it:
11
-
12
- .. code-block:: twig
13
-
14
- {{ source('template.html') }}
15
- {{ source(some_var) }}
16
-
17
- When you set the ``ignore_missing`` flag, Twig will return an empty string if
18
- the template does not exist:
19
-
20
- .. code-block:: twig
21
-
22
- {{ source('template.html', ignore_missing = true) }}
23
-
24
- The function uses the same template loaders as the ones used to include
25
- templates. So, if you are using the filesystem loader, the templates are looked
26
- for in the paths defined by it.
27
-
28
- Arguments
29
- ---------
30
-
31
- * ``name``: The name of the template to read
32
- * ``ignore_missing``: Whether to ignore missing templates or not
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/functions/template_from_string.rst DELETED
@@ -1,43 +0,0 @@
1
- ``template_from_string``
2
- ========================
3
-
4
- .. versionadded:: 1.11
5
- The ``template_from_string`` function was added in Twig 1.11.
6
-
7
- .. versionadded:: 1.39
8
- The name argument was added in Twig 1.39.
9
-
10
- The ``template_from_string`` function loads a template from a string:
11
-
12
- .. code-block:: twig
13
-
14
- {{ include(template_from_string("Hello {{ name }}")) }}
15
- {{ include(template_from_string(page.template)) }}
16
-
17
- To ease debugging, you can also give the template a name that will be part of
18
- any related error message:
19
-
20
- .. code-block:: twig
21
-
22
- {{ include(template_from_string(page.template, "template for page " ~ page.name)) }}
23
-
24
- .. note::
25
-
26
- The ``template_from_string`` function is not available by default. You
27
- must add the ``\Twig\Extension\StringLoaderExtension`` extension explicitly when
28
- creating your Twig environment::
29
-
30
- $twig = new \Twig\Environment(...);
31
- $twig->addExtension(new \Twig\Extension\StringLoaderExtension());
32
-
33
- .. note::
34
-
35
- Even if you will probably always use the ``template_from_string`` function
36
- with the ``include`` function, you can use it with any tag or function that
37
- takes a template as an argument (like the ``embed`` or ``extends`` tags).
38
-
39
- Arguments
40
- ---------
41
-
42
- * ``template``: The template
43
- * ``name``: A name for the template
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/index.rst DELETED
@@ -1,19 +0,0 @@
1
- Twig
2
- ====
3
-
4
- .. toctree::
5
- :maxdepth: 2
6
-
7
- intro
8
- installation
9
- templates
10
- api
11
- advanced
12
- internals
13
- deprecated
14
- recipes
15
- coding_standards
16
- tags/index
17
- filters/index
18
- functions/index
19
- tests/index
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/installation.rst DELETED
@@ -1,73 +0,0 @@
1
- Installation
2
- ============
3
-
4
- You have multiple ways to install Twig.
5
-
6
- Installing the Twig PHP package
7
- -------------------------------
8
-
9
- Install `Composer`_ and run the following command:
10
-
11
- .. code-block:: bash
12
-
13
- composer require "twig/twig:^1.0"
14
-
15
- Installing the C extension
16
- --------------------------
17
-
18
- .. versionadded:: 1.4
19
- The C extension was added in Twig 1.4.
20
-
21
- Twig comes with an **optional** C extension that improves the performance of the
22
- Twig runtime engine.
23
-
24
- Note that this extension does not replace the PHP code but only provides an
25
- optimized version of the ``\Twig\Template::getAttribute()`` method; you must
26
- still install the regular PHP code
27
-
28
- The C extension is only compatible and useful for **PHP5**.
29
-
30
- Install it like any other PHP extensions:
31
-
32
- .. code-block:: bash
33
-
34
- cd ext/twig
35
- phpize
36
- ./configure
37
- make
38
- make install
39
-
40
- For Windows:
41
-
42
- 1. Setup the build environment following the `PHP documentation`_
43
- 2. Put Twig's C extension source code into ``C:\php-sdk\phpdev\vcXX\x86\php-source-directory\ext\twig``
44
- 3. Use the ``configure --disable-all --enable-cli --enable-twig=shared`` command instead of step 14
45
- 4. ``nmake``
46
- 5. Copy the ``C:\php-sdk\phpdev\vcXX\x86\php-source-directory\Release_TS\php_twig.dll`` file to your PHP setup.
47
-
48
- .. tip::
49
-
50
- For Windows ZendServer, ZTS is not enabled as mentioned in `Zend Server
51
- FAQ`_.
52
-
53
- You have to use ``configure --disable-all --disable-zts --enable-cli
54
- --enable-twig=shared`` to be able to build the twig C extension for
55
- ZendServer.
56
-
57
- The built DLL will be available in
58
- ``C:\\php-sdk\\phpdev\\vcXX\\x86\\php-source-directory\\Release``
59
-
60
- Finally, enable the extension in your ``php.ini`` configuration file:
61
-
62
- .. code-block:: ini
63
-
64
- extension=twig.so # For Unix systems
65
- extension=php_twig.dll # For Windows systems
66
-
67
- And from now on, Twig will automatically compile your templates to take
68
- advantage of the C extension.
69
-
70
- .. _`download page`: https://github.com/twigphp/Twig/tags
71
- .. _`Composer`: https://getcomposer.org/download/
72
- .. _`PHP documentation`: https://wiki.php.net/internals/windows/stepbystepbuild
73
- .. _`Zend Server FAQ`: https://www.zend.com/en/products/server/faq#faqD6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/internals.rst DELETED
@@ -1,144 +0,0 @@
1
- Twig Internals
2
- ==============
3
-
4
- Twig is very extensible and you can hack it. Keep in mind that you
5
- should probably try to create an extension before hacking the core, as most
6
- features and enhancements can be handled with extensions. This chapter is also
7
- useful for people who want to understand how Twig works under the hood.
8
-
9
- How does Twig work?
10
- -------------------
11
-
12
- The rendering of a Twig template can be summarized into four key steps:
13
-
14
- * **Load** the template: If the template is already compiled, load it and go
15
- to the *evaluation* step, otherwise:
16
-
17
- * First, the **lexer** tokenizes the template source code into small pieces
18
- for easier processing;
19
-
20
- * Then, the **parser** converts the token stream into a meaningful tree
21
- of nodes (the Abstract Syntax Tree);
22
-
23
- * Finally, the *compiler* transforms the AST into PHP code.
24
-
25
- * **Evaluate** the template: It means calling the ``display()``
26
- method of the compiled template and passing it the context.
27
-
28
- The Lexer
29
- ---------
30
-
31
- The lexer tokenizes a template source code into a token stream (each token is
32
- an instance of ``\Twig\Token``, and the stream is an instance of
33
- ``\Twig\TokenStream``). The default lexer recognizes 13 different token types:
34
-
35
- * ``\Twig\Token::BLOCK_START_TYPE``, ``\Twig\Token::BLOCK_END_TYPE``: Delimiters for blocks (``{% %}``)
36
- * ``\Twig\Token::VAR_START_TYPE``, ``\Twig\Token::VAR_END_TYPE``: Delimiters for variables (``{{ }}``)
37
- * ``\Twig\Token::TEXT_TYPE``: A text outside an expression;
38
- * ``\Twig\Token::NAME_TYPE``: A name in an expression;
39
- * ``\Twig\Token::NUMBER_TYPE``: A number in an expression;
40
- * ``\Twig\Token::STRING_TYPE``: A string in an expression;
41
- * ``\Twig\Token::OPERATOR_TYPE``: An operator;
42
- * ``\Twig\Token::PUNCTUATION_TYPE``: A punctuation sign;
43
- * ``\Twig\Token::INTERPOLATION_START_TYPE``, ``\Twig\Token::INTERPOLATION_END_TYPE`` (as of Twig 1.5): Delimiters for string interpolation;
44
- * ``\Twig\Token::EOF_TYPE``: Ends of template.
45
-
46
- You can manually convert a source code into a token stream by calling the
47
- ``tokenize()`` method of an environment::
48
-
49
- $stream = $twig->tokenize(new \Twig\Source($source, $identifier));
50
-
51
- .. versionadded:: 1.27
52
- ``\Twig\Source`` was introduced in version 1.27, pass the source and the
53
- identifier directly on previous versions.
54
-
55
- As the stream has a ``__toString()`` method, you can have a textual
56
- representation of it by echoing the object::
57
-
58
- echo $stream."\n";
59
-
60
- Here is the output for the ``Hello {{ name }}`` template:
61
-
62
- .. code-block:: text
63
-
64
- TEXT_TYPE(Hello )
65
- VAR_START_TYPE()
66
- NAME_TYPE(name)
67
- VAR_END_TYPE()
68
- EOF_TYPE()
69
-
70
- .. note::
71
-
72
- The default lexer (``\Twig\Lexer``) can be changed by calling
73
- the ``setLexer()`` method::
74
-
75
- $twig->setLexer($lexer);
76
-
77
- The Parser
78
- ----------
79
-
80
- The parser converts the token stream into an AST (Abstract Syntax Tree), or a
81
- node tree (an instance of ``\Twig\Node\ModuleNode``). The core extension defines
82
- the basic nodes like: ``for``, ``if``, ... and the expression nodes.
83
-
84
- You can manually convert a token stream into a node tree by calling the
85
- ``parse()`` method of an environment::
86
-
87
- $nodes = $twig->parse($stream);
88
-
89
- Echoing the node object gives you a nice representation of the tree::
90
-
91
- echo $nodes."\n";
92
-
93
- Here is the output for the ``Hello {{ name }}`` template:
94
-
95
- .. code-block:: text
96
-
97
- \Twig\Node\ModuleNode(
98
- \Twig\Node\TextNode(Hello )
99
- \Twig\Node\PrintNode(
100
- \Twig\Node\Expression\NameExpression(name)
101
- )
102
- )
103
-
104
- .. note::
105
-
106
- The default parser (``\Twig\TokenParser\AbstractTokenParser``) can be changed by calling the
107
- ``setParser()`` method::
108
-
109
- $twig->setParser($parser);
110
-
111
- The Compiler
112
- ------------
113
-
114
- The last step is done by the compiler. It takes a node tree as an input and
115
- generates PHP code usable for runtime execution of the template.
116
-
117
- You can manually compile a node tree to PHP code with the ``compile()`` method
118
- of an environment::
119
-
120
- $php = $twig->compile($nodes);
121
-
122
- The generated template for a ``Hello {{ name }}`` template reads as follows
123
- (the actual output can differ depending on the version of Twig you are
124
- using)::
125
-
126
- /* Hello {{ name }} */
127
- class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends \Twig\Template
128
- {
129
- protected function doDisplay(array $context, array $blocks = [])
130
- {
131
- // line 1
132
- echo "Hello ";
133
- echo twig_escape_filter($this->env, (isset($context["name"]) ? $context["name"] : null), "html", null, true);
134
- }
135
-
136
- // some more code
137
- }
138
-
139
- .. note::
140
-
141
- The default compiler (``\Twig\Compiler``) can be changed by calling the
142
- ``setCompiler()`` method::
143
-
144
- $twig->setCompiler($compiler);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/intro.rst DELETED
@@ -1,76 +0,0 @@
1
- Introduction
2
- ============
3
-
4
- Welcome to the documentation for Twig, the flexible, fast, and secure template
5
- engine for PHP.
6
-
7
- Twig is both designer and developer friendly by sticking to PHP's principles and
8
- adding functionality useful for templating environments.
9
-
10
- The key-features are...
11
-
12
- * *Fast*: Twig compiles templates down to plain optimized PHP code. The
13
- overhead compared to regular PHP code was reduced to the very minimum.
14
-
15
- * *Secure*: Twig has a sandbox mode to evaluate untrusted template code. This
16
- allows Twig to be used as a template language for applications where users
17
- may modify the template design.
18
-
19
- * *Flexible*: Twig is powered by a flexible lexer and parser. This allows the
20
- developer to define their own custom tags and filters, and to create their own DSL.
21
-
22
- Twig is used by many Open-Source projects like Symfony, Drupal8, eZPublish,
23
- phpBB, Matomo, OroCRM; and many frameworks have support for it as well like
24
- Slim, Yii, Laravel, and Codeigniter — just to name a few.
25
-
26
- Prerequisites
27
- -------------
28
-
29
- Twig needs at least **PHP 5.5.0** to run.
30
-
31
- Installation
32
- ------------
33
-
34
- The recommended way to install Twig is via Composer:
35
-
36
- .. code-block:: bash
37
-
38
- composer require "twig/twig:^1.0"
39
-
40
- .. note::
41
-
42
- To learn more about the other installation methods, read the
43
- :doc:`installation<installation>` chapter; it also explains how to install
44
- the Twig C extension.
45
-
46
- Basic API Usage
47
- ---------------
48
-
49
- This section gives you a brief introduction to the PHP API for Twig.
50
-
51
- .. code-block:: php
52
-
53
- require_once '/path/to/vendor/autoload.php';
54
-
55
- $loader = new \Twig\Loader\ArrayLoader([
56
- 'index' => 'Hello {{ name }}!',
57
- ]);
58
- $twig = new \Twig\Environment($loader);
59
-
60
- echo $twig->render('index', ['name' => 'Fabien']);
61
-
62
- Twig uses a loader (``\Twig\Loader\ArrayLoader``) to locate templates, and an
63
- environment (``\Twig\Environment``) to store its configuration.
64
-
65
- The ``render()`` method loads the template passed as a first argument and
66
- renders it with the variables passed as a second argument.
67
-
68
- As templates are generally stored on the filesystem, Twig also comes with a
69
- filesystem loader::
70
-
71
- $loader = new \Twig\Loader\FilesystemLoader('/path/to/templates');
72
- $twig = new \Twig\Environment($loader, [
73
- 'cache' => '/path/to/compilation_cache',
74
- ]);
75
-
76
- echo $twig->render('index.html', ['name' => 'Fabien']);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/recipes.rst DELETED
@@ -1,568 +0,0 @@
1
- Recipes
2
- =======
3
-
4
- .. _deprecation-notices:
5
-
6
- Displaying Deprecation Notices
7
- ------------------------------
8
-
9
- .. versionadded:: 1.21
10
- This works as of Twig 1.21.
11
-
12
- Deprecated features generate deprecation notices (via a call to the
13
- ``trigger_error()`` PHP function). By default, they are silenced and never
14
- displayed nor logged.
15
-
16
- To remove all deprecated feature usages from your templates, write and run a
17
- script along the lines of the following::
18
-
19
- require_once __DIR__.'/vendor/autoload.php';
20
-
21
- $twig = create_your_twig_env();
22
-
23
- $deprecations = new \Twig\Util\DeprecationCollector($twig);
24
-
25
- print_r($deprecations->collectDir(__DIR__.'/templates'));
26
-
27
- The ``collectDir()`` method compiles all templates found in a directory,
28
- catches deprecation notices, and return them.
29
-
30
- .. tip::
31
-
32
- If your templates are not stored on the filesystem, use the ``collect()``
33
- method instead. ``collect()`` takes a ``Traversable`` which must return
34
- template names as keys and template contents as values (as done by
35
- ``\Twig\Util\TemplateDirIterator``).
36
-
37
- However, this code won't find all deprecations (like using deprecated some Twig
38
- classes). To catch all notices, register a custom error handler like the one
39
- below::
40
-
41
- $deprecations = [];
42
- set_error_handler(function ($type, $msg) use (&$deprecations) {
43
- if (E_USER_DEPRECATED === $type) {
44
- $deprecations[] = $msg;
45
- }
46
- });
47
-
48
- // run your application
49
-
50
- print_r($deprecations);
51
-
52
- Note that most deprecation notices are triggered during **compilation**, so
53
- they won't be generated when templates are already cached.
54
-
55
- .. tip::
56
-
57
- If you want to manage the deprecation notices from your PHPUnit tests, have
58
- a look at the `symfony/phpunit-bridge
59
- <https://github.com/symfony/phpunit-bridge>`_ package, which eases the
60
- process.
61
-
62
- Making a Layout conditional
63
- ---------------------------
64
-
65
- Working with Ajax means that the same content is sometimes displayed as is,
66
- and sometimes decorated with a layout. As Twig layout template names can be
67
- any valid expression, you can pass a variable that evaluates to ``true`` when
68
- the request is made via Ajax and choose the layout accordingly:
69
-
70
- .. code-block:: twig
71
-
72
- {% extends request.ajax ? "base_ajax.html" : "base.html" %}
73
-
74
- {% block content %}
75
- This is the content to be displayed.
76
- {% endblock %}
77
-
78
- Making an Include dynamic
79
- -------------------------
80
-
81
- When including a template, its name does not need to be a string. For
82
- instance, the name can depend on the value of a variable:
83
-
84
- .. code-block:: twig
85
-
86
- {% include var ~ '_foo.html' %}
87
-
88
- If ``var`` evaluates to ``index``, the ``index_foo.html`` template will be
89
- rendered.
90
-
91
- As a matter of fact, the template name can be any valid expression, such as
92
- the following:
93
-
94
- .. code-block:: twig
95
-
96
- {% include var|default('index') ~ '_foo.html' %}
97
-
98
- Overriding a Template that also extends itself
99
- ----------------------------------------------
100
-
101
- A template can be customized in two different ways:
102
-
103
- * *Inheritance*: A template *extends* a parent template and overrides some
104
- blocks;
105
-
106
- * *Replacement*: If you use the filesystem loader, Twig loads the first
107
- template it finds in a list of configured directories; a template found in a
108
- directory *replaces* another one from a directory further in the list.
109
-
110
- But how do you combine both: *replace* a template that also extends itself
111
- (aka a template in a directory further in the list)?
112
-
113
- Let's say that your templates are loaded from both ``.../templates/mysite``
114
- and ``.../templates/default`` in this order. The ``page.twig`` template,
115
- stored in ``.../templates/default`` reads as follows:
116
-
117
- .. code-block:: twig
118
-
119
- {# page.twig #}
120
- {% extends "layout.twig" %}
121
-
122
- {% block content %}
123
- {% endblock %}
124
-
125
- You can replace this template by putting a file with the same name in
126
- ``.../templates/mysite``. And if you want to extend the original template, you
127
- might be tempted to write the following:
128
-
129
- .. code-block:: twig
130
-
131
- {# page.twig in .../templates/mysite #}
132
- {% extends "page.twig" %} {# from .../templates/default #}
133
-
134
- However, this will not work as Twig will always load the template from
135
- ``.../templates/mysite``.
136
-
137
- It turns out it is possible to get this to work, by adding a directory right
138
- at the end of your template directories, which is the parent of all of the
139
- other directories: ``.../templates`` in our case. This has the effect of
140
- making every template file within our system uniquely addressable. Most of the
141
- time you will use the "normal" paths, but in the special case of wanting to
142
- extend a template with an overriding version of itself we can reference its
143
- parent's full, unambiguous template path in the extends tag:
144
-
145
- .. code-block:: twig
146
-
147
- {# page.twig in .../templates/mysite #}
148
- {% extends "default/page.twig" %} {# from .../templates #}
149
-
150
- .. note::
151
-
152
- This recipe was inspired by the following Django wiki page:
153
- https://code.djangoproject.com/wiki/ExtendingTemplates
154
-
155
- Customizing the Syntax
156
- ----------------------
157
-
158
- Twig allows some syntax customization for the block delimiters. It's **not**
159
- recommended to use this feature as templates will be tied with your custom
160
- syntax. But for specific projects, it can make sense to change the defaults.
161
-
162
- To change the block delimiters, you need to create your own lexer object::
163
-
164
- $twig = new \Twig\Environment();
165
-
166
- $lexer = new \Twig\Lexer($twig, [
167
- 'tag_comment' => ['{#', '#}'],
168
- 'tag_block' => ['{%', '%}'],
169
- 'tag_variable' => ['{{', '}}'],
170
- 'interpolation' => ['#{', '}'],
171
- ]);
172
- $twig->setLexer($lexer);
173
-
174
- Here are some configuration example that simulates some other template engines
175
- syntax::
176
-
177
- // Ruby erb syntax
178
- $lexer = new \Twig\Lexer($twig, [
179
- 'tag_comment' => ['<%#', '%>'],
180
- 'tag_block' => ['<%', '%>'],
181
- 'tag_variable' => ['<%=', '%>'],
182
- ]);
183
-
184
- // SGML Comment Syntax
185
- $lexer = new \Twig\Lexer($twig, [
186
- 'tag_comment' => ['<!--#', '-->'],
187
- 'tag_block' => ['<!--', '-->'],
188
- 'tag_variable' => ['${', '}'],
189
- ]);
190
-
191
- // Smarty like
192
- $lexer = new \Twig\Lexer($twig, [
193
- 'tag_comment' => ['{*', '*}'],
194
- 'tag_block' => ['{', '}'],
195
- 'tag_variable' => ['{$', '}'],
196
- ]);
197
-
198
- Using dynamic Object Properties
199
- -------------------------------
200
-
201
- When Twig encounters a variable like ``article.title``, it tries to find a
202
- ``title`` public property in the ``article`` object.
203
-
204
- It also works if the property does not exist but is rather defined dynamically
205
- thanks to the magic ``__get()`` method; you need to also implement the
206
- ``__isset()`` magic method like shown in the following snippet of code::
207
-
208
- class Article
209
- {
210
- public function __get($name)
211
- {
212
- if ('title' == $name) {
213
- return 'The title';
214
- }
215
-
216
- // throw some kind of error
217
- }
218
-
219
- public function __isset($name)
220
- {
221
- if ('title' == $name) {
222
- return true;
223
- }
224
-
225
- return false;
226
- }
227
- }
228
-
229
- Accessing the parent Context in Nested Loops
230
- --------------------------------------------
231
-
232
- Sometimes, when using nested loops, you need to access the parent context. The
233
- parent context is always accessible via the ``loop.parent`` variable. For
234
- instance, if you have the following template data::
235
-
236
- $data = [
237
- 'topics' => [
238
- 'topic1' => ['Message 1 of topic 1', 'Message 2 of topic 1'],
239
- 'topic2' => ['Message 1 of topic 2', 'Message 2 of topic 2'],
240
- ],
241
- ];
242
-
243
- And the following template to display all messages in all topics:
244
-
245
- .. code-block:: twig
246
-
247
- {% for topic, messages in topics %}
248
- * {{ loop.index }}: {{ topic }}
249
- {% for message in messages %}
250
- - {{ loop.parent.loop.index }}.{{ loop.index }}: {{ message }}
251
- {% endfor %}
252
- {% endfor %}
253
-
254
- The output will be similar to:
255
-
256
- .. code-block:: text
257
-
258
- * 1: topic1
259
- - 1.1: The message 1 of topic 1
260
- - 1.2: The message 2 of topic 1
261
- * 2: topic2
262
- - 2.1: The message 1 of topic 2
263
- - 2.2: The message 2 of topic 2
264
-
265
- In the inner loop, the ``loop.parent`` variable is used to access the outer
266
- context. So, the index of the current ``topic`` defined in the outer for loop
267
- is accessible via the ``loop.parent.loop.index`` variable.
268
-
269
- Defining undefined Functions and Filters on the Fly
270
- ---------------------------------------------------
271
-
272
- When a function (or a filter) is not defined, Twig defaults to throw a
273
- ``\Twig\Error\SyntaxError`` exception. However, it can also call a `callback`_ (any
274
- valid PHP callable) which should return a function (or a filter).
275
-
276
- For filters, register callbacks with ``registerUndefinedFilterCallback()``.
277
- For functions, use ``registerUndefinedFunctionCallback()``::
278
-
279
- // auto-register all native PHP functions as Twig functions
280
- // don't try this at home as it's not secure at all!
281
- $twig->registerUndefinedFunctionCallback(function ($name) {
282
- if (function_exists($name)) {
283
- return new \Twig\TwigFunction($name, $name);
284
- }
285
-
286
- return false;
287
- });
288
-
289
- If the callable is not able to return a valid function (or filter), it must
290
- return ``false``.
291
-
292
- If you register more than one callback, Twig will call them in turn until one
293
- does not return ``false``.
294
-
295
- .. tip::
296
-
297
- As the resolution of functions and filters is done during compilation,
298
- there is no overhead when registering these callbacks.
299
-
300
- Validating the Template Syntax
301
- ------------------------------
302
-
303
- When template code is provided by a third-party (through a web interface for
304
- instance), it might be interesting to validate the template syntax before
305
- saving it. If the template code is stored in a `$template` variable, here is
306
- how you can do it::
307
-
308
- try {
309
- $twig->parse($twig->tokenize(new \Twig\Source($template)));
310
-
311
- // the $template is valid
312
- } catch (\Twig\Error\SyntaxError $e) {
313
- // $template contains one or more syntax errors
314
- }
315
-
316
- If you iterate over a set of files, you can pass the filename to the
317
- ``tokenize()`` method to get the filename in the exception message::
318
-
319
- foreach ($files as $file) {
320
- try {
321
- $twig->parse($twig->tokenize(new \Twig\Source($template, $file->getFilename(), $file)));
322
-
323
- // the $template is valid
324
- } catch (\Twig\Error\SyntaxError $e) {
325
- // $template contains one or more syntax errors
326
- }
327
- }
328
-
329
- .. versionadded:: 1.27
330
- ``\Twig\Source`` was introduced in version 1.27, pass the source and the
331
- identifier directly on previous versions.
332
-
333
- .. note::
334
-
335
- This method won't catch any sandbox policy violations because the policy
336
- is enforced during template rendering (as Twig needs the context for some
337
- checks like allowed methods on objects).
338
-
339
- Refreshing modified Templates when OPcache or APC is enabled
340
- ------------------------------------------------------------
341
-
342
- When using OPcache with ``opcache.validate_timestamps`` set to ``0`` or APC
343
- with ``apc.stat`` set to ``0`` and Twig cache enabled, clearing the template
344
- cache won't update the cache.
345
-
346
- To get around this, force Twig to invalidate the bytecode cache::
347
-
348
- $twig = new \Twig\Environment($loader, [
349
- 'cache' => new \Twig\Cache\FilesystemCache('/some/cache/path', \Twig\Cache\FilesystemCache::FORCE_BYTECODE_INVALIDATION),
350
- // ...
351
- ]);
352
-
353
- .. note::
354
-
355
- Before Twig 1.22, you should extend ``\Twig\Environment`` instead::
356
-
357
- class OpCacheAwareTwigEnvironment extends \Twig\Environment
358
- {
359
- protected function writeCacheFile($file, $content)
360
- {
361
- parent::writeCacheFile($file, $content);
362
-
363
- // Compile cached file into bytecode cache
364
- if (function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) {
365
- opcache_invalidate($file, true);
366
- } elseif (function_exists('apc_compile_file')) {
367
- apc_compile_file($file);
368
- }
369
- }
370
- }
371
-
372
- Reusing a stateful Node Visitor
373
- -------------------------------
374
-
375
- When attaching a visitor to a ``\Twig\Environment`` instance, Twig uses it to
376
- visit *all* templates it compiles. If you need to keep some state information
377
- around, you probably want to reset it when visiting a new template.
378
-
379
- This can be achieved with the following code::
380
-
381
- protected $someTemplateState = [];
382
-
383
- public function enterNode(Twig_NodeInterface $node, \Twig\Environment $env)
384
- {
385
- if ($node instanceof \Twig\Node\ModuleNode) {
386
- // reset the state as we are entering a new template
387
- $this->someTemplateState = [];
388
- }
389
-
390
- // ...
391
-
392
- return $node;
393
- }
394
-
395
- Using a Database to store Templates
396
- -----------------------------------
397
-
398
- If you are developing a CMS, templates are usually stored in a database. This
399
- recipe gives you a simple PDO template loader you can use as a starting point
400
- for your own.
401
-
402
- First, let's create a temporary in-memory SQLite3 database to work with::
403
-
404
- $dbh = new PDO('sqlite::memory:');
405
- $dbh->exec('CREATE TABLE templates (name STRING, source STRING, last_modified INTEGER)');
406
- $base = '{% block content %}{% endblock %}';
407
- $index = '
408
- {% extends "base.twig" %}
409
- {% block content %}Hello {{ name }}{% endblock %}
410
- ';
411
- $now = time();
412
- $dbh->prepare('INSERT INTO templates (name, source, last_modified) VALUES (?, ?, ?)')->execute(['base.twig', $base, $now]);
413
- $dbh->prepare('INSERT INTO templates (name, source, last_modified) VALUES (?, ?, ?)')->execute(['index.twig', $index, $now]);
414
-
415
- We have created a simple ``templates`` table that hosts two templates:
416
- ``base.twig`` and ``index.twig``.
417
-
418
- Now, let's define a loader able to use this database::
419
-
420
- class DatabaseTwigLoader implements \Twig\Loader\LoaderInterface, \Twig\Loader\ExistsLoaderInterface, \Twig\Loader\SourceContextLoaderInterface
421
- {
422
- protected $dbh;
423
-
424
- public function __construct(PDO $dbh)
425
- {
426
- $this->dbh = $dbh;
427
- }
428
-
429
- public function getSource($name)
430
- {
431
- if (false === $source = $this->getValue('source', $name)) {
432
- throw new \Twig\Error\LoaderError(sprintf('Template "%s" does not exist.', $name));
433
- }
434
-
435
- return $source;
436
- }
437
-
438
- // \Twig\Loader\SourceContextLoaderInterface as of Twig 1.27
439
- public function getSourceContext($name)
440
- {
441
- if (false === $source = $this->getValue('source', $name)) {
442
- throw new \Twig\Error\LoaderError(sprintf('Template "%s" does not exist.', $name));
443
- }
444
-
445
- return new \Twig\Source($source, $name);
446
- }
447
-
448
- // \Twig\Loader\ExistsLoaderInterface as of Twig 1.11
449
- public function exists($name)
450
- {
451
- return $name === $this->getValue('name', $name);
452
- }
453
-
454
- public function getCacheKey($name)
455
- {
456
- return $name;
457
- }
458
-
459
- public function isFresh($name, $time)
460
- {
461
- if (false === $lastModified = $this->getValue('last_modified', $name)) {
462
- return false;
463
- }
464
-
465
- return $lastModified <= $time;
466
- }
467
-
468
- protected function getValue($column, $name)
469
- {
470
- $sth = $this->dbh->prepare('SELECT '.$column.' FROM templates WHERE name = :name');
471
- $sth->execute([':name' => (string) $name]);
472
-
473
- return $sth->fetchColumn();
474
- }
475
- }
476
-
477
- Finally, here is an example on how you can use it::
478
-
479
- $loader = new DatabaseTwigLoader($dbh);
480
- $twig = new \Twig\Environment($loader);
481
-
482
- echo $twig->render('index.twig', ['name' => 'Fabien']);
483
-
484
- Using different Template Sources
485
- --------------------------------
486
-
487
- This recipe is the continuation of the previous one. Even if you store the
488
- contributed templates in a database, you might want to keep the original/base
489
- templates on the filesystem. When templates can be loaded from different
490
- sources, you need to use the ``\Twig\Loader\ChainLoader`` loader.
491
-
492
- As you can see in the previous recipe, we reference the template in the exact
493
- same way as we would have done it with a regular filesystem loader. This is
494
- the key to be able to mix and match templates coming from the database, the
495
- filesystem, or any other loader for that matter: the template name should be a
496
- logical name, and not the path from the filesystem::
497
-
498
- $loader1 = new DatabaseTwigLoader($dbh);
499
- $loader2 = new \Twig\Loader\ArrayLoader([
500
- 'base.twig' => '{% block content %}{% endblock %}',
501
- ]);
502
- $loader = new \Twig\Loader\ChainLoader([$loader1, $loader2]);
503
-
504
- $twig = new \Twig\Environment($loader);
505
-
506
- echo $twig->render('index.twig', ['name' => 'Fabien']);
507
-
508
- Now that the ``base.twig`` templates is defined in an array loader, you can
509
- remove it from the database, and everything else will still work as before.
510
-
511
- Loading a Template from a String
512
- --------------------------------
513
-
514
- From a template, you can load a template stored in a string via the
515
- ``template_from_string`` function (available as of Twig 1.11 via the
516
- ``\Twig\Extension\StringLoaderExtension`` extension):
517
-
518
- .. code-block:: twig
519
-
520
- {{ include(template_from_string("Hello {{ name }}")) }}
521
-
522
- From PHP, it's also possible to load a template stored in a string via
523
- ``\Twig\Environment::createTemplate()`` (available as of Twig 1.18)::
524
-
525
- $template = $twig->createTemplate('hello {{ name }}');
526
- echo $template->render(['name' => 'Fabien']);
527
-
528
- .. note::
529
-
530
- Never use the ``Twig_Loader_String`` loader, which has severe limitations.
531
-
532
- Using Twig and AngularJS in the same Templates
533
- ----------------------------------------------
534
-
535
- Mixing different template syntaxes in the same file is not a recommended
536
- practice as both AngularJS and Twig use the same delimiters in their syntax:
537
- ``{{`` and ``}}``.
538
-
539
- Still, if you want to use AngularJS and Twig in the same template, there are
540
- two ways to make it work depending on the amount of AngularJS you need to
541
- include in your templates:
542
-
543
- * Escaping the AngularJS delimiters by wrapping AngularJS sections with the
544
- ``{% verbatim %}`` tag or by escaping each delimiter via ``{{ '{{' }}`` and
545
- ``{{ '}}' }}``;
546
-
547
- * Changing the delimiters of one of the template engines (depending on which
548
- engine you introduced last):
549
-
550
- * For AngularJS, change the interpolation tags using the
551
- ``interpolateProvider`` service, for instance at the module initialization
552
- time:
553
-
554
- .. code-block:: javascript
555
-
556
- angular.module('myApp', []).config(function($interpolateProvider) {
557
- $interpolateProvider.startSymbol('{[').endSymbol(']}');
558
- });
559
-
560
- * For Twig, change the delimiters via the ``tag_variable`` Lexer option:
561
-
562
- .. code-block:: php
563
-
564
- $env->setLexer(new \Twig\Lexer($env, [
565
- 'tag_variable' => ['{[', ']}'],
566
- ]));
567
-
568
- .. _callback: https://secure.php.net/manual/en/function.is-callable.php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/apply.rst DELETED
@@ -1,23 +0,0 @@
1
- ``apply``
2
- =========
3
-
4
- .. versionadded:: 1.40
5
- The ``apply`` tag was added in Twig 1.40.
6
-
7
- The ``apply`` tag allows you to apply Twig filters on a block of template data:
8
-
9
- .. code-block:: twig
10
-
11
- {% apply upper %}
12
- This text becomes uppercase
13
- {% endapply %}
14
-
15
- You can also chain filters and pass arguments to them:
16
-
17
- .. code-block:: twig
18
-
19
- {% apply lower|escape('html') %}
20
- <strong>SOME TEXT</strong>
21
- {% endapply %}
22
-
23
- {# outputs "&lt;strong&gt;some text&lt;/strong&gt;" #}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/autoescape.rst DELETED
@@ -1,81 +0,0 @@
1
- ``autoescape``
2
- ==============
3
-
4
- Whether automatic escaping is enabled or not, you can mark a section of a
5
- template to be escaped or not by using the ``autoescape`` tag:
6
-
7
- .. code-block:: twig
8
-
9
- {% autoescape %}
10
- Everything will be automatically escaped in this block
11
- using the HTML strategy
12
- {% endautoescape %}
13
-
14
- {% autoescape 'html' %}
15
- Everything will be automatically escaped in this block
16
- using the HTML strategy
17
- {% endautoescape %}
18
-
19
- {% autoescape 'js' %}
20
- Everything will be automatically escaped in this block
21
- using the js escaping strategy
22
- {% endautoescape %}
23
-
24
- {% autoescape false %}
25
- Everything will be outputted as is in this block
26
- {% endautoescape %}
27
-
28
- .. note::
29
-
30
- Before Twig 1.8, the syntax was different:
31
-
32
- .. code-block:: twig
33
-
34
- {% autoescape true %}
35
- Everything will be automatically escaped in this block
36
- using the HTML strategy
37
- {% endautoescape %}
38
-
39
- {% autoescape false %}
40
- Everything will be outputted as is in this block
41
- {% endautoescape %}
42
-
43
- {% autoescape true js %}
44
- Everything will be automatically escaped in this block
45
- using the js escaping strategy
46
- {% endautoescape %}
47
-
48
- When automatic escaping is enabled everything is escaped by default except for
49
- values explicitly marked as safe. Those can be marked in the template by using
50
- the :doc:`raw<../filters/raw>` filter:
51
-
52
- .. code-block:: twig
53
-
54
- {% autoescape %}
55
- {{ safe_value|raw }}
56
- {% endautoescape %}
57
-
58
- Functions returning template data (like :doc:`macros<macro>` and
59
- :doc:`parent<../functions/parent>`) always return safe markup.
60
-
61
- .. note::
62
-
63
- Twig is smart enough to not escape an already escaped value by the
64
- :doc:`escape<../filters/escape>` filter.
65
-
66
- .. note::
67
-
68
- Twig does not escape static expressions:
69
-
70
- .. code-block:: twig
71
-
72
- {% set hello = "<strong>Hello</strong>" %}
73
- {{ hello }}
74
- {{ "<strong>world</strong>" }}
75
-
76
- Will be rendered "<strong>Hello</strong> **world**".
77
-
78
- .. note::
79
-
80
- The chapter :doc:`Twig for Developers<../api>` gives more information
81
- about when and how automatic escaping is applied.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/block.rst DELETED
@@ -1,11 +0,0 @@
1
- ``block``
2
- =========
3
-
4
- Blocks are used for inheritance and act as placeholders and replacements at
5
- the same time. They are documented in detail in the documentation for the
6
- :doc:`extends<../tags/extends>` tag.
7
-
8
- Block names should consist of alphanumeric characters, and underscores. Dashes
9
- are not permitted.
10
-
11
- .. seealso:: :doc:`block<../functions/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>`, :doc:`extends<../tags/extends>`
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/deprecated.rst DELETED
@@ -1,30 +0,0 @@
1
- ``deprecated``
2
- ==============
3
-
4
- .. versionadded:: 1.36 and 2.6
5
- The ``deprecated`` tag was added in Twig 1.36 and 2.6.
6
-
7
- Twig generates a deprecation notice (via a call to the ``trigger_error()``
8
- PHP function) where the ``deprecated`` tag is used in a template:
9
-
10
- .. code-block:: twig
11
-
12
- {# base.twig #}
13
- {% deprecated 'The "base.twig" template is deprecated, use "layout.twig" instead.' %}
14
- {% extends 'layout.twig' %}
15
-
16
- Also you can deprecate a block in the following way:
17
-
18
- .. code-block:: twig
19
-
20
- {% block hey %}
21
- {% deprecated 'The "hey" block is deprecated, use "greet" instead.' %}
22
- {{ block('greet') }}
23
- {% endblock %}
24
-
25
- {% block greet %}
26
- Hey you!
27
- {% endblock %}
28
-
29
- Note that by default, the deprecation notices are silenced and never displayed nor logged.
30
- See :ref:`deprecation-notices` to learn how to handle them.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/do.rst DELETED
@@ -1,12 +0,0 @@
1
- ``do``
2
- ======
3
-
4
- .. versionadded:: 1.5
5
- The ``do`` tag was added in Twig 1.5.
6
-
7
- The ``do`` tag works exactly like the regular variable expression (``{{ ...
8
- }}``) just that it doesn't print anything:
9
-
10
- .. code-block:: twig
11
-
12
- {% do 1 + 2 %}
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/embed.rst DELETED
@@ -1,178 +0,0 @@
1
- ``embed``
2
- =========
3
-
4
- .. versionadded:: 1.8
5
- The ``embed`` tag was added in Twig 1.8.
6
-
7
- The ``embed`` tag combines the behaviour of :doc:`include<include>` and
8
- :doc:`extends<extends>`.
9
- It allows you to include another template's contents, just like ``include``
10
- does. But it also allows you to override any block defined inside the
11
- included template, like when extending a template.
12
-
13
- Think of an embedded template as a "micro layout skeleton".
14
-
15
- .. code-block:: twig
16
-
17
- {% embed "teasers_skeleton.twig" %}
18
- {# These blocks are defined in "teasers_skeleton.twig" #}
19
- {# and we override them right here: #}
20
- {% block left_teaser %}
21
- Some content for the left teaser box
22
- {% endblock %}
23
- {% block right_teaser %}
24
- Some content for the right teaser box
25
- {% endblock %}
26
- {% endembed %}
27
-
28
- The ``embed`` tag takes the idea of template inheritance to the level of
29
- content fragments. While template inheritance allows for "document skeletons",
30
- which are filled with life by child templates, the ``embed`` tag allows you to
31
- create "skeletons" for smaller units of content and re-use and fill them
32
- anywhere you like.
33
-
34
- Since the use case may not be obvious, let's look at a simplified example.
35
- Imagine a base template shared by multiple HTML pages, defining a single block
36
- named "content":
37
-
38
- .. code-block:: text
39
-
40
- ┌─── page layout ─────────────────────┐
41
- │ │
42
- │ ┌── block "content" ──┐ │
43
- │ │ │ │
44
- │ │ │ │
45
- │ │ (child template to │ │
46
- │ │ put content here) │ │
47
- │ │ │ │
48
- │ │ │ │
49
- │ └─────────────────────┘ │
50
- │ │
51
- └─────────────────────────────────────┘
52
-
53
- Some pages ("foo" and "bar") share the same content structure -
54
- two vertically stacked boxes:
55
-
56
- .. code-block:: text
57
-
58
- ┌─── page layout ─────────────────────┐
59
- │ │
60
- │ ┌── block "content" ──┐ │
61
- │ │ ┌─ block "top" ───┐ │ │
62
- │ │ │ │ │ │
63
- │ │ └─────────────────┘ │ │
64
- │ │ ┌─ block "bottom" ┐ │ │
65
- │ │ │ │ │ │
66
- │ │ └─────────────────┘ │ │
67
- │ └─────────────────────┘ │
68
- │ │
69
- └─────────────────────────────────────┘
70
-
71
- While other pages ("boom" and "baz") share a different content structure -
72
- two boxes side by side:
73
-
74
- .. code-block:: text
75
-
76
- ┌─── page layout ─────────────────────┐
77
- │ │
78
- │ ┌── block "content" ──┐ │
79
- │ │ │ │
80
- │ │ ┌ block ┐ ┌ block ┐ │ │
81
- │ │ │"left" │ │"right"│ │ │
82
- │ │ │ │ │ │ │ │
83
- │ │ │ │ │ │ │ │
84
- │ │ └───────┘ └───────┘ │ │
85
- │ └─────────────────────┘ │
86
- │ │
87
- └─────────────────────────────────────┘
88
-
89
- Without the ``embed`` tag, you have two ways to design your templates:
90
-
91
- * Create two "intermediate" base templates that extend the master layout
92
- template: one with vertically stacked boxes to be used by the "foo" and
93
- "bar" pages and another one with side-by-side boxes for the "boom" and
94
- "baz" pages.
95
-
96
- * Embed the markup for the top/bottom and left/right boxes into each page
97
- template directly.
98
-
99
- These two solutions do not scale well because they each have a major drawback:
100
-
101
- * The first solution may indeed work for this simplified example. But imagine
102
- we add a sidebar, which may again contain different, recurring structures
103
- of content. Now we would need to create intermediate base templates for
104
- all occurring combinations of content structure and sidebar structure...
105
- and so on.
106
-
107
- * The second solution involves duplication of common code with all its negative
108
- consequences: any change involves finding and editing all affected copies
109
- of the structure, correctness has to be verified for each copy, copies may
110
- go out of sync by careless modifications etc.
111
-
112
- In such a situation, the ``embed`` tag comes in handy. The common layout
113
- code can live in a single base template, and the two different content structures,
114
- let's call them "micro layouts" go into separate templates which are embedded
115
- as necessary:
116
-
117
- Page template ``foo.twig``:
118
-
119
- .. code-block:: twig
120
-
121
- {% extends "layout_skeleton.twig" %}
122
-
123
- {% block content %}
124
- {% embed "vertical_boxes_skeleton.twig" %}
125
- {% block top %}
126
- Some content for the top box
127
- {% endblock %}
128
-
129
- {% block bottom %}
130
- Some content for the bottom box
131
- {% endblock %}
132
- {% endembed %}
133
- {% endblock %}
134
-
135
- And here is the code for ``vertical_boxes_skeleton.twig``:
136
-
137
- .. code-block:: html+twig
138
-
139
- <div class="top_box">
140
- {% block top %}
141
- Top box default content
142
- {% endblock %}
143
- </div>
144
-
145
- <div class="bottom_box">
146
- {% block bottom %}
147
- Bottom box default content
148
- {% endblock %}
149
- </div>
150
-
151
- The goal of the ``vertical_boxes_skeleton.twig`` template being to factor
152
- out the HTML markup for the boxes.
153
-
154
- The ``embed`` tag takes the exact same arguments as the ``include`` tag:
155
-
156
- .. code-block:: twig
157
-
158
- {% embed "base" with {'foo': 'bar'} %}
159
- ...
160
- {% endembed %}
161
-
162
- {% embed "base" with {'foo': 'bar'} only %}
163
- ...
164
- {% endembed %}
165
-
166
- {% embed "base" ignore missing %}
167
- ...
168
- {% endembed %}
169
-
170
- .. warning::
171
-
172
- As embedded templates do not have "names", auto-escaping strategies based
173
- on the template name won't work as expected if you change the context (for
174
- instance, if you embed a CSS/JavaScript template into an HTML one). In that
175
- case, explicitly set the default auto-escaping strategy with the
176
- ``autoescape`` tag.
177
-
178
- .. seealso:: :doc:`include<../tags/include>`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/extends.rst DELETED
@@ -1,270 +0,0 @@
1
- ``extends``
2
- ===========
3
-
4
- The ``extends`` tag can be used to extend a template from another one.
5
-
6
- .. note::
7
-
8
- Like PHP, Twig does not support multiple inheritance. So you can only have
9
- one extends tag called per rendering. However, Twig supports horizontal
10
- :doc:`reuse<use>`.
11
-
12
- Let's define a base template, ``base.html``, which defines a simple HTML
13
- skeleton document:
14
-
15
- .. code-block:: html+twig
16
-
17
- <!DOCTYPE html>
18
- <html>
19
- <head>
20
- {% block head %}
21
- <link rel="stylesheet" href="style.css" />
22
- <title>{% block title %}{% endblock %} - My Webpage</title>
23
- {% endblock %}
24
- </head>
25
- <body>
26
- <div id="content">{% block content %}{% endblock %}</div>
27
- <div id="footer">
28
- {% block footer %}
29
- &copy; Copyright 2011 by <a href="http://domain.invalid/">you</a>.
30
- {% endblock %}
31
- </div>
32
- </body>
33
- </html>
34
-
35
- In this example, the :doc:`block<block>` tags define four blocks that child
36
- templates can fill in.
37
-
38
- All the ``block`` tag does is to tell the template engine that a child
39
- template may override those portions of the template.
40
-
41
- Child Template
42
- --------------
43
-
44
- A child template might look like this:
45
-
46
- .. code-block:: twig
47
-
48
- {% extends "base.html" %}
49
-
50
- {% block title %}Index{% endblock %}
51
- {% block head %}
52
- {{ parent() }}
53
- <style type="text/css">
54
- .important { color: #336699; }
55
- </style>
56
- {% endblock %}
57
- {% block content %}
58
- <h1>Index</h1>
59
- <p class="important">
60
- Welcome on my awesome homepage.
61
- </p>
62
- {% endblock %}
63
-
64
- The ``extends`` tag is the key here. It tells the template engine that this
65
- template "extends" another template. When the template system evaluates this
66
- template, first it locates the parent. The extends tag should be the first tag
67
- in the template.
68
-
69
- Note that since the child template doesn't define the ``footer`` block, the
70
- value from the parent template is used instead.
71
-
72
- You can't define multiple ``block`` tags with the same name in the same
73
- template. This limitation exists because a block tag works in "both"
74
- directions. That is, a block tag doesn't just provide a hole to fill - it also
75
- defines the content that fills the hole in the *parent*. If there were two
76
- similarly-named ``block`` tags in a template, that template's parent wouldn't
77
- know which one of the blocks' content to use.
78
-
79
- If you want to print a block multiple times you can however use the
80
- ``block`` function:
81
-
82
- .. code-block:: twig
83
-
84
- <title>{% block title %}{% endblock %}</title>
85
- <h1>{{ block('title') }}</h1>
86
- {% block body %}{% endblock %}
87
-
88
- Parent Blocks
89
- -------------
90
-
91
- It's possible to render the contents of the parent block by using the
92
- :doc:`parent<../functions/parent>` function. This gives back the results of
93
- the parent block:
94
-
95
- .. code-block:: twig
96
-
97
- {% block sidebar %}
98
- <h3>Table Of Contents</h3>
99
- ...
100
- {{ parent() }}
101
- {% endblock %}
102
-
103
- Named Block End-Tags
104
- --------------------
105
-
106
- Twig allows you to put the name of the block after the end tag for better
107
- readability (the name after the ``endblock`` word must match the block name):
108
-
109
- .. code-block:: twig
110
-
111
- {% block sidebar %}
112
- {% block inner_sidebar %}
113
- ...
114
- {% endblock inner_sidebar %}
115
- {% endblock sidebar %}
116
-
117
- Block Nesting and Scope
118
- -----------------------
119
-
120
- Blocks can be nested for more complex layouts. Per default, blocks have access
121
- to variables from outer scopes:
122
-
123
- .. code-block:: twig
124
-
125
- {% for item in seq %}
126
- <li>{% block loop_item %}{{ item }}{% endblock %}</li>
127
- {% endfor %}
128
-
129
- Block Shortcuts
130
- ---------------
131
-
132
- For blocks with little content, it's possible to use a shortcut syntax. The
133
- following constructs do the same thing:
134
-
135
- .. code-block:: twig
136
-
137
- {% block title %}
138
- {{ page_title|title }}
139
- {% endblock %}
140
-
141
- .. code-block:: twig
142
-
143
- {% block title page_title|title %}
144
-
145
- Dynamic Inheritance
146
- -------------------
147
-
148
- Twig supports dynamic inheritance by using a variable as the base template:
149
-
150
- .. code-block:: twig
151
-
152
- {% extends some_var %}
153
-
154
- If the variable evaluates to a ``\Twig\Template`` or a ``\Twig\TemplateWrapper``
155
- instance, Twig will use it as the parent template::
156
-
157
- // {% extends layout %}
158
-
159
- // deprecated as of Twig 1.28
160
- $layout = $twig->loadTemplate('some_layout_template.twig');
161
-
162
- // as of Twig 1.28
163
- $layout = $twig->load('some_layout_template.twig');
164
-
165
- $twig->display('template.twig', ['layout' => $layout]);
166
-
167
- .. versionadded:: 1.2
168
- The possibility to pass an array of templates has been added in Twig 1.2.
169
-
170
- You can also provide a list of templates that are checked for existence. The
171
- first template that exists will be used as a parent:
172
-
173
- .. code-block:: twig
174
-
175
- {% extends ['layout.html', 'base_layout.html'] %}
176
-
177
- Conditional Inheritance
178
- -----------------------
179
-
180
- As the template name for the parent can be any valid Twig expression, it's
181
- possible to make the inheritance mechanism conditional:
182
-
183
- .. code-block:: twig
184
-
185
- {% extends standalone ? "minimum.html" : "base.html" %}
186
-
187
- In this example, the template will extend the "minimum.html" layout template
188
- if the ``standalone`` variable evaluates to ``true``, and "base.html"
189
- otherwise.
190
-
191
- How do blocks work?
192
- -------------------
193
-
194
- A block provides a way to change how a certain part of a template is rendered
195
- but it does not interfere in any way with the logic around it.
196
-
197
- Let's take the following example to illustrate how a block works and more
198
- importantly, how it does not work:
199
-
200
- .. code-block:: twig
201
-
202
- {# base.twig #}
203
-
204
- {% for post in posts %}
205
- {% block post %}
206
- <h1>{{ post.title }}</h1>
207
- <p>{{ post.body }}</p>
208
- {% endblock %}
209
- {% endfor %}
210
-
211
- If you render this template, the result would be exactly the same with or
212
- without the ``block`` tag. The ``block`` inside the ``for`` loop is just a way
213
- to make it overridable by a child template:
214
-
215
- .. code-block:: twig
216
-
217
- {# child.twig #}
218
-
219
- {% extends "base.twig" %}
220
-
221
- {% block post %}
222
- <article>
223
- <header>{{ post.title }}</header>
224
- <section>{{ post.text }}</section>
225
- </article>
226
- {% endblock %}
227
-
228
- Now, when rendering the child template, the loop is going to use the block
229
- defined in the child template instead of the one defined in the base one; the
230
- executed template is then equivalent to the following one:
231
-
232
- .. code-block:: twig
233
-
234
- {% for post in posts %}
235
- <article>
236
- <header>{{ post.title }}</header>
237
- <section>{{ post.text }}</section>
238
- </article>
239
- {% endfor %}
240
-
241
- Let's take another example: a block included within an ``if`` statement:
242
-
243
- .. code-block:: twig
244
-
245
- {% if posts is empty %}
246
- {% block head %}
247
- {{ parent() }}
248
-
249
- <meta name="robots" content="noindex, follow">
250
- {% endblock head %}
251
- {% endif %}
252
-
253
- Contrary to what you might think, this template does not define a block
254
- conditionally; it just makes overridable by a child template the output of
255
- what will be rendered when the condition is ``true``.
256
-
257
- If you want the output to be displayed conditionally, use the following
258
- instead:
259
-
260
- .. code-block:: twig
261
-
262
- {% block head %}
263
- {{ parent() }}
264
-
265
- {% if posts is empty %}
266
- <meta name="robots" content="noindex, follow">
267
- {% endif %}
268
- {% endblock head %}
269
-
270
- .. seealso:: :doc:`block<../functions/block>`, :doc:`block<../tags/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/filter.rst DELETED
@@ -1,26 +0,0 @@
1
- ``filter``
2
- ==========
3
-
4
- .. note::
5
-
6
- As of Twig 1.40, you should use the ``apply`` tag instead which does the
7
- same thing except that the wrapped template data is not scoped.
8
-
9
- Filter sections allow you to apply regular Twig filters on a block of template
10
- data. Just wrap the code in the special ``filter`` section:
11
-
12
- .. code-block:: twig
13
-
14
- {% filter upper %}
15
- This text becomes uppercase
16
- {% endfilter %}
17
-
18
- You can also chain filters and pass arguments to them:
19
-
20
- .. code-block:: twig
21
-
22
- {% filter lower|escape('html') %}
23
- <strong>SOME TEXT</strong>
24
- {% endfilter %}
25
-
26
- {# outputs "&lt;strong&gt;some text&lt;/strong&gt;" #}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/flush.rst DELETED
@@ -1,17 +0,0 @@
1
- ``flush``
2
- =========
3
-
4
- .. versionadded:: 1.5
5
- The flush tag was added in Twig 1.5.
6
-
7
- The ``flush`` tag tells Twig to flush the output buffer:
8
-
9
- .. code-block:: twig
10
-
11
- {% flush %}
12
-
13
- .. note::
14
-
15
- Internally, Twig uses the PHP `flush`_ function.
16
-
17
- .. _`flush`: https://secure.php.net/flush
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/for.rst DELETED
@@ -1,179 +0,0 @@
1
- ``for``
2
- =======
3
-
4
- Loop over each item in a sequence. For example, to display a list of users
5
- provided in a variable called ``users``:
6
-
7
- .. code-block:: twig
8
-
9
- <h1>Members</h1>
10
- <ul>
11
- {% for user in users %}
12
- <li>{{ user.username|e }}</li>
13
- {% endfor %}
14
- </ul>
15
-
16
- .. note::
17
-
18
- A sequence can be either an array or an object implementing the
19
- ``Traversable`` interface.
20
-
21
- If you do need to iterate over a sequence of numbers, you can use the ``..``
22
- operator:
23
-
24
- .. code-block:: twig
25
-
26
- {% for i in 0..10 %}
27
- * {{ i }}
28
- {% endfor %}
29
-
30
- The above snippet of code would print all numbers from 0 to 10.
31
-
32
- It can be also useful with letters:
33
-
34
- .. code-block:: twig
35
-
36
- {% for letter in 'a'..'z' %}
37
- * {{ letter }}
38
- {% endfor %}
39
-
40
- The ``..`` operator can take any expression at both sides:
41
-
42
- .. code-block:: twig
43
-
44
- {% for letter in 'a'|upper..'z'|upper %}
45
- * {{ letter }}
46
- {% endfor %}
47
-
48
- .. tip:
49
-
50
- If you need a step different from 1, you can use the ``range`` function
51
- instead.
52
-
53
- The `loop` variable
54
- -------------------
55
-
56
- Inside of a ``for`` loop block you can access some special variables:
57
-
58
- ===================== =============================================================
59
- Variable Description
60
- ===================== =============================================================
61
- ``loop.index`` The current iteration of the loop. (1 indexed)
62
- ``loop.index0`` The current iteration of the loop. (0 indexed)
63
- ``loop.revindex`` The number of iterations from the end of the loop (1 indexed)
64
- ``loop.revindex0`` The number of iterations from the end of the loop (0 indexed)
65
- ``loop.first`` True if first iteration
66
- ``loop.last`` True if last iteration
67
- ``loop.length`` The number of items in the sequence
68
- ``loop.parent`` The parent context
69
- ===================== =============================================================
70
-
71
- .. code-block:: twig
72
-
73
- {% for user in users %}
74
- {{ loop.index }} - {{ user.username }}
75
- {% endfor %}
76
-
77
- .. note::
78
-
79
- The ``loop.length``, ``loop.revindex``, ``loop.revindex0``, and
80
- ``loop.last`` variables are only available for PHP arrays, or objects that
81
- implement the ``Countable`` interface. They are also not available when
82
- looping with a condition.
83
-
84
- .. versionadded:: 1.2
85
- The ``if`` modifier support has been added in Twig 1.2.
86
-
87
- Adding a condition
88
- ------------------
89
-
90
- .. tip::
91
-
92
- As of Twig 1.41, use the :doc:`filter <../filters/filter>` filter instead,
93
- or an ``if`` condition inside the ``for`` body (if your condition depends on
94
- a variable updated inside the loop and you are not using the ``loop``
95
- variable).
96
-
97
- Unlike in PHP, it's not possible to ``break`` or ``continue`` in a loop. You
98
- can however filter the sequence during iteration which allows you to skip
99
- items. The following example skips all the users which are not active:
100
-
101
- .. code-block:: twig
102
-
103
- <ul>
104
- {% for user in users if user.active %}
105
- <li>{{ user.username|e }}</li>
106
- {% endfor %}
107
- </ul>
108
-
109
- The advantage is that the special loop variable will count correctly thus not
110
- counting the users not iterated over. Keep in mind that properties like
111
- ``loop.last`` will not be defined when using loop conditions.
112
-
113
- .. note::
114
-
115
- Using the ``loop`` variable within the condition is not recommended as it
116
- will probably not be doing what you expect it to. For instance, adding a
117
- condition like ``loop.index > 4`` won't work as the index is only
118
- incremented when the condition is true (so the condition will never
119
- match).
120
-
121
- The `else` Clause
122
- -----------------
123
-
124
- If no iteration took place because the sequence was empty, you can render a
125
- replacement block by using ``else``:
126
-
127
- .. code-block:: twig
128
-
129
- <ul>
130
- {% for user in users %}
131
- <li>{{ user.username|e }}</li>
132
- {% else %}
133
- <li><em>no user found</em></li>
134
- {% endfor %}
135
- </ul>
136
-
137
- Iterating over Keys
138
- -------------------
139
-
140
- By default, a loop iterates over the values of the sequence. You can iterate
141
- on keys by using the ``keys`` filter:
142
-
143
- .. code-block:: twig
144
-
145
- <h1>Members</h1>
146
- <ul>
147
- {% for key in users|keys %}
148
- <li>{{ key }}</li>
149
- {% endfor %}
150
- </ul>
151
-
152
- Iterating over Keys and Values
153
- ------------------------------
154
-
155
- You can also access both keys and values:
156
-
157
- .. code-block:: twig
158
-
159
- <h1>Members</h1>
160
- <ul>
161
- {% for key, user in users %}
162
- <li>{{ key }}: {{ user.username|e }}</li>
163
- {% endfor %}
164
- </ul>
165
-
166
- Iterating over a Subset
167
- -----------------------
168
-
169
- You might want to iterate over a subset of values. This can be achieved using
170
- the :doc:`slice <../filters/slice>` filter:
171
-
172
- .. code-block:: twig
173
-
174
- <h1>Top Ten Members</h1>
175
- <ul>
176
- {% for user in users|slice(0, 10) %}
177
- <li>{{ user.username|e }}</li>
178
- {% endfor %}
179
- </ul>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/from.rst DELETED
@@ -1,6 +0,0 @@
1
- ``from``
2
- ========
3
-
4
- The ``from`` tag imports :doc:`macro<../tags/macro>` names into the current
5
- namespace. The tag is documented in detail in the documentation for the
6
- :doc:`macro<../tags/macro>` tag.
 
 
 
 
 
 
vendor/twig/twig/doc/tags/if.rst DELETED
@@ -1,79 +0,0 @@
1
- ``if``
2
- ======
3
-
4
- The ``if`` statement in Twig is comparable with the if statements of PHP.
5
-
6
- In the simplest form you can use it to test if an expression evaluates to
7
- ``true``:
8
-
9
- .. code-block:: twig
10
-
11
- {% if online == false %}
12
- <p>Our website is in maintenance mode. Please, come back later.</p>
13
- {% endif %}
14
-
15
- You can also test if an array is not empty:
16
-
17
- .. code-block:: twig
18
-
19
- {% if users %}
20
- <ul>
21
- {% for user in users %}
22
- <li>{{ user.username|e }}</li>
23
- {% endfor %}
24
- </ul>
25
- {% endif %}
26
-
27
- .. note::
28
-
29
- If you want to test if the variable is defined, use ``if users is
30
- defined`` instead.
31
-
32
- You can also use ``not`` to check for values that evaluate to ``false``:
33
-
34
- .. code-block:: twig
35
-
36
- {% if not user.subscribed %}
37
- <p>You are not subscribed to our mailing list.</p>
38
- {% endif %}
39
-
40
- For multiple conditions, ``and`` and ``or`` can be used:
41
-
42
- .. code-block:: twig
43
-
44
- {% if temperature > 18 and temperature < 27 %}
45
- <p>It's a nice day for a walk in the park.</p>
46
- {% endif %}
47
-
48
- For multiple branches ``elseif`` and ``else`` can be used like in PHP. You can
49
- use more complex ``expressions`` there too:
50
-
51
- .. code-block:: twig
52
-
53
- {% if product.stock > 10 %}
54
- Available
55
- {% elseif product.stock > 0 %}
56
- Only {{ product.stock }} left!
57
- {% else %}
58
- Sold-out!
59
- {% endif %}
60
-
61
- .. note::
62
-
63
- The rules to determine if an expression is ``true`` or ``false`` are the
64
- same as in PHP; here are the edge cases rules:
65
-
66
- ====================== ====================
67
- Value Boolean evaluation
68
- ====================== ====================
69
- empty string false
70
- numeric zero false
71
- NAN (Not A Number) true
72
- INF (Infinity) true
73
- whitespace-only string true
74
- string "0" or '0' false
75
- empty array false
76
- null false
77
- non-empty array true
78
- object true
79
- ====================== ====================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/import.rst DELETED
@@ -1,6 +0,0 @@
1
- ``import``
2
- ==========
3
-
4
- The ``import`` tag imports :doc:`macro<../tags/macro>` names in a local
5
- variable. The tag is documented in detail in the documentation for the
6
- :doc:`macro<../tags/macro>` tag.
 
 
 
 
 
 
vendor/twig/twig/doc/tags/include.rst DELETED
@@ -1,114 +0,0 @@
1
- ``include``
2
- ===========
3
-
4
- The ``include`` statement includes a template and returns the rendered content
5
- of that file:
6
-
7
- .. code-block:: twig
8
-
9
- {% include 'header.html' %}
10
- Body
11
- {% include 'footer.html' %}
12
-
13
- .. note::
14
-
15
- As of Twig 1.12, it is recommended to use the
16
- :doc:`include<../functions/include>` function instead as it provides the
17
- same features with a bit more flexibility:
18
-
19
- * The ``include`` function is semantically more "correct" (including a
20
- template outputs its rendered contents in the current scope; a tag should
21
- not display anything);
22
-
23
- * It's easier to store the rendered template in a variable when using
24
- the ``include`` function:
25
-
26
- .. code-block:: twig
27
-
28
- {% set content %}{% include 'template.html' %}{% endset %}
29
-
30
- {# vs #}
31
-
32
- {% set content = include('template.html') %}
33
-
34
- * The ``include`` function does not impose any specific order for
35
- arguments thanks to :ref:`named arguments <named-arguments>`.
36
-
37
- Included templates have access to the variables of the active context.
38
-
39
- If you are using the filesystem loader, the templates are looked for in the
40
- paths defined by it.
41
-
42
- You can add additional variables by passing them after the ``with`` keyword:
43
-
44
- .. code-block:: twig
45
-
46
- {# template.html will have access to the variables from the current context and the additional ones provided #}
47
- {% include 'template.html' with {'foo': 'bar'} %}
48
-
49
- {% set vars = {'foo': 'bar'} %}
50
- {% include 'template.html' with vars %}
51
-
52
- You can disable access to the context by appending the ``only`` keyword:
53
-
54
- .. code-block:: twig
55
-
56
- {# only the foo variable will be accessible #}
57
- {% include 'template.html' with {'foo': 'bar'} only %}
58
-
59
- .. code-block:: twig
60
-
61
- {# no variables will be accessible #}
62
- {% include 'template.html' only %}
63
-
64
- .. tip::
65
-
66
- When including a template created by an end user, you should consider
67
- sandboxing it. More information in the :doc:`Twig for Developers<../api>`
68
- chapter and in the :doc:`sandbox<../tags/sandbox>` tag documentation.
69
-
70
- The template name can be any valid Twig expression:
71
-
72
- .. code-block:: twig
73
-
74
- {% include some_var %}
75
- {% include ajax ? 'ajax.html' : 'not_ajax.html' %}
76
-
77
- And if the expression evaluates to a ``\Twig\Template`` or a
78
- ``\Twig\TemplateWrapper`` instance, Twig will use it directly::
79
-
80
- // {% include template %}
81
-
82
- // deprecated as of Twig 1.28
83
- $template = $twig->loadTemplate('some_template.twig');
84
-
85
- // as of Twig 1.28
86
- $template = $twig->load('some_template.twig');
87
-
88
- $twig->display('template.twig', ['template' => $template]);
89
-
90
- .. versionadded:: 1.2
91
- The ``ignore missing`` feature has been added in Twig 1.2.
92
-
93
- You can mark an include with ``ignore missing`` in which case Twig will ignore
94
- the statement if the template to be included does not exist. It has to be
95
- placed just after the template name. Here some valid examples:
96
-
97
- .. code-block:: twig
98
-
99
- {% include 'sidebar.html' ignore missing %}
100
- {% include 'sidebar.html' ignore missing with {'foo': 'bar'} %}
101
- {% include 'sidebar.html' ignore missing only %}
102
-
103
- .. versionadded:: 1.2
104
- The possibility to pass an array of templates has been added in Twig 1.2.
105
-
106
- You can also provide a list of templates that are checked for existence before
107
- inclusion. The first template that exists will be included:
108
-
109
- .. code-block:: twig
110
-
111
- {% include ['page_detailed.html', 'page.html'] %}
112
-
113
- If ``ignore missing`` is given, it will fall back to rendering nothing if none
114
- of the templates exist, otherwise it will throw an exception.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/index.rst DELETED
@@ -1,27 +0,0 @@
1
- Tags
2
- ====
3
-
4
- .. toctree::
5
- :maxdepth: 1
6
-
7
- apply
8
- autoescape
9
- block
10
- deprecated
11
- do
12
- embed
13
- extends
14
- filter
15
- flush
16
- for
17
- from
18
- if
19
- import
20
- include
21
- macro
22
- sandbox
23
- set
24
- spaceless
25
- use
26
- verbatim
27
- with
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/macro.rst DELETED
@@ -1,139 +0,0 @@
1
- ``macro``
2
- =========
3
-
4
- .. versionadded:: 1.12
5
-
6
- The possibility to define default values for arguments in the macro
7
- signature was added in Twig 1.12.
8
-
9
- Macros are comparable with functions in regular programming languages. They
10
- are useful to reuse template fragments to not repeat yourself.
11
-
12
- Macros are defined in regular templates.
13
-
14
- Imagine having a generic helper template that define how to render HTML forms
15
- via macros (called ``forms.html``):
16
-
17
- .. code-block:: twig
18
-
19
- {% macro input(name, value, type = "text", size = 20) %}
20
- <input type="{{ type }}" name="{{ name }}" value="{{ value|e }}" size="{{ size }}" />
21
- {% endmacro %}
22
-
23
- {% macro textarea(name, value, rows = 10, cols = 40) %}
24
- <textarea name="{{ name }}" rows="{{ rows }}" cols="{{ cols }}">{{ value|e }}</textarea>
25
- {% endmacro %}
26
-
27
- Each macro argument can have a default value (here ``text`` is the default value
28
- for ``type`` if not provided in the call).
29
-
30
- .. note::
31
-
32
- Before Twig 1.12, defining default argument values was done via the
33
- ``default`` filter in the macro body:
34
-
35
- .. code-block:: twig
36
-
37
- {% macro input(name, value, type, size) %}
38
- <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
39
- {% endmacro %}
40
-
41
- Macros differ from native PHP functions in a few ways:
42
-
43
- * Arguments of a macro are always optional.
44
-
45
- * If extra positional arguments are passed to a macro, they end up in the
46
- special ``varargs`` variable as a list of values.
47
-
48
- But as with PHP functions, macros don't have access to the current template
49
- variables.
50
-
51
- .. tip::
52
-
53
- You can pass the whole context as an argument by using the special
54
- ``_context`` variable.
55
-
56
- Import
57
- ------
58
-
59
- There are two ways to import macros. You can import the complete template
60
- containing the macros into a local variable (via the ``import`` tag) or only
61
- import specific macros from the template (via the ``from`` tag).
62
-
63
- To import all macros from a template into a local variable, use the ``import``
64
- tag:
65
-
66
- .. code-block:: twig
67
-
68
- {% import "forms.html" as forms %}
69
-
70
- The above ``import`` call imports the ``forms.html`` file (which can contain
71
- only macros, or a template and some macros), and import the macros as items of
72
- the ``forms`` local variable.
73
-
74
- The macros can then be called at will in the *current* template:
75
-
76
- .. code-block:: twig
77
-
78
- <p>{{ forms.input('username') }}</p>
79
- <p>{{ forms.input('password', null, 'password') }}</p>
80
-
81
- When you want to use a macro in another macro from the same file, you need to
82
- import it locally:
83
-
84
- .. code-block:: twig
85
-
86
- {% macro input(name, value, type, size) %}
87
- <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
88
- {% endmacro %}
89
-
90
- {% macro wrapped_input(name, value, type, size) %}
91
- {% import _self as forms %}
92
-
93
- <div class="field">
94
- {{ forms.input(name, value, type, size) }}
95
- </div>
96
- {% endmacro %}
97
-
98
- Alternatively you can import names from the template into the current namespace
99
- via the ``from`` tag:
100
-
101
- .. code-block:: twig
102
-
103
- {% from 'forms.html' import input as input_field, textarea %}
104
-
105
- <p>{{ input_field('password', '', 'password') }}</p>
106
- <p>{{ textarea('comment') }}</p>
107
-
108
- .. note::
109
-
110
- Importing macros using ``import`` or ``from`` is **local** to the current
111
- file. The imported macros are not available in included templates or child
112
- templates; you need to explicitly re-import macros in each file.
113
-
114
- .. tip::
115
-
116
- To import macros from the current file, use the special ``_self`` variable:
117
-
118
- .. code-block:: twig
119
-
120
- {% import _self as forms %}
121
-
122
- <p>{{ forms.input('username') }}</p>
123
-
124
- When you define a macro in the template where you are going to use it, you
125
- might be tempted to call the macro directly via ``_self.input()`` instead of
126
- importing it; even if it seems to work, this is just a side-effect of the
127
- current implementation and it won't work anymore in Twig 2.x.
128
-
129
- Named Macro End-Tags
130
- --------------------
131
-
132
- Twig allows you to put the name of the macro after the end tag for better
133
- readability (the name after the ``endmacro`` word must match the macro name):
134
-
135
- .. code-block:: twig
136
-
137
- {% macro input() %}
138
- ...
139
- {% endmacro input %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/sandbox.rst DELETED
@@ -1,30 +0,0 @@
1
- ``sandbox``
2
- ===========
3
-
4
- The ``sandbox`` tag can be used to enable the sandboxing mode for an included
5
- template, when sandboxing is not enabled globally for the Twig environment:
6
-
7
- .. code-block:: twig
8
-
9
- {% sandbox %}
10
- {% include 'user.html' %}
11
- {% endsandbox %}
12
-
13
- .. warning::
14
-
15
- The ``sandbox`` tag is only available when the sandbox extension is
16
- enabled (see the :doc:`Twig for Developers<../api>` chapter).
17
-
18
- .. note::
19
-
20
- The ``sandbox`` tag can only be used to sandbox an include tag and it
21
- cannot be used to sandbox a section of a template. The following example
22
- won't work:
23
-
24
- .. code-block:: twig
25
-
26
- {% sandbox %}
27
- {% for i in 1..2 %}
28
- {{ i }}
29
- {% endfor %}
30
- {% endsandbox %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/set.rst DELETED
@@ -1,78 +0,0 @@
1
- ``set``
2
- =======
3
-
4
- Inside code blocks you can also assign values to variables. Assignments use
5
- the ``set`` tag and can have multiple targets.
6
-
7
- Here is how you can assign the ``bar`` value to the ``foo`` variable:
8
-
9
- .. code-block:: twig
10
-
11
- {% set foo = 'bar' %}
12
-
13
- After the ``set`` call, the ``foo`` variable is available in the template like
14
- any other ones:
15
-
16
- .. code-block:: twig
17
-
18
- {# displays bar #}
19
- {{ foo }}
20
-
21
- The assigned value can be any valid :ref:`Twig expression
22
- <twig-expressions>`:
23
-
24
- .. code-block:: twig
25
-
26
- {% set foo = [1, 2] %}
27
- {% set foo = {'foo': 'bar'} %}
28
- {% set foo = 'foo' ~ 'bar' %}
29
-
30
- Several variables can be assigned in one block:
31
-
32
- .. code-block:: twig
33
-
34
- {% set foo, bar = 'foo', 'bar' %}
35
-
36
- {# is equivalent to #}
37
-
38
- {% set foo = 'foo' %}
39
- {% set bar = 'bar' %}
40
-
41
- The ``set`` tag can also be used to 'capture' chunks of text:
42
-
43
- .. code-block:: twig
44
-
45
- {% set foo %}
46
- <div id="pagination">
47
- ...
48
- </div>
49
- {% endset %}
50
-
51
- .. caution::
52
-
53
- If you enable automatic output escaping, Twig will only consider the
54
- content to be safe when capturing chunks of text.
55
-
56
- .. note::
57
-
58
- Note that loops are scoped in Twig; therefore a variable declared inside a
59
- ``for`` loop is not accessible outside the loop itself:
60
-
61
- .. code-block:: twig
62
-
63
- {% for item in list %}
64
- {% set foo = item %}
65
- {% endfor %}
66
-
67
- {# foo is NOT available #}
68
-
69
- If you want to access the variable, just declare it before the loop:
70
-
71
- .. code-block:: twig
72
-
73
- {% set foo = "" %}
74
- {% for item in list %}
75
- {% set foo = item %}
76
- {% endfor %}
77
-
78
- {# foo is available #}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/spaceless.rst DELETED
@@ -1,41 +0,0 @@
1
- ``spaceless``
2
- =============
3
-
4
- .. tip::
5
-
6
- As of Twig 1.38, use the :doc:`spaceless <../filters/spaceless>` filter instead.
7
-
8
- Use the ``spaceless`` tag to remove whitespace *between HTML tags*, not
9
- whitespace within HTML tags or whitespace in plain text:
10
-
11
- .. code-block:: twig
12
-
13
- {% spaceless %}
14
- <div>
15
- <strong>foo</strong>
16
- </div>
17
- {% endspaceless %}
18
-
19
- {# output will be <div><strong>foo</strong></div> #}
20
-
21
- This tag is not meant to "optimize" the size of the generated HTML content but
22
- merely to avoid extra whitespace between HTML tags to avoid browser rendering
23
- quirks under some circumstances.
24
-
25
- .. tip::
26
-
27
- If you want to optimize the size of the generated HTML content, gzip
28
- compress the output instead.
29
-
30
- .. tip::
31
-
32
- If you want to create a tag that actually removes all extra whitespace in
33
- an HTML string, be warned that this is not as easy as it seems to be
34
- (think of ``textarea`` or ``pre`` tags for instance). Using a third-party
35
- library like Tidy is probably a better idea.
36
-
37
- .. tip::
38
-
39
- For more information on whitespace control, read the
40
- :ref:`dedicated section <templates-whitespace-control>` of the documentation and learn how
41
- you can also use the whitespace control modifier on your tags.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/use.rst DELETED
@@ -1,124 +0,0 @@
1
- ``use``
2
- =======
3
-
4
- .. versionadded:: 1.1
5
- Horizontal reuse was added in Twig 1.1.
6
-
7
- .. note::
8
-
9
- Horizontal reuse is an advanced Twig feature that is hardly ever needed in
10
- regular templates. It is mainly used by projects that need to make
11
- template blocks reusable without using inheritance.
12
-
13
- Template inheritance is one of the most powerful features of Twig but it is
14
- limited to single inheritance; a template can only extend one other template.
15
- This limitation makes template inheritance simple to understand and easy to
16
- debug:
17
-
18
- .. code-block:: twig
19
-
20
- {% extends "base.html" %}
21
-
22
- {% block title %}{% endblock %}
23
- {% block content %}{% endblock %}
24
-
25
- Horizontal reuse is a way to achieve the same goal as multiple inheritance,
26
- but without the associated complexity:
27
-
28
- .. code-block:: twig
29
-
30
- {% extends "base.html" %}
31
-
32
- {% use "blocks.html" %}
33
-
34
- {% block title %}{% endblock %}
35
- {% block content %}{% endblock %}
36
-
37
- The ``use`` statement tells Twig to import the blocks defined in
38
- ``blocks.html`` into the current template (it's like macros, but for blocks):
39
-
40
- .. code-block:: twig
41
-
42
- {# blocks.html #}
43
-
44
- {% block sidebar %}{% endblock %}
45
-
46
- In this example, the ``use`` statement imports the ``sidebar`` block into the
47
- main template. The code is mostly equivalent to the following one (the
48
- imported blocks are not outputted automatically):
49
-
50
- .. code-block:: twig
51
-
52
- {% extends "base.html" %}
53
-
54
- {% block sidebar %}{% endblock %}
55
- {% block title %}{% endblock %}
56
- {% block content %}{% endblock %}
57
-
58
- .. note::
59
-
60
- The ``use`` tag only imports a template if it does not extend another
61
- template, if it does not define macros, and if the body is empty. But it
62
- can *use* other templates.
63
-
64
- .. note::
65
-
66
- Because ``use`` statements are resolved independently of the context
67
- passed to the template, the template reference cannot be an expression.
68
-
69
- The main template can also override any imported block. If the template
70
- already defines the ``sidebar`` block, then the one defined in ``blocks.html``
71
- is ignored. To avoid name conflicts, you can rename imported blocks:
72
-
73
- .. code-block:: twig
74
-
75
- {% extends "base.html" %}
76
-
77
- {% use "blocks.html" with sidebar as base_sidebar, title as base_title %}
78
-
79
- {% block sidebar %}{% endblock %}
80
- {% block title %}{% endblock %}
81
- {% block content %}{% endblock %}
82
-
83
- .. versionadded:: 1.3
84
- The ``parent()`` support was added in Twig 1.3.
85
-
86
- The ``parent()`` function automatically determines the correct inheritance
87
- tree, so it can be used when overriding a block defined in an imported
88
- template:
89
-
90
- .. code-block:: twig
91
-
92
- {% extends "base.html" %}
93
-
94
- {% use "blocks.html" %}
95
-
96
- {% block sidebar %}
97
- {{ parent() }}
98
- {% endblock %}
99
-
100
- {% block title %}{% endblock %}
101
- {% block content %}{% endblock %}
102
-
103
- In this example, ``parent()`` will correctly call the ``sidebar`` block from
104
- the ``blocks.html`` template.
105
-
106
- .. tip::
107
-
108
- In Twig 1.2, renaming allows you to simulate inheritance by calling the
109
- "parent" block:
110
-
111
- .. code-block:: twig
112
-
113
- {% extends "base.html" %}
114
-
115
- {% use "blocks.html" with sidebar as parent_sidebar %}
116
-
117
- {% block sidebar %}
118
- {{ block('parent_sidebar') }}
119
- {% endblock %}
120
-
121
- .. note::
122
-
123
- You can use as many ``use`` statements as you want in any given template.
124
- If two imported templates define the same block, the latest one wins.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/verbatim.rst DELETED
@@ -1,24 +0,0 @@
1
- ``verbatim``
2
- ============
3
-
4
- .. versionadded:: 1.12
5
- The ``verbatim`` tag was added in Twig 1.12 (it was named ``raw`` before).
6
-
7
- The ``verbatim`` tag marks sections as being raw text that should not be
8
- parsed. For example to put Twig syntax as example into a template you can use
9
- this snippet:
10
-
11
- .. code-block:: twig
12
-
13
- {% verbatim %}
14
- <ul>
15
- {% for item in seq %}
16
- <li>{{ item }}</li>
17
- {% endfor %}
18
- </ul>
19
- {% endverbatim %}
20
-
21
- .. note::
22
-
23
- The ``verbatim`` tag works in the exact same way as the old ``raw`` tag,
24
- but was renamed to avoid confusion with the ``raw`` filter.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tags/with.rst DELETED
@@ -1,44 +0,0 @@
1
- ``with``
2
- ========
3
-
4
- .. versionadded:: 1.28
5
- The ``with`` tag was added in Twig 1.28.
6
-
7
- Use the ``with`` tag to create a new inner scope. Variables set within this
8
- scope are not visible outside of the scope:
9
-
10
- .. code-block:: twig
11
-
12
- {% with %}
13
- {% set foo = 42 %}
14
- {{ foo }} foo is 42 here
15
- {% endwith %}
16
- foo is not visible here any longer
17
-
18
- Instead of defining variables at the beginning of the scope, you can pass a
19
- hash of variables you want to define in the ``with`` tag; the previous example
20
- is equivalent to the following one:
21
-
22
- .. code-block:: twig
23
-
24
- {% with { foo: 42 } %}
25
- {{ foo }} foo is 42 here
26
- {% endwith %}
27
- foo is not visible here any longer
28
-
29
- {# it works with any expression that resolves to a hash #}
30
- {% set vars = { foo: 42 } %}
31
- {% with vars %}
32
- ...
33
- {% endwith %}
34
-
35
- By default, the inner scope has access to the outer scope context; you can
36
- disable this behavior by appending the ``only`` keyword:
37
-
38
- .. code-block:: twig
39
-
40
- {% set bar = 'bar' %}
41
- {% with { foo: 42 } only %}
42
- {# only foo is defined #}
43
- {# bar is not defined #}
44
- {% endwith %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/templates.rst DELETED
@@ -1,884 +0,0 @@
1
- Twig for Template Designers
2
- ===========================
3
-
4
- This document describes the syntax and semantics of the template engine and
5
- will be most useful as reference to those creating Twig templates.
6
-
7
- Synopsis
8
- --------
9
-
10
- A template is a regular text file. It can generate any text-based format (HTML,
11
- XML, CSV, LaTeX, etc.). It doesn't have a specific extension, ``.html`` or
12
- ``.xml`` are just fine.
13
-
14
- A template contains **variables** or **expressions**, which get replaced with
15
- values when the template is evaluated, and **tags**, which control the
16
- template's logic.
17
-
18
- Below is a minimal template that illustrates a few basics. We will cover further
19
- details later on:
20
-
21
- .. code-block:: html+twig
22
-
23
- <!DOCTYPE html>
24
- <html>
25
- <head>
26
- <title>My Webpage</title>
27
- </head>
28
- <body>
29
- <ul id="navigation">
30
- {% for item in navigation %}
31
- <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
32
- {% endfor %}
33
- </ul>
34
-
35
- <h1>My Webpage</h1>
36
- {{ a_variable }}
37
- </body>
38
- </html>
39
-
40
- There are two kinds of delimiters: ``{% ... %}`` and ``{{ ... }}``. The first
41
- one is used to execute statements such as for-loops, the latter outputs the
42
- result of an expression.
43
-
44
- IDEs Integration
45
- ----------------
46
-
47
- Many IDEs support syntax highlighting and auto-completion for Twig:
48
-
49
- * *Textmate* via the `Twig bundle`_
50
- * *Vim* via the `Jinja syntax plugin`_ or the `vim-twig plugin`_
51
- * *Netbeans* via the `Twig syntax plugin`_ (until 7.1, native as of 7.2)
52
- * *PhpStorm* (native as of 2.1)
53
- * *Eclipse* via the `Twig plugin`_
54
- * *Sublime Text* via the `Twig bundle`_
55
- * *GtkSourceView* via the `Twig language definition`_ (used by gedit and other projects)
56
- * *Coda* and *SubEthaEdit* via the `Twig syntax mode`_
57
- * *Coda 2* via the `other Twig syntax mode`_
58
- * *Komodo* and *Komodo Edit* via the Twig highlight/syntax check mode
59
- * *Notepad++* via the `Notepad++ Twig Highlighter`_
60
- * *Emacs* via `web-mode.el`_
61
- * *Atom* via the `PHP-twig for atom`_
62
- * *Visual Studio Code* via the `Twig pack`_
63
-
64
- Also, `TwigFiddle`_ is an online service that allows you to execute Twig templates
65
- from a browser; it supports all versions of Twig.
66
-
67
- Variables
68
- ---------
69
-
70
- The application passes variables to the templates for manipulation in the
71
- template. Variables may have attributes or elements you can access, too. The
72
- visual representation of a variable depends heavily on the application providing
73
- it.
74
-
75
- Use a dot (``.``) to access attributes of a variable (methods or properties of a
76
- PHP object, or items of a PHP array):
77
-
78
- .. code-block:: twig
79
-
80
- {{ foo.bar }}
81
-
82
- .. note::
83
-
84
- It's important to know that the curly braces are *not* part of the
85
- variable but the print statement. When accessing variables inside tags,
86
- don't put the braces around them.
87
-
88
- .. sidebar:: Implementation
89
-
90
- For convenience's sake ``foo.bar`` does the following things on the PHP
91
- layer:
92
-
93
- * check if ``foo`` is an array and ``bar`` a valid element;
94
- * if not, and if ``foo`` is an object, check that ``bar`` is a valid property;
95
- * if not, and if ``foo`` is an object, check that ``bar`` is a valid method
96
- (even if ``bar`` is the constructor - use ``__construct()`` instead);
97
- * if not, and if ``foo`` is an object, check that ``getBar`` is a valid method;
98
- * if not, and if ``foo`` is an object, check that ``isBar`` is a valid method;
99
- * if not, return a ``null`` value.
100
-
101
- Twig also supports a specific syntax for accessing items on PHP arrays,
102
- ``foo['bar']``:
103
-
104
- * check if ``foo`` is an array and ``bar`` a valid element;
105
- * if not, return a ``null`` value.
106
-
107
- If a variable or attribute does not exist, you will receive a ``null`` value
108
- when the ``strict_variables`` option is set to ``false``; alternatively, if ``strict_variables``
109
- is set, Twig will throw an error (see :ref:`environment options<environment_options>`).
110
-
111
- .. note::
112
-
113
- If you want to access a dynamic attribute of a variable, use the
114
- :doc:`attribute<functions/attribute>` function instead.
115
-
116
- The ``attribute`` function is also useful when the attribute contains
117
- special characters (like ``-`` that would be interpreted as the minus
118
- operator):
119
-
120
- .. code-block:: twig
121
-
122
- {# equivalent to the non-working foo.data-foo #}
123
- {{ attribute(foo, 'data-foo') }}
124
-
125
- Global Variables
126
- ~~~~~~~~~~~~~~~~
127
-
128
- The following variables are always available in templates:
129
-
130
- * ``_self``: references the current template;
131
- * ``_context``: references the current context;
132
- * ``_charset``: references the current charset.
133
-
134
- Setting Variables
135
- ~~~~~~~~~~~~~~~~~
136
-
137
- You can assign values to variables inside code blocks. Assignments use the
138
- :doc:`set<tags/set>` tag:
139
-
140
- .. code-block:: twig
141
-
142
- {% set foo = 'foo' %}
143
- {% set foo = [1, 2] %}
144
- {% set foo = {'foo': 'bar'} %}
145
-
146
- Filters
147
- -------
148
-
149
- Variables can be modified by **filters**. Filters are separated from the
150
- variable by a pipe symbol (``|``). Multiple filters can be chained. The output
151
- of one filter is applied to the next.
152
-
153
- The following example removes all HTML tags from the ``name`` and title-cases
154
- it:
155
-
156
- .. code-block:: twig
157
-
158
- {{ name|striptags|title }}
159
-
160
- Filters that accept arguments have parentheses around the arguments. This
161
- example joins the elements of a list by commas:
162
-
163
- .. code-block:: twig
164
-
165
- {{ list|join(', ') }}
166
-
167
- To apply a filter on a section of code, wrap it with the
168
- :doc:`apply<tags/apply>` tag:
169
-
170
- .. code-block:: twig
171
-
172
- {% apply upper %}
173
- This text becomes uppercase
174
- {% endapply %}
175
-
176
- Go to the :doc:`filters<filters/index>` page to learn more about built-in
177
- filters.
178
-
179
- .. note::
180
-
181
- The ``apply`` tag was introduced in Twig 1.40; use the ``filter`` tag with
182
- previous versions.
183
-
184
- Functions
185
- ---------
186
-
187
- Functions can be called to generate content. Functions are called by their
188
- name followed by parentheses (``()``) and may have arguments.
189
-
190
- For instance, the ``range`` function returns a list containing an arithmetic
191
- progression of integers:
192
-
193
- .. code-block:: twig
194
-
195
- {% for i in range(0, 3) %}
196
- {{ i }},
197
- {% endfor %}
198
-
199
- Go to the :doc:`functions<functions/index>` page to learn more about the
200
- built-in functions.
201
-
202
- .. _named-arguments:
203
-
204
- Named Arguments
205
- ---------------
206
-
207
- .. versionadded:: 1.12
208
- Support for named arguments was added in Twig 1.12.
209
-
210
- .. code-block:: twig
211
-
212
- {% for i in range(low=1, high=10, step=2) %}
213
- {{ i }},
214
- {% endfor %}
215
-
216
- Using named arguments makes your templates more explicit about the meaning of
217
- the values you pass as arguments:
218
-
219
- .. code-block:: twig
220
-
221
- {{ data|convert_encoding('UTF-8', 'iso-2022-jp') }}
222
-
223
- {# versus #}
224
-
225
- {{ data|convert_encoding(from='iso-2022-jp', to='UTF-8') }}
226
-
227
- Named arguments also allow you to skip some arguments for which you don't want
228
- to change the default value:
229
-
230
- .. code-block:: twig
231
-
232
- {# the first argument is the date format, which defaults to the global date format if null is passed #}
233
- {{ "now"|date(null, "Europe/Paris") }}
234
-
235
- {# or skip the format value by using a named argument for the time zone #}
236
- {{ "now"|date(timezone="Europe/Paris") }}
237
-
238
- You can also use both positional and named arguments in one call, in which
239
- case positional arguments must always come before named arguments:
240
-
241
- .. code-block:: twig
242
-
243
- {{ "now"|date('d/m/Y H:i', timezone="Europe/Paris") }}
244
-
245
- .. tip::
246
-
247
- Each function and filter documentation page has a section where the names
248
- of all arguments are listed when supported.
249
-
250
- Control Structure
251
- -----------------
252
-
253
- A control structure refers to all those things that control the flow of a
254
- program - conditionals (i.e. ``if``/``elseif``/``else``), ``for``-loops, as
255
- well as things like blocks. Control structures appear inside ``{% ... %}``
256
- blocks.
257
-
258
- For example, to display a list of users provided in a variable called
259
- ``users``, use the :doc:`for<tags/for>` tag:
260
-
261
- .. code-block:: twig
262
-
263
- <h1>Members</h1>
264
- <ul>
265
- {% for user in users %}
266
- <li>{{ user.username|e }}</li>
267
- {% endfor %}
268
- </ul>
269
-
270
- The :doc:`if<tags/if>` tag can be used to test an expression:
271
-
272
- .. code-block:: twig
273
-
274
- {% if users|length > 0 %}
275
- <ul>
276
- {% for user in users %}
277
- <li>{{ user.username|e }}</li>
278
- {% endfor %}
279
- </ul>
280
- {% endif %}
281
-
282
- Go to the :doc:`tags<tags/index>` page to learn more about the built-in tags.
283
-
284
- Comments
285
- --------
286
-
287
- To comment-out part of a line in a template, use the comment syntax ``{# ...
288
- #}``. This is useful for debugging or to add information for other template
289
- designers or yourself:
290
-
291
- .. code-block:: twig
292
-
293
- {# note: disabled template because we no longer use this
294
- {% for user in users %}
295
- ...
296
- {% endfor %}
297
- #}
298
-
299
- Including other Templates
300
- -------------------------
301
-
302
- The :doc:`include<functions/include>` function is useful to include a template
303
- and return the rendered content of that template into the current one:
304
-
305
- .. code-block:: twig
306
-
307
- {{ include('sidebar.html') }}
308
-
309
- By default, included templates have access to the same context as the template
310
- which includes them. This means that any variable defined in the main template
311
- will be available in the included template too:
312
-
313
- .. code-block:: twig
314
-
315
- {% for box in boxes %}
316
- {{ include('render_box.html') }}
317
- {% endfor %}
318
-
319
- The included template ``render_box.html`` is able to access the ``box`` variable.
320
-
321
- The name of the template depends on the template loader. For instance, the
322
- ``\Twig\Loader\FilesystemLoader`` allows you to access other templates by giving the
323
- filename. You can access templates in subdirectories with a slash:
324
-
325
- .. code-block:: twig
326
-
327
- {{ include('sections/articles/sidebar.html') }}
328
-
329
- This behavior depends on the application embedding Twig.
330
-
331
- Template Inheritance
332
- --------------------
333
-
334
- The most powerful part of Twig is template inheritance. Template inheritance
335
- allows you to build a base "skeleton" template that contains all the common
336
- elements of your site and defines **blocks** that child templates can
337
- override.
338
-
339
- It's easier to understand the concept by starting with an example.
340
-
341
- Let's define a base template, ``base.html``, which defines an HTML skeleton
342
- document that might be used for a two-column page:
343
-
344
- .. code-block:: html+twig
345
-
346
- <!DOCTYPE html>
347
- <html>
348
- <head>
349
- {% block head %}
350
- <link rel="stylesheet" href="style.css" />
351
- <title>{% block title %}{% endblock %} - My Webpage</title>
352
- {% endblock %}
353
- </head>
354
- <body>
355
- <div id="content">{% block content %}{% endblock %}</div>
356
- <div id="footer">
357
- {% block footer %}
358
- &copy; Copyright 2011 by <a href="http://domain.invalid/">you</a>.
359
- {% endblock %}
360
- </div>
361
- </body>
362
- </html>
363
-
364
- In this example, the :doc:`block<tags/block>` tags define four blocks that
365
- child templates can fill in. All the ``block`` tag does is to tell the
366
- template engine that a child template may override those portions of the
367
- template.
368
-
369
- A child template might look like this:
370
-
371
- .. code-block:: twig
372
-
373
- {% extends "base.html" %}
374
-
375
- {% block title %}Index{% endblock %}
376
- {% block head %}
377
- {{ parent() }}
378
- <style type="text/css">
379
- .important { color: #336699; }
380
- </style>
381
- {% endblock %}
382
- {% block content %}
383
- <h1>Index</h1>
384
- <p class="important">
385
- Welcome to my awesome homepage.
386
- </p>
387
- {% endblock %}
388
-
389
- The :doc:`extends<tags/extends>` tag is the key here. It tells the template
390
- engine that this template "extends" another template. When the template system
391
- evaluates this template, first it locates the parent. The extends tag should
392
- be the first tag in the template.
393
-
394
- Note that since the child template doesn't define the ``footer`` block, the
395
- value from the parent template is used instead.
396
-
397
- It's possible to render the contents of the parent block by using the
398
- :doc:`parent<functions/parent>` function. This gives back the results of the
399
- parent block:
400
-
401
- .. code-block:: twig
402
-
403
- {% block sidebar %}
404
- <h3>Table Of Contents</h3>
405
- ...
406
- {{ parent() }}
407
- {% endblock %}
408
-
409
- .. tip::
410
-
411
- The documentation page for the :doc:`extends<tags/extends>` tag describes
412
- more advanced features like block nesting, scope, dynamic inheritance, and
413
- conditional inheritance.
414
-
415
- .. note::
416
-
417
- Twig also supports multiple inheritance via "horizontal reuse" with the help
418
- of the :doc:`use<tags/use>` tag.
419
-
420
- HTML Escaping
421
- -------------
422
-
423
- When generating HTML from templates, there's always a risk that a variable
424
- will include characters that affect the resulting HTML. There are two
425
- approaches: manually escaping each variable or automatically escaping
426
- everything by default.
427
-
428
- Twig supports both, automatic escaping is enabled by default.
429
-
430
- The automatic escaping strategy can be configured via the
431
- :ref:`autoescape<environment_options>` option and defaults to ``html``.
432
-
433
- Working with Manual Escaping
434
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
435
-
436
- If manual escaping is enabled, it is **your** responsibility to escape variables
437
- if needed. What to escape? Any variable that comes from an untrusted source.
438
-
439
- Escaping works by using the :doc:`escape<filters/escape>` or ``e`` filter:
440
-
441
- .. code-block:: twig
442
-
443
- {{ user.username|e }}
444
-
445
- By default, the ``escape`` filter uses the ``html`` strategy, but depending on
446
- the escaping context, you might want to explicitly use an other strategy:
447
-
448
- .. code-block:: twig
449
-
450
- {{ user.username|e('js') }}
451
- {{ user.username|e('css') }}
452
- {{ user.username|e('url') }}
453
- {{ user.username|e('html_attr') }}
454
-
455
- Working with Automatic Escaping
456
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
457
-
458
- Whether automatic escaping is enabled or not, you can mark a section of a
459
- template to be escaped or not by using the :doc:`autoescape<tags/autoescape>`
460
- tag:
461
-
462
- .. code-block:: twig
463
-
464
- {% autoescape %}
465
- Everything will be automatically escaped in this block (using the HTML strategy)
466
- {% endautoescape %}
467
-
468
- By default, auto-escaping uses the ``html`` escaping strategy. If you output
469
- variables in other contexts, you need to explicitly escape them with the
470
- appropriate escaping strategy:
471
-
472
- .. code-block:: twig
473
-
474
- {% autoescape 'js' %}
475
- Everything will be automatically escaped in this block (using the JS strategy)
476
- {% endautoescape %}
477
-
478
- Escaping
479
- --------
480
-
481
- It is sometimes desirable or even necessary to have Twig ignore parts it would
482
- otherwise handle as variables or blocks. For example if the default syntax is
483
- used and you want to use ``{{`` as raw string in the template and not start a
484
- variable you have to use a trick.
485
-
486
- The easiest way is to output the variable delimiter (``{{``) by using a variable
487
- expression:
488
-
489
- .. code-block:: twig
490
-
491
- {{ '{{' }}
492
-
493
- For bigger sections it makes sense to mark a block
494
- :doc:`verbatim<tags/verbatim>`.
495
-
496
- Macros
497
- ------
498
-
499
- .. versionadded:: 1.12
500
- Support for default argument values was added in Twig 1.12.
501
-
502
- Macros are comparable with functions in regular programming languages. They are
503
- useful to reuse HTML fragments to not repeat yourself. They are described in the
504
- :doc:`macro<tags/macro>` tag documentation.
505
-
506
- .. _twig-expressions:
507
-
508
- Expressions
509
- -----------
510
-
511
- Twig allows expressions everywhere.
512
-
513
- .. note::
514
-
515
- The operator precedence is as follows, with the lowest-precedence operators
516
- listed first: ``?:`` (ternary operator), ``b-and``, ``b-xor``, ``b-or``,
517
- ``or``, ``and``, ``==``, ``!=``, ``<``, ``>``, ``>=``, ``<=``, ``in``,
518
- ``matches``, ``starts with``, ``ends with``, ``..``, ``+``, ``-``, ``~``,
519
- ``*``, ``/``, ``//``, ``%``, ``is`` (tests), ``**``, ``??``, ``|``
520
- (filters), ``[]``, and ``.``:
521
-
522
- .. code-block:: twig
523
-
524
- {% set greeting = 'Hello ' %}
525
- {% set name = 'Fabien' %}
526
-
527
- {{ greeting ~ name|lower }} {# Hello fabien #}
528
-
529
- {# use parenthesis to change precedence #}
530
- {{ (greeting ~ name)|lower }} {# hello fabien #}
531
-
532
- Literals
533
- ~~~~~~~~
534
-
535
- .. versionadded:: 1.5
536
- Support for hash keys as names and expressions was added in Twig 1.5.
537
-
538
- The simplest form of expressions are literals. Literals are representations
539
- for PHP types such as strings, numbers, and arrays. The following literals
540
- exist:
541
-
542
- * ``"Hello World"``: Everything between two double or single quotes is a
543
- string. They are useful whenever you need a string in the template (for
544
- example as arguments to function calls, filters or just to extend or include
545
- a template). A string can contain a delimiter if it is preceded by a
546
- backslash (``\``) -- like in ``'It\'s good'``. If the string contains a
547
- backslash (e.g. ``'c:\Program Files'``) escape it by doubling it
548
- (e.g. ``'c:\\Program Files'``).
549
-
550
- * ``42`` / ``42.23``: Integers and floating point numbers are created by
551
- writing the number down. If a dot is present the number is a float,
552
- otherwise an integer.
553
-
554
- * ``["foo", "bar"]``: Arrays are defined by a sequence of expressions
555
- separated by a comma (``,``) and wrapped with squared brackets (``[]``).
556
-
557
- * ``{"foo": "bar"}``: Hashes are defined by a list of keys and values
558
- separated by a comma (``,``) and wrapped with curly braces (``{}``):
559
-
560
- .. code-block:: twig
561
-
562
- {# keys as string #}
563
- { 'foo': 'foo', 'bar': 'bar' }
564
-
565
- {# keys as names (equivalent to the previous hash) -- as of Twig 1.5 #}
566
- { foo: 'foo', bar: 'bar' }
567
-
568
- {# keys as integer #}
569
- { 2: 'foo', 4: 'bar' }
570
-
571
- {# keys as expressions (the expression must be enclosed into parentheses) -- as of Twig 1.5 #}
572
- {% set foo = 'foo' %}
573
- { (foo): 'foo', (1 + 1): 'bar', (foo ~ 'b'): 'baz' }
574
-
575
- * ``true`` / ``false``: ``true`` represents the true value, ``false``
576
- represents the false value.
577
-
578
- * ``null``: ``null`` represents no specific value. This is the value returned
579
- when a variable does not exist. ``none`` is an alias for ``null``.
580
-
581
- Arrays and hashes can be nested:
582
-
583
- .. code-block:: twig
584
-
585
- {% set foo = [1, {"foo": "bar"}] %}
586
-
587
- .. tip::
588
-
589
- Using double-quoted or single-quoted strings has no impact on performance
590
- but :ref:`string interpolation <templates-string-interpolation>` is only
591
- supported in double-quoted strings.
592
-
593
- Math
594
- ~~~~
595
-
596
- Twig allows you to do math in templates; the following operators are supported:
597
-
598
- * ``+``: Adds two numbers together (the operands are casted to numbers). ``{{
599
- 1 + 1 }}`` is ``2``.
600
-
601
- * ``-``: Subtracts the second number from the first one. ``{{ 3 - 2 }}`` is
602
- ``1``.
603
-
604
- * ``/``: Divides two numbers. The returned value will be a floating point
605
- number. ``{{ 1 / 2 }}`` is ``{{ 0.5 }}``.
606
-
607
- * ``%``: Calculates the remainder of an integer division. ``{{ 11 % 7 }}`` is
608
- ``4``.
609
-
610
- * ``//``: Divides two numbers and returns the floored integer result. ``{{ 20
611
- // 7 }}`` is ``2``, ``{{ -20 // 7 }}`` is ``-3`` (this is just syntactic
612
- sugar for the :doc:`round<filters/round>` filter).
613
-
614
- * ``*``: Multiplies the left operand with the right one. ``{{ 2 * 2 }}`` would
615
- return ``4``.
616
-
617
- * ``**``: Raises the left operand to the power of the right operand. ``{{ 2 **
618
- 3 }}`` would return ``8``.
619
-
620
- .. _template_logic:
621
-
622
- Logic
623
- ~~~~~
624
-
625
- You can combine multiple expressions with the following operators:
626
-
627
- * ``and``: Returns true if the left and the right operands are both true.
628
-
629
- * ``or``: Returns true if the left or the right operand is true.
630
-
631
- * ``not``: Negates a statement.
632
-
633
- * ``(expr)``: Groups an expression.
634
-
635
- .. note::
636
-
637
- Twig also supports bitwise operators (``b-and``, ``b-xor``, and ``b-or``).
638
-
639
- .. note::
640
-
641
- Operators are case sensitive.
642
-
643
- Comparisons
644
- ~~~~~~~~~~~
645
-
646
- The following comparison operators are supported in any expression: ``==``,
647
- ``!=``, ``<``, ``>``, ``>=``, and ``<=``.
648
-
649
- You can also check if a string ``starts with`` or ``ends with`` another
650
- string:
651
-
652
- .. code-block:: twig
653
-
654
- {% if 'Fabien' starts with 'F' %}
655
- {% endif %}
656
-
657
- {% if 'Fabien' ends with 'n' %}
658
- {% endif %}
659
-
660
- .. note::
661
-
662
- For complex string comparisons, the ``matches`` operator allows you to use
663
- `regular expressions`_:
664
-
665
- .. code-block:: twig
666
-
667
- {% if phone matches '/^[\\d\\.]+$/' %}
668
- {% endif %}
669
-
670
- Containment Operator
671
- ~~~~~~~~~~~~~~~~~~~~
672
-
673
- The ``in`` operator performs containment test. It returns ``true`` if the left
674
- operand is contained in the right:
675
-
676
- .. code-block:: twig
677
-
678
- {# returns true #}
679
-
680
- {{ 1 in [1, 2, 3] }}
681
-
682
- {{ 'cd' in 'abcde' }}
683
-
684
- .. tip::
685
-
686
- You can use this filter to perform a containment test on strings, arrays,
687
- or objects implementing the ``Traversable`` interface.
688
-
689
- To perform a negative test, use the ``not in`` operator:
690
-
691
- .. code-block:: twig
692
-
693
- {% if 1 not in [1, 2, 3] %}
694
-
695
- {# is equivalent to #}
696
- {% if not (1 in [1, 2, 3]) %}
697
-
698
- Test Operator
699
- ~~~~~~~~~~~~~
700
-
701
- The ``is`` operator performs tests. Tests can be used to test a variable against
702
- a common expression. The right operand is name of the test:
703
-
704
- .. code-block:: twig
705
-
706
- {# find out if a variable is odd #}
707
-
708
- {{ name is odd }}
709
-
710
- Tests can accept arguments too:
711
-
712
- .. code-block:: twig
713
-
714
- {% if post.status is constant('Post::PUBLISHED') %}
715
-
716
- Tests can be negated by using the ``is not`` operator:
717
-
718
- .. code-block:: twig
719
-
720
- {% if post.status is not constant('Post::PUBLISHED') %}
721
-
722
- {# is equivalent to #}
723
- {% if not (post.status is constant('Post::PUBLISHED')) %}
724
-
725
- Go to the :doc:`tests<tests/index>` page to learn more about the built-in
726
- tests.
727
-
728
- Other Operators
729
- ~~~~~~~~~~~~~~~
730
-
731
- .. versionadded:: 1.12.0
732
- Support for the extended ternary operator was added in Twig 1.12.0.
733
-
734
- The following operators don't fit into any of the other categories:
735
-
736
- * ``|``: Applies a filter.
737
-
738
- * ``..``: Creates a sequence based on the operand before and after the operator
739
- (this is syntactic sugar for the :doc:`range<functions/range>` function):
740
-
741
- .. code-block:: twig
742
-
743
- {{ 1..5 }}
744
-
745
- {# equivalent to #}
746
- {{ range(1, 5) }}
747
-
748
- Note that you must use parentheses when combining it with the filter operator
749
- due to the :ref:`operator precedence rules <twig-expressions>`:
750
-
751
- .. code-block:: twig
752
-
753
- (1..5)|join(', ')
754
-
755
- * ``~``: Converts all operands into strings and concatenates them. ``{{ "Hello
756
- " ~ name ~ "!" }}`` would return (assuming ``name`` is ``'John'``) ``Hello
757
- John!``.
758
-
759
- * ``.``, ``[]``: Gets an attribute of a variable.
760
-
761
- * ``?:``: The ternary operator:
762
-
763
- .. code-block:: twig
764
-
765
- {{ foo ? 'yes' : 'no' }}
766
-
767
- {# as of Twig 1.12.0 #}
768
- {{ foo ?: 'no' }} is the same as {{ foo ? foo : 'no' }}
769
- {{ foo ? 'yes' }} is the same as {{ foo ? 'yes' : '' }}
770
-
771
- * ``??``: The null-coalescing operator:
772
-
773
- .. code-block:: twig
774
-
775
- {# returns the value of foo if it is defined and not null, 'no' otherwise #}
776
- {{ foo ?? 'no' }}
777
-
778
- .. _templates-string-interpolation:
779
-
780
- String Interpolation
781
- ~~~~~~~~~~~~~~~~~~~~
782
-
783
- .. versionadded:: 1.5
784
- String interpolation was added in Twig 1.5.
785
-
786
- String interpolation (``#{expression}``) allows any valid expression to appear
787
- within a *double-quoted string*. The result of evaluating that expression is
788
- inserted into the string:
789
-
790
- .. code-block:: twig
791
-
792
- {{ "foo #{bar} baz" }}
793
- {{ "foo #{1 + 2} baz" }}
794
-
795
- .. _templates-whitespace-control:
796
-
797
- Whitespace Control
798
- ------------------
799
-
800
- .. versionadded:: 1.1
801
- Tag level whitespace control was added in Twig 1.1.
802
-
803
- .. versionadded:: 1.39
804
- Tag level Line whitespace control was added in Twig 1.39.
805
-
806
- The first newline after a template tag is removed automatically (like in PHP).
807
- Whitespace is not further modified by the template engine, so each whitespace
808
- (spaces, tabs, newlines etc.) is returned unchanged.
809
-
810
- You can also control whitespace on a per tag level. By using the whitespace
811
- control modifiers on your tags, you can trim leading and or trailing whitespace.
812
-
813
- Twig supports two modifiers:
814
-
815
- * *Whitespace trimming* via the ``-`` modifier: Removes all whitespace
816
- (including newlines);
817
-
818
- * *Line whitespace trimming* via the ``~`` modifier: Removes all whitespace
819
- (excluding newlines). Using this modifier on the right disables the default
820
- removal of the first newline inherited from PHP.
821
-
822
- The modifiers can be used on either side of the tags like in ``{%-`` or ``-%}``
823
- and they consume all whitespace for that side of the tag. It is possible to use
824
- the modifiers on one side of a tag or on both sides:
825
-
826
- .. code-block:: twig
827
-
828
- {% set value = 'no spaces' %}
829
- {#- No leading/trailing whitespace -#}
830
- {%- if true -%}
831
- {{- value -}}
832
- {%- endif -%}
833
- {# output 'no spaces' #}
834
-
835
- <li>
836
- {{ value }} </li>
837
- {# outputs '<li>\n no spaces </li>' #}
838
-
839
- <li>
840
- {{- value }} </li>
841
- {# outputs '<li>no spaces </li>' #}
842
-
843
- <li>
844
- {{~ value }} </li>
845
- {# outputs '<li>\nno spaces </li>' #}
846
-
847
- .. tip::
848
-
849
- In addition to the whitespace modifiers, Twig also has a ``spaceless`` filter
850
- that removes whitespace **between HTML tags**:
851
-
852
- .. code-block:: twig
853
-
854
- {% apply spaceless %}
855
- <div>
856
- <strong>foo bar</strong>
857
- </div>
858
- {% endapply %}
859
-
860
- {# output will be <div><strong>foo bar</strong></div> #}
861
-
862
- Note that the ``apply`` tag was introduced in Twig 1.40; use the ``filter``
863
- tag with previous versions.
864
-
865
- Extensions
866
- ----------
867
-
868
- Twig can be extended. If you want to create your own extensions, read the
869
- :ref:`Creating an Extension <creating_extensions>` chapter.
870
-
871
- .. _`Twig bundle`: https://github.com/Anomareh/PHP-Twig.tmbundle
872
- .. _`Jinja syntax plugin`: http://jinja.pocoo.org/docs/integration/#vim
873
- .. _`vim-twig plugin`: https://github.com/lumiliet/vim-twig
874
- .. _`Twig syntax plugin`: http://plugins.netbeans.org/plugin/37069/php-twig
875
- .. _`Twig plugin`: https://github.com/pulse00/Twig-Eclipse-Plugin
876
- .. _`Twig language definition`: https://github.com/gabrielcorpse/gedit-twig-template-language
877
- .. _`Twig syntax mode`: https://github.com/bobthecow/Twig-HTML.mode
878
- .. _`other Twig syntax mode`: https://github.com/muxx/Twig-HTML.mode
879
- .. _`Notepad++ Twig Highlighter`: https://github.com/Banane9/notepadplusplus-twig
880
- .. _`web-mode.el`: http://web-mode.org/
881
- .. _`regular expressions`: https://secure.php.net/manual/en/pcre.pattern.php
882
- .. _`PHP-twig for atom`: https://github.com/reesef/php-twig
883
- .. _`TwigFiddle`: https://twigfiddle.com/
884
- .. _`Twig pack`: https://marketplace.visualstudio.com/items?itemName=bajdzis.vscode-twig-pack
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tests/constant.rst DELETED
@@ -1,22 +0,0 @@
1
- ``constant``
2
- ============
3
-
4
- .. versionadded:: 1.13.1
5
- constant now accepts object instances as the second argument.
6
-
7
- ``constant`` checks if a variable has the exact same value as a constant. You
8
- can use either global constants or class constants:
9
-
10
- .. code-block:: twig
11
-
12
- {% if post.status is constant('Post::PUBLISHED') %}
13
- the status attribute is exactly the same as Post::PUBLISHED
14
- {% endif %}
15
-
16
- You can test constants from object instances as well:
17
-
18
- .. code-block:: twig
19
-
20
- {% if post.status is constant('PUBLISHED', post) %}
21
- the status attribute is exactly the same as Post::PUBLISHED
22
- {% endif %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tests/defined.rst DELETED
@@ -1,30 +0,0 @@
1
- ``defined``
2
- ===========
3
-
4
- ``defined`` checks if a variable is defined in the current context. This is very
5
- useful if you use the ``strict_variables`` option:
6
-
7
- .. code-block:: twig
8
-
9
- {# defined works with variable names #}
10
- {% if foo is defined %}
11
- ...
12
- {% endif %}
13
-
14
- {# and attributes on variables names #}
15
- {% if foo.bar is defined %}
16
- ...
17
- {% endif %}
18
-
19
- {% if foo['bar'] is defined %}
20
- ...
21
- {% endif %}
22
-
23
- When using the ``defined`` test on an expression that uses variables in some
24
- method calls, be sure that they are all defined first:
25
-
26
- .. code-block:: twig
27
-
28
- {% if var is defined and foo.method(var) is defined %}
29
- ...
30
- {% endif %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tests/divisibleby.rst DELETED
@@ -1,14 +0,0 @@
1
- ``divisible by``
2
- ================
3
-
4
- .. versionadded:: 1.14.2
5
- The ``divisible by`` test was added in Twig 1.14.2 as an alias for
6
- ``divisibleby``.
7
-
8
- ``divisible by`` checks if a variable is divisible by a number:
9
-
10
- .. code-block:: twig
11
-
12
- {% if loop.index is divisible by(3) %}
13
- ...
14
- {% endif %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tests/empty.rst DELETED
@@ -1,22 +0,0 @@
1
- ``empty``
2
- =========
3
-
4
- .. versionadded:: 1.33
5
-
6
- Support for the ``__toString()`` magic method has been added in Twig 1.33.
7
-
8
- ``empty`` checks if a variable is an empty string, an empty array, an empty
9
- hash, exactly ``false``, or exactly ``null``.
10
-
11
- For objects that implement the ``Countable`` interface, ``empty`` will check the
12
- return value of the ``count()`` method.
13
-
14
- For objects that implement the ``__toString()`` magic method (and not ``Countable``),
15
- it will check if an empty string is returned.
16
-
17
- .. code-block:: twig
18
-
19
- {% if foo is empty %}
20
- ...
21
- {% endif %}
22
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tests/even.rst DELETED
@@ -1,10 +0,0 @@
1
- ``even``
2
- ========
3
-
4
- ``even`` returns ``true`` if the given number is even:
5
-
6
- .. code-block:: twig
7
-
8
- {{ var is even }}
9
-
10
- .. seealso:: :doc:`odd<../tests/odd>`
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tests/index.rst DELETED
@@ -1,15 +0,0 @@
1
- Tests
2
- =====
3
-
4
- .. toctree::
5
- :maxdepth: 1
6
-
7
- constant
8
- defined
9
- divisibleby
10
- empty
11
- even
12
- iterable
13
- null
14
- odd
15
- sameas
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tests/iterable.rst DELETED
@@ -1,19 +0,0 @@
1
- ``iterable``
2
- ============
3
-
4
- .. versionadded:: 1.7
5
- The iterable test was added in Twig 1.7.
6
-
7
- ``iterable`` checks if a variable is an array or a traversable object:
8
-
9
- .. code-block:: twig
10
-
11
- {# evaluates to true if the foo variable is iterable #}
12
- {% if users is iterable %}
13
- {% for user in users %}
14
- Hello {{ user }}!
15
- {% endfor %}
16
- {% else %}
17
- {# users is probably a string #}
18
- Hello {{ users }}!
19
- {% endif %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tests/null.rst DELETED
@@ -1,12 +0,0 @@
1
- ``null``
2
- ========
3
-
4
- ``null`` returns ``true`` if the variable is ``null``:
5
-
6
- .. code-block:: twig
7
-
8
- {{ var is null }}
9
-
10
- .. note::
11
-
12
- ``none`` is an alias for ``null``.
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tests/odd.rst DELETED
@@ -1,10 +0,0 @@
1
- ``odd``
2
- =======
3
-
4
- ``odd`` returns ``true`` if the given number is odd:
5
-
6
- .. code-block:: twig
7
-
8
- {{ var is odd }}
9
-
10
- .. seealso:: :doc:`even<../tests/even>`
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/doc/tests/sameas.rst DELETED
@@ -1,14 +0,0 @@
1
- ``same as``
2
- ===========
3
-
4
- .. versionadded:: 1.14.2
5
- The ``same as`` test was added in Twig 1.14.2 as an alias for ``sameas``.
6
-
7
- ``same as`` checks if a variable is the same as another variable.
8
- This is equivalent to ``===`` in PHP:
9
-
10
- .. code-block:: twig
11
-
12
- {% if foo.attribute is same as(false) %}
13
- the foo attribute really is the 'false' PHP value
14
- {% endif %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/drupal_test.sh DELETED
@@ -1,50 +0,0 @@
1
- #!/bin/bash
2
-
3
- set -x
4
- set -e
5
-
6
- REPO=`pwd`
7
- cd /tmp
8
- rm -rf drupal-twig-test
9
- composer create-project --no-interaction drupal-composer/drupal-project:8.x-dev drupal-twig-test
10
- cd drupal-twig-test
11
- (cd vendor/twig && rm -rf twig && ln -sf $REPO twig)
12
- echo '$config["system.logging"]["error_level"] = "verbose";' >> web/sites/default/settings.php
13
- php ./web/core/scripts/drupal install --no-interaction demo_umami > output
14
- perl -p -i -e 's/^([A-Za-z]+)\: (.+)$/export DRUPAL_\1=\2/' output
15
- source output
16
-
17
- wget https://get.symfony.com/cli/installer -O - | bash
18
- export PATH="$HOME/.symfony/bin:$PATH"
19
- symfony server:start -d --no-tls
20
-
21
- curl -OLsS https://get.blackfire.io/blackfire-player.phar
22
- chmod +x blackfire-player.phar
23
- cat > drupal-tests.bkf <<EOF
24
- name "Drupal tests"
25
-
26
- scenario
27
- name "homepage"
28
- set name "admin"
29
- set pass "pass"
30
-
31
- visit url('/')
32
- expect status_code() == 200
33
- click link('Articles')
34
- expect status_code() == 200
35
- click link('Dairy-free and delicious milk chocolate')
36
- expect body() matches "/Dairy\-free milk chocolate is made in largely the same way as regular chocolate/"
37
- expect status_code() == 200
38
- click link('Log in')
39
- expect status_code() == 200
40
- submit button("Log in")
41
- param name name
42
- param pass pass
43
- expect status_code() == 303
44
- follow
45
- expect status_code() == 200
46
- click link('Structure')
47
- expect status_code() == 200
48
- EOF
49
- ./blackfire-player.phar run drupal-tests.bkf --endpoint=`symfony var:export SYMFONY_DEFAULT_ROUTE_URL` --variable name=$DRUPAL_Username --variable pass=$DRUPAL_Password
50
- symfony server:stop
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/ext/twig/.gitignore DELETED
@@ -1,30 +0,0 @@
1
- *.sw*
2
- .deps
3
- Makefile
4
- Makefile.fragments
5
- Makefile.global
6
- Makefile.objects
7
- acinclude.m4
8
- aclocal.m4
9
- build/
10
- config.cache
11
- config.guess
12
- config.h
13
- config.h.in
14
- config.log
15
- config.nice
16
- config.status
17
- config.sub
18
- configure
19
- configure.in
20
- install-sh
21
- libtool
22
- ltmain.sh
23
- missing
24
- mkinstalldirs
25
- run-tests.php
26
- twig.loT
27
- .libs/
28
- modules/
29
- twig.la
30
- twig.lo
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/ext/twig/config.m4 DELETED
@@ -1,8 +0,0 @@
1
- dnl config.m4 for extension twig
2
-
3
- PHP_ARG_ENABLE(twig, whether to enable twig support,
4
- [ --enable-twig Enable twig support])
5
-
6
- if test "$PHP_TWIG" != "no"; then
7
- PHP_NEW_EXTENSION(twig, twig.c, $ext_shared)
8
- fi
 
 
 
 
 
 
 
 
vendor/twig/twig/ext/twig/config.w32 DELETED
@@ -1,8 +0,0 @@
1
- // vim:ft=javascript
2
-
3
- ARG_ENABLE("twig", "Twig support", "no");
4
-
5
- if (PHP_TWIG != "no") {
6
- AC_DEFINE('HAVE_TWIG', 1);
7
- EXTENSION('twig', 'twig.c');
8
- }
 
 
 
 
 
 
 
 
vendor/twig/twig/ext/twig/php_twig.h DELETED
@@ -1,35 +0,0 @@
1
- /*
2
- +----------------------------------------------------------------------+
3
- | Twig Extension |
4
- +----------------------------------------------------------------------+
5
- | Copyright (c) 2011 Derick Rethans |
6
- +----------------------------------------------------------------------+
7
- | Redistribution and use in source and binary forms, with or without |
8
- | modification, are permitted provided that the conditions mentioned |
9
- | in the accompanying LICENSE file are met (BSD-3-Clause). |
10
- +----------------------------------------------------------------------+
11
- | Author: Derick Rethans <derick@derickrethans.nl> |
12
- +----------------------------------------------------------------------+
13
- */
14
-
15
- #ifndef PHP_TWIG_H
16
- #define PHP_TWIG_H
17
-
18
- #define PHP_TWIG_VERSION "1.42.5-DEV"
19
-
20
- #include "php.h"
21
-
22
- extern zend_module_entry twig_module_entry;
23
- #define phpext_twig_ptr &twig_module_entry
24
- #ifndef PHP_WIN32
25
- zend_module_entry *get_module(void);
26
- #endif
27
-
28
- #ifdef ZTS
29
- #include "TSRM.h"
30
- #endif
31
-
32
- PHP_FUNCTION(twig_template_get_attributes);
33
- PHP_RSHUTDOWN_FUNCTION(twig);
34
-
35
- #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/ext/twig/twig.c DELETED
@@ -1,1217 +0,0 @@
1
- /*
2
- +----------------------------------------------------------------------+
3
- | Twig Extension |
4
- +----------------------------------------------------------------------+
5
- | Copyright (c) 2011 Derick Rethans |
6
- +----------------------------------------------------------------------+
7
- | Redistribution and use in source and binary forms, with or without |
8
- | modification, are permitted provided that the conditions mentioned |
9
- | in the accompanying LICENSE file are met (BSD-3-Clause). |
10
- +----------------------------------------------------------------------+
11
- | Author: Derick Rethans <derick@derickrethans.nl> |
12
- +----------------------------------------------------------------------+
13
- */
14
-
15
- #ifdef HAVE_CONFIG_H
16
- #include "config.h"
17
- #endif
18
-
19
- #include "php.h"
20
- #include "php_twig.h"
21
- #include "ext/standard/php_var.h"
22
- #include "ext/standard/php_string.h"
23
- #include "ext/standard/php_smart_str.h"
24
- #include "ext/spl/spl_exceptions.h"
25
-
26
- #include "Zend/zend_object_handlers.h"
27
- #include "Zend/zend_interfaces.h"
28
- #include "Zend/zend_exceptions.h"
29
-
30
- #ifndef Z_ADDREF_P
31
- #define Z_ADDREF_P(pz) (pz)->refcount++
32
- #endif
33
-
34
- #ifndef E_USER_DEPRECATED
35
- #define E_USER_DEPRECATED (1<<14L)
36
- #endif
37
-
38
- #define FREE_DTOR(z) \
39
- zval_dtor(z); \
40
- efree(z);
41
-
42
- #if PHP_VERSION_ID >= 50300
43
- #define APPLY_TSRMLS_DC TSRMLS_DC
44
- #define APPLY_TSRMLS_CC TSRMLS_CC
45
- #define APPLY_TSRMLS_FETCH()
46
- #else
47
- #define APPLY_TSRMLS_DC
48
- #define APPLY_TSRMLS_CC
49
- #define APPLY_TSRMLS_FETCH() TSRMLS_FETCH()
50
- #endif
51
-
52
- ZEND_BEGIN_ARG_INFO_EX(twig_template_get_attribute_args, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 6)
53
- ZEND_ARG_INFO(0, template)
54
- ZEND_ARG_INFO(0, object)
55
- ZEND_ARG_INFO(0, item)
56
- ZEND_ARG_INFO(0, arguments)
57
- ZEND_ARG_INFO(0, type)
58
- ZEND_ARG_INFO(0, isDefinedTest)
59
- ZEND_END_ARG_INFO()
60
-
61
- #ifndef PHP_FE_END
62
- #define PHP_FE_END { NULL, NULL, NULL}
63
- #endif
64
-
65
- static const zend_function_entry twig_functions[] = {
66
- PHP_FE(twig_template_get_attributes, twig_template_get_attribute_args)
67
- PHP_FE_END
68
- };
69
-
70
- PHP_RSHUTDOWN_FUNCTION(twig)
71
- {
72
- #if ZEND_DEBUG
73
- CG(unclean_shutdown) = 0; /* get rid of PHPUnit's exit() and report memleaks */
74
- #endif
75
- return SUCCESS;
76
- }
77
-
78
- zend_module_entry twig_module_entry = {
79
- STANDARD_MODULE_HEADER,
80
- "twig",
81
- twig_functions,
82
- NULL,
83
- NULL,
84
- NULL,
85
- PHP_RSHUTDOWN(twig),
86
- NULL,
87
- PHP_TWIG_VERSION,
88
- STANDARD_MODULE_PROPERTIES
89
- };
90
-
91
-
92
- #ifdef COMPILE_DL_TWIG
93
- ZEND_GET_MODULE(twig)
94
- #endif
95
-
96
- static int TWIG_ARRAY_KEY_EXISTS(zval *array, zval *key)
97
- {
98
- if (Z_TYPE_P(array) != IS_ARRAY) {
99
- return 0;
100
- }
101
-
102
- switch (Z_TYPE_P(key)) {
103
- case IS_NULL:
104
- return zend_hash_exists(Z_ARRVAL_P(array), "", 1);
105
-
106
- case IS_BOOL:
107
- case IS_DOUBLE:
108
- convert_to_long(key);
109
- case IS_LONG:
110
- return zend_hash_index_exists(Z_ARRVAL_P(array), Z_LVAL_P(key));
111
-
112
- default:
113
- convert_to_string(key);
114
- return zend_symtable_exists(Z_ARRVAL_P(array), Z_STRVAL_P(key), Z_STRLEN_P(key) + 1);
115
- }
116
- }
117
-
118
- static int TWIG_INSTANCE_OF(zval *object, zend_class_entry *interface TSRMLS_DC)
119
- {
120
- if (Z_TYPE_P(object) != IS_OBJECT) {
121
- return 0;
122
- }
123
- return instanceof_function(Z_OBJCE_P(object), interface TSRMLS_CC);
124
- }
125
-
126
- static int TWIG_INSTANCE_OF_USERLAND(zval *object, char *interface TSRMLS_DC)
127
- {
128
- zend_class_entry **pce;
129
- if (Z_TYPE_P(object) != IS_OBJECT) {
130
- return 0;
131
- }
132
- if (zend_lookup_class(interface, strlen(interface), &pce TSRMLS_CC) == FAILURE) {
133
- return 0;
134
- }
135
- return instanceof_function(Z_OBJCE_P(object), *pce TSRMLS_CC);
136
- }
137
-
138
- static zval *TWIG_GET_ARRAYOBJECT_ELEMENT(zval *object, zval *offset TSRMLS_DC)
139
- {
140
- zend_class_entry *ce = Z_OBJCE_P(object);
141
- zval *retval;
142
-
143
- if (Z_TYPE_P(object) == IS_OBJECT) {
144
- SEPARATE_ARG_IF_REF(offset);
145
- zend_call_method_with_1_params(&object, ce, NULL, "offsetget", &retval, offset);
146
-
147
- zval_ptr_dtor(&offset);
148
-
149
- if (!retval) {
150
- if (!EG(exception)) {
151
- zend_error(E_ERROR, "Undefined offset for object of type %s used as array.", ce->name);
152
- }
153
- return NULL;
154
- }
155
-
156
- return retval;
157
- }
158
- return NULL;
159
- }
160
-
161
- static int TWIG_ISSET_ARRAYOBJECT_ELEMENT(zval *object, zval *offset TSRMLS_DC)
162
- {
163
- zend_class_entry *ce = Z_OBJCE_P(object);
164
- zval *retval;
165
-
166
- if (Z_TYPE_P(object) == IS_OBJECT) {
167
- SEPARATE_ARG_IF_REF(offset);
168
- zend_call_method_with_1_params(&object, ce, NULL, "offsetexists", &retval, offset);
169
-
170
- zval_ptr_dtor(&offset);
171
-
172
- if (!retval) {
173
- if (!EG(exception)) {
174
- zend_error(E_ERROR, "Undefined offset for object of type %s used as array.", ce->name);
175
- }
176
- return 0;
177
- }
178
-
179
- return (retval && Z_TYPE_P(retval) == IS_BOOL && Z_LVAL_P(retval));
180
- }
181
- return 0;
182
- }
183
-
184
- static char *TWIG_STRTOLOWER(const char *str, int str_len)
185
- {
186
- char *item_dup;
187
-
188
- item_dup = estrndup(str, str_len);
189
- php_strtolower(item_dup, str_len);
190
- return item_dup;
191
- }
192
-
193
- static zval *TWIG_CALL_USER_FUNC_ARRAY(zval *object, char *function, zval *arguments TSRMLS_DC)
194
- {
195
- zend_fcall_info fci;
196
- zval ***args = NULL;
197
- int arg_count = 0;
198
- HashTable *table;
199
- HashPosition pos;
200
- int i = 0;
201
- zval *retval_ptr;
202
- zval *zfunction;
203
-
204
- if (arguments) {
205
- table = HASH_OF(arguments);
206
- args = safe_emalloc(sizeof(zval **), table->nNumOfElements, 0);
207
-
208
- zend_hash_internal_pointer_reset_ex(table, &pos);
209
-
210
- while (zend_hash_get_current_data_ex(table, (void **)&args[i], &pos) == SUCCESS) {
211
- i++;
212
- zend_hash_move_forward_ex(table, &pos);
213
- }
214
- arg_count = table->nNumOfElements;
215
- }
216
-
217
- MAKE_STD_ZVAL(zfunction);
218
- ZVAL_STRING(zfunction, function, 1);
219
- fci.size = sizeof(fci);
220
- fci.function_table = EG(function_table);
221
- fci.function_name = zfunction;
222
- fci.symbol_table = NULL;
223
- #if PHP_VERSION_ID >= 50300
224
- fci.object_ptr = object;
225
- #else
226
- fci.object_pp = &object;
227
- #endif
228
- fci.retval_ptr_ptr = &retval_ptr;
229
- fci.param_count = arg_count;
230
- fci.params = args;
231
- fci.no_separation = 0;
232
-
233
- if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE) {
234
- ALLOC_INIT_ZVAL(retval_ptr);
235
- ZVAL_BOOL(retval_ptr, 0);
236
- }
237
-
238
- if (args) {
239
- efree(fci.params);
240
- }
241
- FREE_DTOR(zfunction);
242
- return retval_ptr;
243
- }
244
-
245
- static int TWIG_CALL_BOOLEAN(zval *object, char *functionName TSRMLS_DC)
246
- {
247
- zval *ret;
248
- int res;
249
-
250
- ret = TWIG_CALL_USER_FUNC_ARRAY(object, functionName, NULL TSRMLS_CC);
251
- res = Z_LVAL_P(ret);
252
- zval_ptr_dtor(&ret);
253
- return res;
254
- }
255
-
256
- static zval *TWIG_GET_STATIC_PROPERTY(zval *class, char *prop_name TSRMLS_DC)
257
- {
258
- zval **tmp_zval;
259
- zend_class_entry *ce;
260
-
261
- if (class == NULL || Z_TYPE_P(class) != IS_OBJECT) {
262
- return NULL;
263
- }
264
-
265
- ce = zend_get_class_entry(class TSRMLS_CC);
266
- #if PHP_VERSION_ID >= 50400
267
- tmp_zval = zend_std_get_static_property(ce, prop_name, strlen(prop_name), 0, NULL TSRMLS_CC);
268
- #else
269
- tmp_zval = zend_std_get_static_property(ce, prop_name, strlen(prop_name), 0 TSRMLS_CC);
270
- #endif
271
- return *tmp_zval;
272
- }
273
-
274
- static zval *TWIG_GET_ARRAY_ELEMENT_ZVAL(zval *class, zval *prop_name TSRMLS_DC)
275
- {
276
- zval **tmp_zval;
277
-
278
- if (class == NULL || Z_TYPE_P(class) != IS_ARRAY) {
279
- if (class != NULL && Z_TYPE_P(class) == IS_OBJECT && TWIG_INSTANCE_OF(class, zend_ce_arrayaccess TSRMLS_CC)) {
280
- // array access object
281
- return TWIG_GET_ARRAYOBJECT_ELEMENT(class, prop_name TSRMLS_CC);
282
- }
283
- return NULL;
284
- }
285
-
286
- switch(Z_TYPE_P(prop_name)) {
287
- case IS_NULL:
288
- zend_hash_find(HASH_OF(class), "", 1, (void**) &tmp_zval);
289
- return *tmp_zval;
290
-
291
- case IS_BOOL:
292
- case IS_DOUBLE:
293
- convert_to_long(prop_name);
294
- case IS_LONG:
295
- zend_hash_index_find(HASH_OF(class), Z_LVAL_P(prop_name), (void **) &tmp_zval);
296
- return *tmp_zval;
297
-
298
- case IS_STRING:
299
- zend_symtable_find(HASH_OF(class), Z_STRVAL_P(prop_name), Z_STRLEN_P(prop_name) + 1, (void**) &tmp_zval);
300
- return *tmp_zval;
301
- }
302
-
303
- return NULL;
304
- }
305
-
306
- static zval *TWIG_GET_ARRAY_ELEMENT(zval *class, char *prop_name, int prop_name_length TSRMLS_DC)
307
- {
308
- zval **tmp_zval;
309
-
310
- if (class == NULL/* || Z_TYPE_P(class) != IS_ARRAY*/) {
311
- return NULL;
312
- }
313
-
314
- if (class != NULL && Z_TYPE_P(class) == IS_OBJECT && TWIG_INSTANCE_OF(class, zend_ce_arrayaccess TSRMLS_CC)) {
315
- // array access object
316
- zval *tmp_name_zval;
317
- zval *tmp_ret_zval;
318
-
319
- ALLOC_INIT_ZVAL(tmp_name_zval);
320
- ZVAL_STRING(tmp_name_zval, prop_name, 1);
321
- tmp_ret_zval = TWIG_GET_ARRAYOBJECT_ELEMENT(class, tmp_name_zval TSRMLS_CC);
322
- FREE_DTOR(tmp_name_zval);
323
- return tmp_ret_zval;
324
- }
325
-
326
- if (zend_symtable_find(HASH_OF(class), prop_name, prop_name_length+1, (void**)&tmp_zval) == SUCCESS) {
327
- return *tmp_zval;
328
- }
329
- return NULL;
330
- }
331
-
332
- static zval *TWIG_PROPERTY(zval *object, zval *propname TSRMLS_DC)
333
- {
334
- zval *tmp = NULL;
335
-
336
- if (Z_OBJ_HT_P(object)->read_property) {
337
- #if PHP_VERSION_ID >= 50400
338
- tmp = Z_OBJ_HT_P(object)->read_property(object, propname, BP_VAR_IS, NULL TSRMLS_CC);
339
- #else
340
- tmp = Z_OBJ_HT_P(object)->read_property(object, propname, BP_VAR_IS TSRMLS_CC);
341
- #endif
342
- if (tmp == EG(uninitialized_zval_ptr)) {
343
- ZVAL_NULL(tmp);
344
- }
345
- }
346
- return tmp;
347
- }
348
-
349
- static int TWIG_HAS_PROPERTY(zval *object, zval *propname TSRMLS_DC)
350
- {
351
- if (Z_OBJ_HT_P(object)->has_property) {
352
- #if PHP_VERSION_ID >= 50400
353
- return Z_OBJ_HT_P(object)->has_property(object, propname, 0, NULL TSRMLS_CC);
354
- #else
355
- return Z_OBJ_HT_P(object)->has_property(object, propname, 0 TSRMLS_CC);
356
- #endif
357
- }
358
- return 0;
359
- }
360
-
361
- static int TWIG_HAS_DYNAMIC_PROPERTY(zval *object, char *prop, int prop_len TSRMLS_DC)
362
- {
363
- if (Z_OBJ_HT_P(object)->get_properties) {
364
- return zend_hash_quick_exists(
365
- Z_OBJ_HT_P(object)->get_properties(object TSRMLS_CC), // the properties hash
366
- prop, // property name
367
- prop_len + 1, // property length
368
- zend_get_hash_value(prop, prop_len + 1) // hash value
369
- );
370
- }
371
- return 0;
372
- }
373
-
374
- static zval *TWIG_PROPERTY_CHAR(zval *object, char *propname TSRMLS_DC)
375
- {
376
- zval *tmp_name_zval, *tmp;
377
-
378
- ALLOC_INIT_ZVAL(tmp_name_zval);
379
- ZVAL_STRING(tmp_name_zval, propname, 1);
380
- tmp = TWIG_PROPERTY(object, tmp_name_zval TSRMLS_CC);
381
- FREE_DTOR(tmp_name_zval);
382
- return tmp;
383
- }
384
-
385
- static zval *TWIG_CALL_S(zval *object, char *method, char *arg0 TSRMLS_DC)
386
- {
387
- zend_fcall_info fci;
388
- zval **args[1];
389
- zval *argument;
390
- zval *zfunction;
391
- zval *retval_ptr;
392
-
393
- MAKE_STD_ZVAL(argument);
394
- ZVAL_STRING(argument, arg0, 1);
395
- args[0] = &argument;
396
-
397
- MAKE_STD_ZVAL(zfunction);
398
- ZVAL_STRING(zfunction, method, 1);
399
- fci.size = sizeof(fci);
400
- fci.function_table = EG(function_table);
401
- fci.function_name = zfunction;
402
- fci.symbol_table = NULL;
403
- #if PHP_VERSION_ID >= 50300
404
- fci.object_ptr = object;
405
- #else
406
- fci.object_pp = &object;
407
- #endif
408
- fci.retval_ptr_ptr = &retval_ptr;
409
- fci.param_count = 1;
410
- fci.params = args;
411
- fci.no_separation = 0;
412
-
413
- if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE) {
414
- FREE_DTOR(zfunction);
415
- zval_ptr_dtor(&argument);
416
- return 0;
417
- }
418
- FREE_DTOR(zfunction);
419
- zval_ptr_dtor(&argument);
420
- return retval_ptr;
421
- }
422
-
423
- static int TWIG_CALL_SB(zval *object, char *method, char *arg0 TSRMLS_DC)
424
- {
425
- zval *retval_ptr;
426
- int success;
427
-
428
- retval_ptr = TWIG_CALL_S(object, method, arg0 TSRMLS_CC);
429
- success = (retval_ptr && (Z_TYPE_P(retval_ptr) == IS_BOOL) && Z_LVAL_P(retval_ptr));
430
-
431
- if (retval_ptr) {
432
- zval_ptr_dtor(&retval_ptr);
433
- }
434
-
435
- return success;
436
- }
437
-
438
- static int TWIG_CALL_ZZ(zval *object, char *method, zval *arg1, zval *arg2 TSRMLS_DC)
439
- {
440
- zend_fcall_info fci;
441
- zval **args[2];
442
- zval *zfunction;
443
- zval *retval_ptr;
444
- int success;
445
-
446
- args[0] = &arg1;
447
- args[1] = &arg2;
448
-
449
- MAKE_STD_ZVAL(zfunction);
450
- ZVAL_STRING(zfunction, method, 1);
451
- fci.size = sizeof(fci);
452
- fci.function_table = EG(function_table);
453
- fci.function_name = zfunction;
454
- fci.symbol_table = NULL;
455
- #if PHP_VERSION_ID >= 50300
456
- fci.object_ptr = object;
457
- #else
458
- fci.object_pp = &object;
459
- #endif
460
- fci.retval_ptr_ptr = &retval_ptr;
461
- fci.param_count = 2;
462
- fci.params = args;
463
- fci.no_separation = 0;
464
-
465
- if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE) {
466
- FREE_DTOR(zfunction);
467
- return 0;
468
- }
469
-
470
- FREE_DTOR(zfunction);
471
-
472
- success = (retval_ptr && (Z_TYPE_P(retval_ptr) == IS_BOOL) && Z_LVAL_P(retval_ptr));
473
- if (retval_ptr) {
474
- zval_ptr_dtor(&retval_ptr);
475
- }
476
-
477
- return success;
478
- }
479
-
480
- #ifndef Z_SET_REFCOUNT_P
481
- # define Z_SET_REFCOUNT_P(pz, rc) pz->refcount = rc
482
- # define Z_UNSET_ISREF_P(pz) pz->is_ref = 0
483
- #endif
484
-
485
- static void TWIG_NEW(zval *object, char *class, zval *arg0, zval *arg1 TSRMLS_DC)
486
- {
487
- zend_class_entry **pce;
488
-
489
- if (zend_lookup_class(class, strlen(class), &pce TSRMLS_CC) == FAILURE) {
490
- return;
491
- }
492
-
493
- Z_TYPE_P(object) = IS_OBJECT;
494
- object_init_ex(object, *pce);
495
- Z_SET_REFCOUNT_P(object, 1);
496
- Z_UNSET_ISREF_P(object);
497
-
498
- TWIG_CALL_ZZ(object, "__construct", arg0, arg1 TSRMLS_CC);
499
- }
500
-
501
- static int twig_add_array_key_to_string(void *pDest APPLY_TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
502
- {
503
- smart_str *buf;
504
- char *joiner;
505
- APPLY_TSRMLS_FETCH();
506
-
507
- buf = va_arg(args, smart_str*);
508
- joiner = va_arg(args, char*);
509
-
510
- if (buf->len != 0) {
511
- smart_str_appends(buf, joiner);
512
- }
513
-
514
- if (hash_key->nKeyLength == 0) {
515
- smart_str_append_long(buf, (long) hash_key->h);
516
- } else {
517
- char *key, *tmp_str;
518
- int key_len, tmp_len;
519
- key = php_addcslashes(hash_key->arKey, hash_key->nKeyLength - 1, &key_len, 0, "'\\", 2 TSRMLS_CC);
520
- tmp_str = php_str_to_str_ex(key, key_len, "\0", 1, "' . \"\\0\" . '", 12, &tmp_len, 0, NULL);
521
-
522
- smart_str_appendl(buf, tmp_str, tmp_len);
523
- efree(key);
524
- efree(tmp_str);
525
- }
526
-
527
- return 0;
528
- }
529
-
530
- static char *TWIG_IMPLODE_ARRAY_KEYS(char *joiner, zval *array TSRMLS_DC)
531
- {
532
- smart_str collector = { 0, 0, 0 };
533
-
534
- smart_str_appendl(&collector, "", 0);
535
- zend_hash_apply_with_arguments(HASH_OF(array) APPLY_TSRMLS_CC, twig_add_array_key_to_string, 2, &collector, joiner);
536
- smart_str_0(&collector);
537
-
538
- return collector.c;
539
- }
540
-
541
- static void TWIG_RUNTIME_ERROR(zval *template TSRMLS_DC, char *message, ...)
542
- {
543
- char *buffer;
544
- va_list args;
545
- zend_class_entry **pce;
546
- zval *ex;
547
- zval *constructor;
548
- zval *zmessage;
549
- zval *lineno;
550
- zval *filename_func;
551
- zval *filename;
552
- zval *constructor_args[3];
553
- zval *constructor_retval;
554
-
555
- if (zend_lookup_class("Twig_Error_Runtime", strlen("Twig_Error_Runtime"), &pce TSRMLS_CC) == FAILURE) {
556
- return;
557
- }
558
-
559
- va_start(args, message);
560
- vspprintf(&buffer, 0, message, args);
561
- va_end(args);
562
-
563
- MAKE_STD_ZVAL(ex);
564
- object_init_ex(ex, *pce);
565
-
566
- // Call Twig_Error constructor
567
- MAKE_STD_ZVAL(constructor);
568
- MAKE_STD_ZVAL(zmessage);
569
- MAKE_STD_ZVAL(lineno);
570
- MAKE_STD_ZVAL(filename);
571
- MAKE_STD_ZVAL(filename_func);
572
- MAKE_STD_ZVAL(constructor_retval);
573
-
574
- ZVAL_STRINGL(constructor, "__construct", sizeof("__construct")-1, 1);
575
- ZVAL_STRING(zmessage, buffer, 1);
576
- ZVAL_LONG(lineno, -1);
577
-
578
- // Get template filename
579
- ZVAL_STRINGL(filename_func, "getTemplateName", sizeof("getTemplateName")-1, 1);
580
- call_user_function(EG(function_table), &template, filename_func, filename, 0, 0 TSRMLS_CC);
581
-
582
- constructor_args[0] = zmessage;
583
- constructor_args[1] = lineno;
584
- constructor_args[2] = filename;
585
- call_user_function(EG(function_table), &ex, constructor, constructor_retval, 3, constructor_args TSRMLS_CC);
586
-
587
- zval_ptr_dtor(&constructor_retval);
588
- zval_ptr_dtor(&zmessage);
589
- zval_ptr_dtor(&lineno);
590
- zval_ptr_dtor(&filename);
591
- FREE_DTOR(constructor);
592
- FREE_DTOR(filename_func);
593
- efree(buffer);
594
-
595
- zend_throw_exception_object(ex TSRMLS_CC);
596
- }
597
-
598
- static char *TWIG_GET_CLASS_NAME(zval *object TSRMLS_DC)
599
- {
600
- char *class_name;
601
- zend_uint class_name_len;
602
-
603
- if (Z_TYPE_P(object) != IS_OBJECT) {
604
- return "";
605
- }
606
- #if PHP_API_VERSION >= 20100412
607
- zend_get_object_classname(object, (const char **) &class_name, &class_name_len TSRMLS_CC);
608
- #else
609
- zend_get_object_classname(object, &class_name, &class_name_len TSRMLS_CC);
610
- #endif
611
- return class_name;
612
- }
613
-
614
- static int twig_add_method_to_class(void *pDest APPLY_TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
615
- {
616
- zend_class_entry *ce;
617
- zval *retval;
618
- char *item;
619
- size_t item_len;
620
- zend_function *mptr = (zend_function *) pDest;
621
- APPLY_TSRMLS_FETCH();
622
-
623
- if (!(mptr->common.fn_flags & ZEND_ACC_PUBLIC)) {
624
- return 0;
625
- }
626
-
627
- ce = *va_arg(args, zend_class_entry**);
628
- retval = va_arg(args, zval*);
629
-
630
- item_len = strlen(mptr->common.function_name);
631
- item = estrndup(mptr->common.function_name, item_len);
632
- php_strtolower(item, item_len);
633
-
634
- if (strcmp("getenvironment", item) == 0) {
635
- zend_class_entry **twig_template_ce;
636
- if (zend_lookup_class("Twig_Template", strlen("Twig_Template"), &twig_template_ce TSRMLS_CC) == FAILURE) {
637
- return 0;
638
- }
639
- if (instanceof_function(ce, *twig_template_ce TSRMLS_CC)) {
640
- return 0;
641
- }
642
- }
643
-
644
- add_assoc_stringl_ex(retval, item, item_len+1, item, item_len, 0);
645
-
646
- return 0;
647
- }
648
-
649
- static int twig_add_property_to_class(void *pDest APPLY_TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
650
- {
651
- zend_class_entry *ce;
652
- zval *retval;
653
- char *class_name, *prop_name;
654
- zend_property_info *pptr = (zend_property_info *) pDest;
655
- APPLY_TSRMLS_FETCH();
656
-
657
- if (!(pptr->flags & ZEND_ACC_PUBLIC) || (pptr->flags & ZEND_ACC_STATIC)) {
658
- return 0;
659
- }
660
-
661
- ce = *va_arg(args, zend_class_entry**);
662
- retval = va_arg(args, zval*);
663
-
664
- #if PHP_API_VERSION >= 20100412
665
- zend_unmangle_property_name(pptr->name, pptr->name_length, (const char **) &class_name, (const char **) &prop_name);
666
- #else
667
- zend_unmangle_property_name(pptr->name, pptr->name_length, &class_name, &prop_name);
668
- #endif
669
-
670
- add_assoc_string(retval, prop_name, prop_name, 1);
671
-
672
- return 0;
673
- }
674
-
675
- static void twig_add_class_to_cache(zval *cache, zval *object, char *class_name TSRMLS_DC)
676
- {
677
- zval *class_info, *class_methods, *class_properties;
678
- zend_class_entry *class_ce;
679
-
680
- class_ce = zend_get_class_entry(object TSRMLS_CC);
681
-
682
- ALLOC_INIT_ZVAL(class_info);
683
- ALLOC_INIT_ZVAL(class_methods);
684
- ALLOC_INIT_ZVAL(class_properties);
685
- array_init(class_info);
686
- array_init(class_methods);
687
- array_init(class_properties);
688
- // add all methods to self::cache[$class]['methods']
689
- zend_hash_apply_with_arguments(&class_ce->function_table APPLY_TSRMLS_CC, twig_add_method_to_class, 2, &class_ce, class_methods);
690
- zend_hash_apply_with_arguments(&class_ce->properties_info APPLY_TSRMLS_CC, twig_add_property_to_class, 2, &class_ce, class_properties);
691
-
692
- add_assoc_zval(class_info, "methods", class_methods);
693
- add_assoc_zval(class_info, "properties", class_properties);
694
- add_assoc_zval(cache, class_name, class_info);
695
- }
696
-
697
- /* {{{ proto mixed twig_template_get_attributes(TwigTemplate template, mixed object, mixed item, array arguments, string type, boolean isDefinedTest, boolean ignoreStrictCheck)
698
- A C implementation of TwigTemplate::getAttribute() */
699
- PHP_FUNCTION(twig_template_get_attributes)
700
- {
701
- zval *template;
702
- zval *object;
703
- char *item;
704
- int item_len;
705
- zval *zitem, ztmpitem;
706
- zval *arguments = NULL;
707
- zval *ret = NULL;
708
- char *type = NULL;
709
- int type_len = 0;
710
- zend_bool isDefinedTest = 0;
711
- zend_bool ignoreStrictCheck = 0;
712
- int free_ret = 0;
713
- zval *tmp_self_cache;
714
- char *class_name = NULL;
715
- zval *tmp_class;
716
- char *type_name;
717
-
718
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ozz|asbb", &template, &object, &zitem, &arguments, &type, &type_len, &isDefinedTest, &ignoreStrictCheck) == FAILURE) {
719
- return;
720
- }
721
-
722
- // convert the item to a string
723
- ztmpitem = *zitem;
724
- zval_copy_ctor(&ztmpitem);
725
- convert_to_string(&ztmpitem);
726
- item_len = Z_STRLEN(ztmpitem);
727
- item = estrndup(Z_STRVAL(ztmpitem), item_len);
728
- zval_dtor(&ztmpitem);
729
-
730
- if (!type) {
731
- type = "any";
732
- }
733
-
734
- /*
735
- // array
736
- if (\Twig\Template::METHOD_CALL !== $type) {
737
- $arrayItem = is_bool($item) || is_float($item) ? (int) $item : $item;
738
-
739
- if ((is_array($object) && array_key_exists($arrayItem, $object))
740
- || ($object instanceof ArrayAccess && isset($object[$arrayItem]))
741
- ) {
742
- if ($isDefinedTest) {
743
- return true;
744
- }
745
-
746
- return $object[$arrayItem];
747
- }
748
- */
749
-
750
-
751
- if (strcmp("method", type) != 0) {
752
- if ((TWIG_ARRAY_KEY_EXISTS(object, zitem))
753
- || (TWIG_INSTANCE_OF(object, zend_ce_arrayaccess TSRMLS_CC) && TWIG_ISSET_ARRAYOBJECT_ELEMENT(object, zitem TSRMLS_CC))
754
- ) {
755
-
756
- if (isDefinedTest) {
757
- efree(item);
758
- RETURN_TRUE;
759
- }
760
-
761
- ret = TWIG_GET_ARRAY_ELEMENT_ZVAL(object, zitem TSRMLS_CC);
762
-
763
- if (!ret) {
764
- ret = &EG(uninitialized_zval);
765
- }
766
- RETVAL_ZVAL(ret, 1, 0);
767
- if (free_ret) {
768
- zval_ptr_dtor(&ret);
769
- }
770
- efree(item);
771
- return;
772
- }
773
- /*
774
- if (\Twig\Template::ARRAY_CALL === $type) {
775
- if ($isDefinedTest) {
776
- return false;
777
- }
778
- if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
779
- return null;
780
- }
781
- */
782
- if (strcmp("array", type) == 0 || Z_TYPE_P(object) != IS_OBJECT) {
783
- if (isDefinedTest) {
784
- efree(item);
785
- RETURN_FALSE;
786
- }
787
- if (ignoreStrictCheck || !TWIG_CALL_BOOLEAN(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "isStrictVariables" TSRMLS_CC)) {
788
- efree(item);
789
- return;
790
- }
791
- /*
792
- if ($object instanceof ArrayAccess) {
793
- $message = sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist', $arrayItem, get_class($object));
794
- } elseif (is_object($object)) {
795
- $message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface', $item, get_class($object));
796
- } elseif (is_array($object)) {
797
- if (empty($object)) {
798
- $message = sprintf('Key "%s" does not exist as the array is empty', $arrayItem);
799
- } else {
800
- $message = sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object)));
801
- }
802
- } elseif (\Twig\Template::ARRAY_CALL === $type) {
803
- if (null === $object) {
804
- $message = sprintf('Impossible to access a key ("%s") on a null variable', $item);
805
- } else {
806
- $message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
807
- }
808
- } elseif (null === $object) {
809
- $message = sprintf('Impossible to access an attribute ("%s") on a null variable', $item);
810
- } else {
811
- $message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
812
- }
813
- throw new \Twig\Error\RuntimeError($message, -1, $this->getTemplateName());
814
- }
815
- }
816
- */
817
- if (TWIG_INSTANCE_OF(object, zend_ce_arrayaccess TSRMLS_CC)) {
818
- TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" in object with ArrayAccess of class \"%s\" does not exist.", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
819
- } else if (Z_TYPE_P(object) == IS_OBJECT) {
820
- TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to access a key \"%s\" on an object of class \"%s\" that does not implement ArrayAccess interface.", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
821
- } else if (Z_TYPE_P(object) == IS_ARRAY) {
822
- if (0 == zend_hash_num_elements(Z_ARRVAL_P(object))) {
823
- TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" does not exist as the array is empty.", item);
824
- } else {
825
- char *array_keys = TWIG_IMPLODE_ARRAY_KEYS(", ", object TSRMLS_CC);
826
- TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" for array with keys \"%s\" does not exist.", item, array_keys);
827
- efree(array_keys);
828
- }
829
- } else {
830
- char *type_name = zend_zval_type_name(object);
831
- Z_ADDREF_P(object);
832
- if (Z_TYPE_P(object) == IS_NULL) {
833
- convert_to_string(object);
834
- TWIG_RUNTIME_ERROR(template TSRMLS_CC,
835
- (strcmp("array", type) == 0)
836
- ? "Impossible to access a key (\"%s\") on a %s variable."
837
- : "Impossible to access an attribute (\"%s\") on a %s variable.",
838
- item, type_name);
839
- } else {
840
- convert_to_string(object);
841
- TWIG_RUNTIME_ERROR(template TSRMLS_CC,
842
- (strcmp("array", type) == 0)
843
- ? "Impossible to access a key (\"%s\") on a %s variable (\"%s\")."
844
- : "Impossible to access an attribute (\"%s\") on a %s variable (\"%s\").",
845
- item, type_name, Z_STRVAL_P(object));
846
- }
847
- zval_ptr_dtor(&object);
848
- }
849
- efree(item);
850
- return;
851
- }
852
- }
853
-
854
- /*
855
- if (!is_object($object)) {
856
- if ($isDefinedTest) {
857
- return false;
858
- }
859
- */
860
-
861
- if (Z_TYPE_P(object) != IS_OBJECT) {
862
- if (isDefinedTest) {
863
- efree(item);
864
- RETURN_FALSE;
865
- }
866
- /*
867
- if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
868
- return null;
869
- }
870
-
871
- if (null === $object) {
872
- $message = sprintf('Impossible to invoke a method ("%s") on a null variable', $item);
873
- } elseif (is_array($object)) {
874
- $message = sprintf('Impossible to invoke a method ("%s") on an array.', $item);
875
- } else {
876
- $message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
877
- }
878
-
879
- throw new \Twig\Error\RuntimeError($message, -1, $this->getTemplateName());
880
- }
881
- */
882
- if (ignoreStrictCheck || !TWIG_CALL_BOOLEAN(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "isStrictVariables" TSRMLS_CC)) {
883
- efree(item);
884
- return;
885
- }
886
-
887
- type_name = zend_zval_type_name(object);
888
- Z_ADDREF_P(object);
889
- if (Z_TYPE_P(object) == IS_NULL) {
890
- TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to invoke a method (\"%s\") on a null variable.", item);
891
- } else if (Z_TYPE_P(object) == IS_ARRAY) {
892
- TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to invoke a method (\"%s\") on an array.", item);
893
- } else {
894
- convert_to_string_ex(&object);
895
-
896
- TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to invoke a method (\"%s\") on a %s variable (\"%s\").", item, type_name, Z_STRVAL_P(object));
897
- }
898
-
899
- zval_ptr_dtor(&object);
900
- efree(item);
901
- return;
902
- }
903
- /*
904
- $class = get_class($object);
905
- */
906
-
907
- class_name = TWIG_GET_CLASS_NAME(object TSRMLS_CC);
908
- tmp_self_cache = TWIG_GET_STATIC_PROPERTY(template, "cache" TSRMLS_CC);
909
- tmp_class = TWIG_GET_ARRAY_ELEMENT(tmp_self_cache, class_name, strlen(class_name) TSRMLS_CC);
910
-
911
- if (!tmp_class) {
912
- twig_add_class_to_cache(tmp_self_cache, object, class_name TSRMLS_CC);
913
- tmp_class = TWIG_GET_ARRAY_ELEMENT(tmp_self_cache, class_name, strlen(class_name) TSRMLS_CC);
914
- }
915
- efree(class_name);
916
-
917
- /*
918
- // object property
919
- if (\Twig\Template::METHOD_CALL !== $type && !$object instanceof \Twig\Template) {
920
- if (isset($object->$item) || array_key_exists((string) $item, $object)) {
921
- if ($isDefinedTest) {
922
- return true;
923
- }
924
-
925
- if ($this->env->hasExtension('\Twig\Extension\SandboxExtension')) {
926
- $this->env->getExtension('\Twig\Extension\SandboxExtension')->checkPropertyAllowed($object, $item);
927
- }
928
-
929
- return $object->$item;
930
- }
931
- }
932
- */
933
- if (strcmp("method", type) != 0 && !TWIG_INSTANCE_OF_USERLAND(object, "Twig_Template" TSRMLS_CC)) {
934
- zval *tmp_properties, *tmp_item;
935
-
936
- tmp_properties = TWIG_GET_ARRAY_ELEMENT(tmp_class, "properties", strlen("properties") TSRMLS_CC);
937
- tmp_item = TWIG_GET_ARRAY_ELEMENT(tmp_properties, item, item_len TSRMLS_CC);
938
-
939
- if (tmp_item || TWIG_HAS_PROPERTY(object, zitem TSRMLS_CC) || TWIG_HAS_DYNAMIC_PROPERTY(object, item, item_len TSRMLS_CC)) {
940
- if (isDefinedTest) {
941
- efree(item);
942
- RETURN_TRUE;
943
- }
944
- if (TWIG_CALL_SB(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "hasExtension", "Twig_Extension_Sandbox" TSRMLS_CC)) {
945
- TWIG_CALL_ZZ(TWIG_CALL_S(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getExtension", "Twig_Extension_Sandbox" TSRMLS_CC), "checkPropertyAllowed", object, zitem TSRMLS_CC);
946
- }
947
- if (EG(exception)) {
948
- efree(item);
949
- return;
950
- }
951
-
952
- ret = TWIG_PROPERTY(object, zitem TSRMLS_CC);
953
- efree(item);
954
- RETURN_ZVAL(ret, 1, 0);
955
- }
956
- }
957
- /*
958
- // object method
959
- if (!isset(self::$cache[$class]['methods'])) {
960
- if ($object instanceof self) {
961
- $ref = new \ReflectionClass($class);
962
- $methods = [];
963
-
964
- foreach ($ref->getMethods(ReflectionMethod::IS_PUBLIC) as $refMethod) {
965
- $methodName = strtolower($refMethod->name);
966
-
967
- // Accessing the environment from templates is forbidden to prevent untrusted changes to the environment
968
- if ('getenvironment' !== $methodName) {
969
- $methods[$methodName] = true;
970
- }
971
- }
972
-
973
- self::$cache[$class]['methods'] = $methods;
974
- } else {
975
- self::$cache[$class]['methods'] = array_change_key_case(array_flip(get_class_methods($object)));
976
- }
977
- }
978
-
979
- $call = false;
980
- $lcItem = strtolower($item);
981
- if (isset(self::$cache[$class]['methods'][$lcItem])) {
982
- $method = (string) $item;
983
- } elseif (isset(self::$cache[$class]['methods']['get'.$lcItem])) {
984
- $method = 'get'.$item;
985
- } elseif (isset(self::$cache[$class]['methods']['is'.$lcItem])) {
986
- $method = 'is'.$item;
987
- } elseif (isset(self::$cache[$class]['methods']['__call'])) {
988
- $method = (string) $item;
989
- $call = true;
990
- */
991
- {
992
- int call = 0;
993
- char *lcItem = TWIG_STRTOLOWER(item, item_len);
994
- int lcItem_length;
995
- char *method = NULL;
996
- char *methodForDeprecation = NULL;
997
- char *tmp_method_name_get;
998
- char *tmp_method_name_is;
999
- zval *zmethod;
1000
- zval *tmp_methods;
1001
-
1002
- lcItem_length = strlen(lcItem);
1003
- tmp_method_name_get = emalloc(4 + lcItem_length);
1004
- tmp_method_name_is = emalloc(3 + lcItem_length);
1005
-
1006
- sprintf(tmp_method_name_get, "get%s", lcItem);
1007
- sprintf(tmp_method_name_is, "is%s", lcItem);
1008
-
1009
- tmp_methods = TWIG_GET_ARRAY_ELEMENT(tmp_class, "methods", strlen("methods") TSRMLS_CC);
1010
- methodForDeprecation = emalloc(item_len + 1);
1011
- sprintf(methodForDeprecation, "%s", item);
1012
-
1013
- if (TWIG_GET_ARRAY_ELEMENT(tmp_methods, lcItem, lcItem_length TSRMLS_CC)) {
1014
- method = item;
1015
- } else if (TWIG_GET_ARRAY_ELEMENT(tmp_methods, tmp_method_name_get, lcItem_length + 3 TSRMLS_CC)) {
1016
- method = tmp_method_name_get;
1017
- } else if (TWIG_GET_ARRAY_ELEMENT(tmp_methods, tmp_method_name_is, lcItem_length + 2 TSRMLS_CC)) {
1018
- method = tmp_method_name_is;
1019
- } else if (TWIG_GET_ARRAY_ELEMENT(tmp_methods, "__call", 6 TSRMLS_CC)) {
1020
- method = item;
1021
- call = 1;
1022
- /*
1023
- } else {
1024
- if ($isDefinedTest) {
1025
- return false;
1026
- }
1027
-
1028
- if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
1029
- return null;
1030
- }
1031
-
1032
- throw new \Twig\Error\RuntimeError(sprintf('Method "%s" for object "%s" does not exist.', $item, get_class($object)), -1, $this->getTemplateName());
1033
- }
1034
-
1035
- if ($isDefinedTest) {
1036
- return true;
1037
- }
1038
- */
1039
- } else {
1040
- efree(tmp_method_name_get);
1041
- efree(tmp_method_name_is);
1042
- efree(lcItem);
1043
-
1044
- if (isDefinedTest) {
1045
- efree(item);
1046
- RETURN_FALSE;
1047
- }
1048
- if (ignoreStrictCheck || !TWIG_CALL_BOOLEAN(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "isStrictVariables" TSRMLS_CC)) {
1049
- efree(item);
1050
- return;
1051
- }
1052
- TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Neither the property \"%s\" nor one of the methods \"%s()\", \"get%s()\"/\"is%s()\" or \"__call()\" exist and have public access in class \"%s\".", item, item, item, item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
1053
- efree(item);
1054
- return;
1055
- }
1056
-
1057
- if (isDefinedTest) {
1058
- efree(tmp_method_name_get);
1059
- efree(tmp_method_name_is);
1060
- efree(lcItem);efree(item);
1061
- RETURN_TRUE;
1062
- }
1063
- /*
1064
- if ($this->env->hasExtension('\Twig\Extension\SandboxExtension')) {
1065
- $this->env->getExtension('\Twig\Extension\SandboxExtension')->checkMethodAllowed($object, $method);
1066
- }
1067
- */
1068
- MAKE_STD_ZVAL(zmethod);
1069
- ZVAL_STRING(zmethod, method, 1);
1070
- if (TWIG_CALL_SB(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "hasExtension", "Twig_Extension_Sandbox" TSRMLS_CC)) {
1071
- TWIG_CALL_ZZ(TWIG_CALL_S(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getExtension", "Twig_Extension_Sandbox" TSRMLS_CC), "checkMethodAllowed", object, zmethod TSRMLS_CC);
1072
- }
1073
- zval_ptr_dtor(&zmethod);
1074
- if (EG(exception)) {
1075
- efree(tmp_method_name_get);
1076
- efree(tmp_method_name_is);
1077
- efree(lcItem);efree(item);
1078
- return;
1079
- }
1080
- /*
1081
- // Some objects throw exceptions when they have __call, and the method we try
1082
- // to call is not supported. If ignoreStrictCheck is true, we should return null.
1083
- try {
1084
- $ret = call_user_func_array([$object, $method], $arguments);
1085
- } catch (\BadMethodCallException $e) {
1086
- if ($call && ($ignoreStrictCheck || !$this->env->isStrictVariables())) {
1087
- return null;
1088
- }
1089
- throw $e;
1090
- }
1091
- */
1092
- ret = TWIG_CALL_USER_FUNC_ARRAY(object, method, arguments TSRMLS_CC);
1093
- if (EG(exception) && TWIG_INSTANCE_OF(EG(exception), spl_ce_BadMethodCallException TSRMLS_CC)) {
1094
- if (ignoreStrictCheck || !TWIG_CALL_BOOLEAN(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "isStrictVariables" TSRMLS_CC)) {
1095
- efree(tmp_method_name_get);
1096
- efree(tmp_method_name_is);
1097
- efree(lcItem);efree(item);
1098
- zend_clear_exception(TSRMLS_C);
1099
- return;
1100
- }
1101
- }
1102
- free_ret = 1;
1103
- efree(tmp_method_name_get);
1104
- efree(tmp_method_name_is);
1105
- efree(lcItem);
1106
- /*
1107
- // @deprecated in 1.28
1108
- if ($object instanceof Twig_TemplateInterface) {
1109
- $self = $object->getTemplateName() === $this->getTemplateName();
1110
- $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());
1111
- if ('renderBlock' === $method || 'displayBlock' === $method) {
1112
- $message .= sprintf(' Use block("%s"%s) instead).', $arguments[0], $self ? '' : ', template');
1113
- } elseif ('hasBlock' === $method) {
1114
- $message .= sprintf(' Use "block("%s"%s) is defined" instead).', $arguments[0], $self ? '' : ', template');
1115
- } elseif ('render' === $method || 'display' === $method) {
1116
- $message .= sprintf(' Use include("%s") instead).', $object->getTemplateName());
1117
- }
1118
- @trigger_error($message, E_USER_DEPRECATED);
1119
-
1120
- return $ret === '' ? '' : new \Twig\Markup($ret, $this->env->getCharset());
1121
- }
1122
-
1123
- return $ret;
1124
- */
1125
- efree(item);
1126
- // ret can be null, if e.g. the called method throws an exception
1127
- if (ret) {
1128
- if (TWIG_INSTANCE_OF_USERLAND(object, "Twig_TemplateInterface" TSRMLS_CC)) {
1129
- int self;
1130
- int old_error_reporting;
1131
- zval *object_filename;
1132
- zval *this_filename;
1133
- zval *filename_func;
1134
- char *deprecation_message_complement = NULL;
1135
- char *deprecation_message = NULL;
1136
-
1137
- MAKE_STD_ZVAL(object_filename);
1138
- MAKE_STD_ZVAL(this_filename);
1139
- MAKE_STD_ZVAL(filename_func);
1140
-
1141
- // Get templates names
1142
- ZVAL_STRINGL(filename_func, "getTemplateName", sizeof("getTemplateName")-1, 1);
1143
- call_user_function(EG(function_table), &object, filename_func, object_filename, 0, 0 TSRMLS_CC);
1144
- ZVAL_STRINGL(filename_func, "getTemplateName", sizeof("getTemplateName")-1, 1);
1145
- call_user_function(EG(function_table), &template, filename_func, this_filename, 0, 0 TSRMLS_CC);
1146
-
1147
- self = (strcmp(Z_STRVAL_P(object_filename), Z_STRVAL_P(this_filename)) == 0);
1148
-
1149
- if (strcmp(methodForDeprecation, "renderBlock") == 0 || strcmp(methodForDeprecation, "displayBlock") == 0) {
1150
- zval **arg0;
1151
- zend_hash_index_find(HASH_OF(arguments), 0, (void **) &arg0);
1152
- asprintf(
1153
- &deprecation_message_complement,
1154
- " Use block(\"%s\"%s) instead).",
1155
- Z_STRVAL_PP(arg0),
1156
- self ? "" : ", template"
1157
- );
1158
- } else if (strcmp(methodForDeprecation, "hasBlock") == 0) {
1159
- zval **arg0;
1160
- zend_hash_index_find(HASH_OF(arguments), 0, (void **) &arg0);
1161
- asprintf(
1162
- &deprecation_message_complement,
1163
- " Use \"block(\"%s\"%s) is defined\" instead).",
1164
- Z_STRVAL_PP(arg0),
1165
- self ? "" : ", template"
1166
- );
1167
- } else if (strcmp(methodForDeprecation, "render") == 0 || strcmp(methodForDeprecation, "display") == 0) {
1168
- asprintf(
1169
- &deprecation_message_complement,
1170
- " Use include(\"%s\") instead).",
1171
- Z_STRVAL_P(object_filename)
1172
- );
1173
- } else {
1174
- deprecation_message_complement = (char*)calloc(0, sizeof(char));
1175
- }
1176
-
1177
- asprintf(
1178
- &deprecation_message,
1179
- "Calling \"%s\" on template \"%s\" from template \"%s\" is deprecated since version 1.28 and won't be supported anymore in 2.0.%s",
1180
- methodForDeprecation,
1181
- Z_STRVAL_P(object_filename),
1182
- Z_STRVAL_P(this_filename),
1183
- deprecation_message_complement
1184
- );
1185
-
1186
- old_error_reporting = EG(error_reporting);
1187
- EG(error_reporting) = 0;
1188
- zend_error(E_USER_DEPRECATED, "%s", deprecation_message);
1189
- EG(error_reporting) = old_error_reporting;
1190
-
1191
- FREE_DTOR(filename_func)
1192
- FREE_DTOR(object_filename)
1193
- FREE_DTOR(this_filename)
1194
- free(deprecation_message);
1195
- free(deprecation_message_complement);
1196
-
1197
- if (Z_STRLEN_P(ret) != 0) {
1198
- zval *charset = TWIG_CALL_USER_FUNC_ARRAY(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getCharset", NULL TSRMLS_CC);
1199
- TWIG_NEW(return_value, "Twig_Markup", ret, charset TSRMLS_CC);
1200
- zval_ptr_dtor(&charset);
1201
- if (ret) {
1202
- zval_ptr_dtor(&ret);
1203
- }
1204
- efree(methodForDeprecation);
1205
- return;
1206
- }
1207
- }
1208
-
1209
- RETVAL_ZVAL(ret, 1, 0);
1210
- if (free_ret) {
1211
- zval_ptr_dtor(&ret);
1212
- }
1213
- }
1214
-
1215
- efree(methodForDeprecation);
1216
- }
1217
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/Autoloader.php DELETED
@@ -1,52 +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
-
12
- @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);
13
-
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
-
32
- spl_autoload_register([__CLASS__, 'autoload'], true, $prepend);
33
- }
34
-
35
- /**
36
- * Handles autoloading of classes.
37
- *
38
- * @param string $class a class name
39
- */
40
- public static function autoload($class)
41
- {
42
- if (0 !== strpos($class, 'Twig')) {
43
- return;
44
- }
45
-
46
- if (is_file($file = __DIR__.'/../'.str_replace(['_', "\0"], ['/', ''], $class).'.php')) {
47
- require $file;
48
- } elseif (is_file($file = __DIR__.'/../../src/'.str_replace(['Twig\\', '\\', "\0"], ['', '/', ''], $class).'.php')) {
49
- require $file;
50
- }
51
- }
52
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/BaseNodeVisitor.php CHANGED
@@ -4,7 +4,10 @@ use Twig\NodeVisitor\AbstractNodeVisitor;
4
 
5
  class_exists('Twig\NodeVisitor\AbstractNodeVisitor');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_BaseNodeVisitor extends AbstractNodeVisitor
9
  {
10
  }
4
 
5
  class_exists('Twig\NodeVisitor\AbstractNodeVisitor');
6
 
7
+ @trigger_error('Using the "Twig_BaseNodeVisitor" class is deprecated since Twig version 2.7, use "Twig\NodeVisitor\AbstractNodeVisitor" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\NodeVisitor\AbstractNodeVisitor" instead */
11
  class Twig_BaseNodeVisitor extends AbstractNodeVisitor
12
  {
13
  }
vendor/twig/twig/lib/Twig/Cache/Filesystem.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Cache\FilesystemCache;
4
 
5
  class_exists('Twig\Cache\FilesystemCache');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Cache_Filesystem extends FilesystemCache
9
  {
10
  }
4
 
5
  class_exists('Twig\Cache\FilesystemCache');
6
 
7
+ @trigger_error('Using the "Twig_Cache_Filesystem" class is deprecated since Twig version 2.7, use "Twig\Cache\FilesystemCache" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Cache\FilesystemCache" instead */
11
  class Twig_Cache_Filesystem extends FilesystemCache
12
  {
13
  }
vendor/twig/twig/lib/Twig/Cache/Null.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Cache\NullCache;
4
 
5
  class_exists('Twig\Cache\NullCache');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Cache_Null extends NullCache
9
  {
10
  }
4
 
5
  class_exists('Twig\Cache\NullCache');
6
 
7
+ @trigger_error('Using the "Twig_Cache_Null" class is deprecated since Twig version 2.7, use "Twig\Cache\NullCache" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Cache\NullCache" instead */
11
  class Twig_Cache_Null extends NullCache
12
  {
13
  }
vendor/twig/twig/lib/Twig/CacheInterface.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Cache\CacheInterface;
4
 
5
  class_exists('Twig\Cache\CacheInterface');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_CacheInterface extends CacheInterface
9
  {
10
  }
4
 
5
  class_exists('Twig\Cache\CacheInterface');
6
 
7
+ @trigger_error('Using the "Twig_CacheInterface" class is deprecated since Twig version 2.7, use "Twig\Cache\CacheInterface" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Cache\CacheInterface" instead */
11
  class Twig_CacheInterface extends CacheInterface
12
  {
13
  }
vendor/twig/twig/lib/Twig/Compiler.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Compiler;
4
 
5
  class_exists('Twig\Compiler');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Compiler extends Compiler
9
  {
10
  }
4
 
5
  class_exists('Twig\Compiler');
6
 
7
+ @trigger_error('Using the "Twig_Compiler" class is deprecated since Twig version 2.7, use "Twig\Compiler" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Compiler" instead */
11
  class Twig_Compiler extends Compiler
12
  {
13
  }
vendor/twig/twig/lib/Twig/CompilerInterface.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
-
12
- /**
13
- * Interface implemented by compiler classes.
14
- *
15
- * @author Fabien Potencier <fabien@symfony.com>
16
- *
17
- * @deprecated since 1.12 (to be removed in 3.0)
18
- */
19
- interface Twig_CompilerInterface
20
- {
21
- /**
22
- * Compiles a node.
23
- *
24
- * @return $this
25
- */
26
- public function compile(Twig_NodeInterface $node);
27
-
28
- /**
29
- * Gets the current PHP code after compilation.
30
- *
31
- * @return string The PHP code
32
- */
33
- public function getSource();
34
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/ContainerRuntimeLoader.php CHANGED
@@ -4,7 +4,10 @@ use Twig\RuntimeLoader\ContainerRuntimeLoader;
4
 
5
  class_exists('Twig\RuntimeLoader\ContainerRuntimeLoader');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_ContainerRuntimeLoader extends ContainerRuntimeLoader
9
  {
10
  }
4
 
5
  class_exists('Twig\RuntimeLoader\ContainerRuntimeLoader');
6
 
7
+ @trigger_error('Using the "Twig_ContainerRuntimeLoader" class is deprecated since Twig version 2.7, use "Twig\RuntimeLoader\ContainerRuntimeLoader" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\RuntimeLoader\ContainerRuntimeLoader" instead */
11
  class Twig_ContainerRuntimeLoader extends ContainerRuntimeLoader
12
  {
13
  }
vendor/twig/twig/lib/Twig/Environment.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Environment;
4
 
5
  class_exists('Twig\Environment');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Environment extends Environment
9
  {
10
  }
4
 
5
  class_exists('Twig\Environment');
6
 
7
+ @trigger_error('Using the "Twig_Environment" class is deprecated since Twig version 2.7, use "Twig\Environment" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Environment" instead */
11
  class Twig_Environment extends Environment
12
  {
13
  }
vendor/twig/twig/lib/Twig/Error.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Error\Error;
4
 
5
  class_exists('Twig\Error\Error');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Error extends Error
9
  {
10
  }
4
 
5
  class_exists('Twig\Error\Error');
6
 
7
+ @trigger_error('Using the "Twig_Error" class is deprecated since Twig version 2.7, use "Twig\Error\Error" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Error\Error" instead */
11
  class Twig_Error extends Error
12
  {
13
  }
vendor/twig/twig/lib/Twig/Error/Loader.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Error\LoaderError;
4
 
5
  class_exists('Twig\Error\LoaderError');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Error_Loader extends LoaderError
9
  {
10
  }
4
 
5
  class_exists('Twig\Error\LoaderError');
6
 
7
+ @trigger_error('Using the "Twig_Error_Loader" class is deprecated since Twig version 2.7, use "Twig\Error\LoaderError" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Error\LoaderError" instead */
11
  class Twig_Error_Loader extends LoaderError
12
  {
13
  }
vendor/twig/twig/lib/Twig/Error/Runtime.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Error\RuntimeError;
4
 
5
  class_exists('Twig\Error\RuntimeError');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Error_Runtime extends RuntimeError
9
  {
10
  }
4
 
5
  class_exists('Twig\Error\RuntimeError');
6
 
7
+ @trigger_error('Using the "Twig_Error_Runtime" class is deprecated since Twig version 2.7, use "Twig\Error\RuntimeError" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Error\RuntimeError" instead */
11
  class Twig_Error_Runtime extends RuntimeError
12
  {
13
  }
vendor/twig/twig/lib/Twig/Error/Syntax.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Error\SyntaxError;
4
 
5
  class_exists('Twig\Error\SyntaxError');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Error_Syntax extends SyntaxError
9
  {
10
  }
4
 
5
  class_exists('Twig\Error\SyntaxError');
6
 
7
+ @trigger_error('Using the "Twig_Error_Syntax" class is deprecated since Twig version 2.7, use "Twig\Error\SyntaxError" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Error\SyntaxError" instead */
11
  class Twig_Error_Syntax extends SyntaxError
12
  {
13
  }
vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Loader\ExistsLoaderInterface;
4
 
5
  class_exists('Twig\Loader\ExistsLoaderInterface');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_ExistsLoaderInterface extends ExistsLoaderInterface
9
  {
10
  }
4
 
5
  class_exists('Twig\Loader\ExistsLoaderInterface');
6
 
7
+ @trigger_error('Using the "Twig_ExistsLoaderInterface" class is deprecated since Twig version 2.7, use "Twig\Loader\ExistsLoaderInterface" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Loader\ExistsLoaderInterface" instead */
11
  class Twig_ExistsLoaderInterface extends ExistsLoaderInterface
12
  {
13
  }
vendor/twig/twig/lib/Twig/ExpressionParser.php CHANGED
@@ -4,7 +4,10 @@ use Twig\ExpressionParser;
4
 
5
  class_exists('Twig\ExpressionParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_ExpressionParser extends ExpressionParser
9
  {
10
  }
4
 
5
  class_exists('Twig\ExpressionParser');
6
 
7
+ @trigger_error('Using the "Twig_ExpressionParser" class is deprecated since Twig version 2.7, use "Twig\ExpressionParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\ExpressionParser" instead */
11
  class Twig_ExpressionParser extends ExpressionParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/Extension.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Extension\AbstractExtension;
4
 
5
  class_exists('Twig\Extension\AbstractExtension');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Extension extends AbstractExtension
9
  {
10
  }
4
 
5
  class_exists('Twig\Extension\AbstractExtension');
6
 
7
+ @trigger_error('Using the "Twig_Extension" class is deprecated since Twig version 2.7, use "Twig\Extension\AbstractExtension" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Extension\AbstractExtension" instead */
11
  class Twig_Extension extends AbstractExtension
12
  {
13
  }
vendor/twig/twig/lib/Twig/Extension/Core.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Extension\CoreExtension;
4
 
5
  class_exists('Twig\Extension\CoreExtension');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Extension_Core extends CoreExtension
9
  {
10
  }
4
 
5
  class_exists('Twig\Extension\CoreExtension');
6
 
7
+ @trigger_error('Using the "Twig_Extension_Core" class is deprecated since Twig version 2.7, use "Twig\Extension\CoreExtension" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Extension\CoreExtension" instead */
11
  class Twig_Extension_Core extends CoreExtension
12
  {
13
  }
vendor/twig/twig/lib/Twig/Extension/Debug.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Extension\DebugExtension;
4
 
5
  class_exists('Twig\Extension\DebugExtension');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Extension_Debug extends DebugExtension
9
  {
10
  }
4
 
5
  class_exists('Twig\Extension\DebugExtension');
6
 
7
+ @trigger_error('Using the "Twig_Extension_Debug" class is deprecated since Twig version 2.7, use "Twig\Extension\DebugExtension" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Extension\DebugExtension" instead */
11
  class Twig_Extension_Debug extends DebugExtension
12
  {
13
  }
vendor/twig/twig/lib/Twig/Extension/Escaper.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Extension\EscaperExtension;
4
 
5
  class_exists('Twig\Extension\EscaperExtension');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Extension_Escaper extends EscaperExtension
9
  {
10
  }
4
 
5
  class_exists('Twig\Extension\EscaperExtension');
6
 
7
+ @trigger_error('Using the "Twig_Extension_Escaper" class is deprecated since Twig version 2.7, use "Twig\Extension\EscaperExtension" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Extension\EscaperExtension" instead */
11
  class Twig_Extension_Escaper extends EscaperExtension
12
  {
13
  }
vendor/twig/twig/lib/Twig/Extension/GlobalsInterface.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Extension\GlobalsInterface;
4
 
5
  class_exists('Twig\Extension\GlobalsInterface');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Extension_GlobalsInterface extends GlobalsInterface
9
  {
10
  }
4
 
5
  class_exists('Twig\Extension\GlobalsInterface');
6
 
7
+ @trigger_error('Using the "Twig_Extension_GlobalsInterface" class is deprecated since Twig version 2.7, use "Twig\Extension\GlobalsInterface" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Extension\GlobalsInterface" instead */
11
  class Twig_Extension_GlobalsInterface extends GlobalsInterface
12
  {
13
  }
vendor/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Extension\InitRuntimeInterface;
4
 
5
  class_exists('Twig\Extension\InitRuntimeInterface');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Extension_InitRuntimeInterface extends InitRuntimeInterface
9
  {
10
  }
4
 
5
  class_exists('Twig\Extension\InitRuntimeInterface');
6
 
7
+ @trigger_error('Using the "Twig_Extension_InitRuntimeInterface" class is deprecated since Twig version 2.7, use "Twig\Extension\InitRuntimeInterface" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Extension\InitRuntimeInterface" instead */
11
  class Twig_Extension_InitRuntimeInterface extends InitRuntimeInterface
12
  {
13
  }
vendor/twig/twig/lib/Twig/Extension/Optimizer.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Extension\OptimizerExtension;
4
 
5
  class_exists('Twig\Extension\OptimizerExtension');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Extension_Optimizer extends OptimizerExtension
9
  {
10
  }
4
 
5
  class_exists('Twig\Extension\OptimizerExtension');
6
 
7
+ @trigger_error('Using the "Twig_Extension_Optimizer" class is deprecated since Twig version 2.7, use "Twig\Extension\OptimizerExtension" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Extension\OptimizerExtension" instead */
11
  class Twig_Extension_Optimizer extends OptimizerExtension
12
  {
13
  }
vendor/twig/twig/lib/Twig/Extension/Profiler.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Extension\ProfilerExtension;
4
 
5
  class_exists('Twig\Extension\ProfilerExtension');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Extension_Profiler extends ProfilerExtension
9
  {
10
  }
4
 
5
  class_exists('Twig\Extension\ProfilerExtension');
6
 
7
+ @trigger_error('Using the "Twig_Extension_Profiler" class is deprecated since Twig version 2.7, use "Twig\Extension\ProfilerExtension" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Extension\ProfilerExtension" instead */
11
  class Twig_Extension_Profiler extends ProfilerExtension
12
  {
13
  }
vendor/twig/twig/lib/Twig/Extension/Sandbox.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Extension\SandboxExtension;
4
 
5
  class_exists('Twig\Extension\SandboxExtension');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Extension_Sandbox extends SandboxExtension
9
  {
10
  }
4
 
5
  class_exists('Twig\Extension\SandboxExtension');
6
 
7
+ @trigger_error('Using the "Twig_Extension_Sandbox" class is deprecated since Twig version 2.7, use "Twig\Extension\SandboxExtension" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Extension\SandboxExtension" instead */
11
  class Twig_Extension_Sandbox extends SandboxExtension
12
  {
13
  }
vendor/twig/twig/lib/Twig/Extension/Staging.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Extension\StagingExtension;
4
 
5
  class_exists('Twig\Extension\StagingExtension');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Extension_Staging extends StagingExtension
9
  {
10
  }
4
 
5
  class_exists('Twig\Extension\StagingExtension');
6
 
7
+ @trigger_error('Using the "Twig_Extension_Staging" class is deprecated since Twig version 2.7, use "Twig\Extension\StagingExtension" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Extension\StagingExtension" instead */
11
  class Twig_Extension_Staging extends StagingExtension
12
  {
13
  }
vendor/twig/twig/lib/Twig/Extension/StringLoader.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Extension\StringLoaderExtension;
4
 
5
  class_exists('Twig\Extension\StringLoaderExtension');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Extension_StringLoader extends StringLoaderExtension
9
  {
10
  }
4
 
5
  class_exists('Twig\Extension\StringLoaderExtension');
6
 
7
+ @trigger_error('Using the "Twig_Extension_StringLoader" class is deprecated since Twig version 2.7, use "Twig\Extension\StringLoaderExtension" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Extension\StringLoaderExtension" instead */
11
  class Twig_Extension_StringLoader extends StringLoaderExtension
12
  {
13
  }
vendor/twig/twig/lib/Twig/ExtensionInterface.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Extension\ExtensionInterface;
4
 
5
  class_exists('Twig\Extension\ExtensionInterface');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_ExtensionInterface extends ExtensionInterface
9
  {
10
  }
4
 
5
  class_exists('Twig\Extension\ExtensionInterface');
6
 
7
+ @trigger_error('Using the "Twig_ExtensionInterface" class is deprecated since Twig version 2.7, use "Twig\Extension\ExtensionInterface" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Extension\ExtensionInterface" instead */
11
  class Twig_ExtensionInterface extends ExtensionInterface
12
  {
13
  }
vendor/twig/twig/lib/Twig/ExtensionSet.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use Twig\ExtensionSet;
4
+
5
+ class_exists('Twig\ExtensionSet');
6
+
7
+ @trigger_error('Using the "Twig_ExtensionSet" class is deprecated since Twig version 2.7, use "Twig\ExtensionSet" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\ExtensionSet" instead */
11
+ class Twig_ExtensionSet extends ExtensionSet
12
+ {
13
+ }
14
+ }
vendor/twig/twig/lib/Twig/FactoryRuntimeLoader.php CHANGED
@@ -4,7 +4,10 @@ use Twig\RuntimeLoader\FactoryRuntimeLoader;
4
 
5
  class_exists('Twig\RuntimeLoader\FactoryRuntimeLoader');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_FactoryRuntimeLoader extends FactoryRuntimeLoader
9
  {
10
  }
4
 
5
  class_exists('Twig\RuntimeLoader\FactoryRuntimeLoader');
6
 
7
+ @trigger_error('Using the "Twig_FactoryRuntimeLoader" class is deprecated since Twig version 2.7, use "Twig\RuntimeLoader\FactoryRuntimeLoader" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\RuntimeLoader\FactoryRuntimeLoader" instead */
11
  class Twig_FactoryRuntimeLoader extends FactoryRuntimeLoader
12
  {
13
  }
vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php CHANGED
@@ -4,7 +4,10 @@ use Twig\FileExtensionEscapingStrategy;
4
 
5
  class_exists('Twig\FileExtensionEscapingStrategy');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_FileExtensionEscapingStrategy extends FileExtensionEscapingStrategy
9
  {
10
  }
4
 
5
  class_exists('Twig\FileExtensionEscapingStrategy');
6
 
7
+ @trigger_error('Using the "Twig_FileExtensionEscapingStrategy" class is deprecated since Twig version 2.7, use "Twig\FileExtensionEscapingStrategy" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\FileExtensionEscapingStrategy" instead */
11
  class Twig_FileExtensionEscapingStrategy extends FileExtensionEscapingStrategy
12
  {
13
  }
vendor/twig/twig/lib/Twig/Filter.php CHANGED
@@ -1,86 +1,14 @@
1
  <?php
2
 
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
 
12
- use Twig\Node\Node;
13
 
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
- /**
17
- * Represents a template filter.
18
- *
19
- * Use \Twig\TwigFilter instead.
20
- *
21
- * @author Fabien Potencier <fabien@symfony.com>
22
- *
23
- * @deprecated since 1.12 (to be removed in 2.0)
24
- */
25
- abstract class Twig_Filter implements Twig_FilterInterface, Twig_FilterCallableInterface
26
- {
27
- protected $options;
28
- protected $arguments = [];
29
-
30
- public function __construct(array $options = [])
31
- {
32
- $this->options = array_merge([
33
- 'needs_environment' => false,
34
- 'needs_context' => false,
35
- 'pre_escape' => null,
36
- 'preserves_safety' => null,
37
- 'callable' => null,
38
- ], $options);
39
- }
40
-
41
- public function setArguments($arguments)
42
- {
43
- $this->arguments = $arguments;
44
- }
45
-
46
- public function getArguments()
47
- {
48
- return $this->arguments;
49
- }
50
-
51
- public function needsEnvironment()
52
- {
53
- return $this->options['needs_environment'];
54
- }
55
-
56
- public function needsContext()
57
- {
58
- return $this->options['needs_context'];
59
- }
60
-
61
- public function getSafe(Node $filterArgs)
62
- {
63
- if (isset($this->options['is_safe'])) {
64
- return $this->options['is_safe'];
65
- }
66
-
67
- if (isset($this->options['is_safe_callback'])) {
68
- return \call_user_func($this->options['is_safe_callback'], $filterArgs);
69
- }
70
- }
71
-
72
- public function getPreservesSafety()
73
- {
74
- return $this->options['preserves_safety'];
75
- }
76
-
77
- public function getPreEscape()
78
- {
79
- return $this->options['pre_escape'];
80
- }
81
-
82
- public function getCallable()
83
  {
84
- return $this->options['callable'];
85
  }
86
  }
1
  <?php
2
 
3
+ use Twig\TwigFilter;
 
 
 
 
 
 
 
4
 
5
+ class_exists('Twig\TwigFilter');
6
 
7
+ @trigger_error('Using the "Twig_Filter" class is deprecated since Twig version 2.7, use "Twig\TwigFilter" instead.', \E_USER_DEPRECATED);
8
 
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TwigFilter" instead */
11
+ class Twig_Filter extends TwigFilter
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  {
 
13
  }
14
  }
vendor/twig/twig/lib/Twig/Filter/Function.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
-
12
- @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);
13
-
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 Twig_Filter
24
- {
25
- protected $function;
26
-
27
- public function __construct($function, array $options = [])
28
- {
29
- $options['callable'] = $function;
30
-
31
- parent::__construct($options);
32
-
33
- $this->function = $function;
34
- }
35
-
36
- public function compile()
37
- {
38
- return $this->function;
39
- }
40
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/Filter/Method.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
-
12
- use Twig\Extension\ExtensionInterface;
13
-
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
- /**
17
- * Represents a method template filter.
18
- *
19
- * Use \Twig\TwigFilter instead.
20
- *
21
- * @author Fabien Potencier <fabien@symfony.com>
22
- *
23
- * @deprecated since 1.12 (to be removed in 2.0)
24
- */
25
- class Twig_Filter_Method extends Twig_Filter
26
- {
27
- protected $extension;
28
- protected $method;
29
-
30
- public function __construct(ExtensionInterface $extension, $method, array $options = [])
31
- {
32
- $options['callable'] = [$extension, $method];
33
-
34
- parent::__construct($options);
35
-
36
- $this->extension = $extension;
37
- $this->method = $method;
38
- }
39
-
40
- public function compile()
41
- {
42
- return sprintf('$this->env->getExtension(\'%s\')->%s', \get_class($this->extension), $this->method);
43
- }
44
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/Filter/Node.php DELETED
@@ -1,42 +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
-
12
- @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);
13
-
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 Twig_Filter
24
- {
25
- protected $class;
26
-
27
- public function __construct($class, array $options = [])
28
- {
29
- parent::__construct($options);
30
-
31
- $this->class = $class;
32
- }
33
-
34
- public function getClass()
35
- {
36
- return $this->class;
37
- }
38
-
39
- public function compile()
40
- {
41
- }
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/FilterCallableInterface.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
-
12
- /**
13
- * Represents a callable template filter.
14
- *
15
- * Use \Twig\TwigFilter instead.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- *
19
- * @deprecated since 1.12 (to be removed in 2.0)
20
- */
21
- interface Twig_FilterCallableInterface
22
- {
23
- public function getCallable();
24
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/FilterInterface.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
-
12
- use Twig\Node\Node;
13
-
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
-
32
- public function needsEnvironment();
33
-
34
- public function needsContext();
35
-
36
- public function getSafe(Node $filterArgs);
37
-
38
- public function getPreservesSafety();
39
-
40
- public function getPreEscape();
41
-
42
- public function setArguments($arguments);
43
-
44
- public function getArguments();
45
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/Function.php CHANGED
@@ -1,76 +1,14 @@
1
  <?php
2
 
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
 
12
- use Twig\Node\Node;
13
 
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
- /**
17
- * Represents a template function.
18
- *
19
- * Use \Twig\TwigFunction instead.
20
- *
21
- * @author Fabien Potencier <fabien@symfony.com>
22
- *
23
- * @deprecated since 1.12 (to be removed in 2.0)
24
- */
25
- abstract class Twig_Function implements Twig_FunctionInterface, Twig_FunctionCallableInterface
26
- {
27
- protected $options;
28
- protected $arguments = [];
29
-
30
- public function __construct(array $options = [])
31
- {
32
- $this->options = array_merge([
33
- 'needs_environment' => false,
34
- 'needs_context' => false,
35
- 'callable' => null,
36
- ], $options);
37
- }
38
-
39
- public function setArguments($arguments)
40
- {
41
- $this->arguments = $arguments;
42
- }
43
-
44
- public function getArguments()
45
- {
46
- return $this->arguments;
47
- }
48
-
49
- public function needsEnvironment()
50
- {
51
- return $this->options['needs_environment'];
52
- }
53
-
54
- public function needsContext()
55
- {
56
- return $this->options['needs_context'];
57
- }
58
-
59
- public function getSafe(Node $functionArgs)
60
- {
61
- if (isset($this->options['is_safe'])) {
62
- return $this->options['is_safe'];
63
- }
64
-
65
- if (isset($this->options['is_safe_callback'])) {
66
- return \call_user_func($this->options['is_safe_callback'], $functionArgs);
67
- }
68
-
69
- return [];
70
- }
71
-
72
- public function getCallable()
73
  {
74
- return $this->options['callable'];
75
  }
76
  }
1
  <?php
2
 
3
+ use Twig\TwigFunction;
 
 
 
 
 
 
 
4
 
5
+ class_exists('Twig\TwigFunction');
6
 
7
+ @trigger_error('Using the "Twig_Function" class is deprecated since Twig version 2.7, use "Twig\TwigFunction" instead.', \E_USER_DEPRECATED);
8
 
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TwigFunction" instead */
11
+ class Twig_Function extends TwigFunction
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  {
 
13
  }
14
  }
vendor/twig/twig/lib/Twig/Function/Function.php DELETED
@@ -1,41 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Arnaud Le Blanc
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
-
13
- @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);
14
-
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 Twig_Function
25
- {
26
- protected $function;
27
-
28
- public function __construct($function, array $options = [])
29
- {
30
- $options['callable'] = $function;
31
-
32
- parent::__construct($options);
33
-
34
- $this->function = $function;
35
- }
36
-
37
- public function compile()
38
- {
39
- return $this->function;
40
- }
41
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/Function/Method.php DELETED
@@ -1,45 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Arnaud Le Blanc
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
-
13
- use Twig\Extension\ExtensionInterface;
14
-
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
- /**
18
- * Represents a method template function.
19
- *
20
- * Use \Twig\TwigFunction instead.
21
- *
22
- * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
23
- *
24
- * @deprecated since 1.12 (to be removed in 2.0)
25
- */
26
- class Twig_Function_Method extends Twig_Function
27
- {
28
- protected $extension;
29
- protected $method;
30
-
31
- public function __construct(ExtensionInterface $extension, $method, array $options = [])
32
- {
33
- $options['callable'] = [$extension, $method];
34
-
35
- parent::__construct($options);
36
-
37
- $this->extension = $extension;
38
- $this->method = $method;
39
- }
40
-
41
- public function compile()
42
- {
43
- return sprintf('$this->env->getExtension(\'%s\')->%s', \get_class($this->extension), $this->method);
44
- }
45
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/Function/Node.php DELETED
@@ -1,42 +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
-
12
- @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);
13
-
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 Twig_Function
24
- {
25
- protected $class;
26
-
27
- public function __construct($class, array $options = [])
28
- {
29
- parent::__construct($options);
30
-
31
- $this->class = $class;
32
- }
33
-
34
- public function getClass()
35
- {
36
- return $this->class;
37
- }
38
-
39
- public function compile()
40
- {
41
- }
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/FunctionCallableInterface.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
-
12
- /**
13
- * Represents a callable template function.
14
- *
15
- * Use \Twig\TwigFunction instead.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- *
19
- * @deprecated since 1.12 (to be removed in 2.0)
20
- */
21
- interface Twig_FunctionCallableInterface
22
- {
23
- public function getCallable();
24
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/FunctionInterface.php DELETED
@@ -1,42 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Arnaud Le Blanc
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
-
13
- use Twig\Node\Node;
14
-
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
-
33
- public function needsEnvironment();
34
-
35
- public function needsContext();
36
-
37
- public function getSafe(Node $filterArgs);
38
-
39
- public function setArguments($arguments);
40
-
41
- public function getArguments();
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/Lexer.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Lexer;
4
 
5
  class_exists('Twig\Lexer');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Lexer extends Lexer
9
  {
10
  }
4
 
5
  class_exists('Twig\Lexer');
6
 
7
+ @trigger_error('Using the "Twig_Lexer" class is deprecated since Twig version 2.7, use "Twig\Lexer" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Lexer" instead */
11
  class Twig_Lexer extends Lexer
12
  {
13
  }
vendor/twig/twig/lib/Twig/LexerInterface.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
-
12
- use Twig\Error\SyntaxError;
13
- use Twig\Source;
14
- use Twig\TokenStream;
15
-
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/Loader/Array.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Loader\ArrayLoader;
4
 
5
  class_exists('Twig\Loader\ArrayLoader');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Loader_Array extends ArrayLoader
9
  {
10
  }
4
 
5
  class_exists('Twig\Loader\ArrayLoader');
6
 
7
+ @trigger_error('Using the "Twig_Loader_Array" class is deprecated since Twig version 2.7, use "Twig\Loader\ArrayLoader" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Loader\ArrayLoader" instead */
11
  class Twig_Loader_Array extends ArrayLoader
12
  {
13
  }
vendor/twig/twig/lib/Twig/Loader/Chain.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Loader\ChainLoader;
4
 
5
  class_exists('Twig\Loader\ChainLoader');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Loader_Chain extends ChainLoader
9
  {
10
  }
4
 
5
  class_exists('Twig\Loader\ChainLoader');
6
 
7
+ @trigger_error('Using the "Twig_Loader_Chain" class is deprecated since Twig version 2.7, use "Twig\Loader\ChainLoader" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Loader\ChainLoader" instead */
11
  class Twig_Loader_Chain extends ChainLoader
12
  {
13
  }
vendor/twig/twig/lib/Twig/Loader/Filesystem.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Loader\FilesystemLoader;
4
 
5
  class_exists('Twig\Loader\FilesystemLoader');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Loader_Filesystem extends FilesystemLoader
9
  {
10
  }
4
 
5
  class_exists('Twig\Loader\FilesystemLoader');
6
 
7
+ @trigger_error('Using the "Twig_Loader_Filesystem" class is deprecated since Twig version 2.7, use "Twig\Loader\FilesystemLoader" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Loader\FilesystemLoader" instead */
11
  class Twig_Loader_Filesystem extends FilesystemLoader
12
  {
13
  }
vendor/twig/twig/lib/Twig/Loader/String.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
-
12
- use Twig\Loader\ExistsLoaderInterface;
13
- use Twig\Loader\LoaderInterface;
14
- use Twig\Loader\SourceContextLoaderInterface;
15
- use Twig\Source;
16
-
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
- /**
20
- * Loads a template from a string.
21
- *
22
- * This loader should NEVER be used. It only exists for Twig internal purposes.
23
- *
24
- * When using this loader with a cache mechanism, you should know that a new cache
25
- * key is generated each time a template content "changes" (the cache key being the
26
- * source code of the template). If you don't want to see your cache grows out of
27
- * control, you need to take care of clearing the old cache file by yourself.
28
- *
29
- * @deprecated since 1.18.1 (to be removed in 2.0)
30
- *
31
- * @internal
32
- *
33
- * @author Fabien Potencier <fabien@symfony.com>
34
- */
35
- class Twig_Loader_String implements LoaderInterface, ExistsLoaderInterface, SourceContextLoaderInterface
36
- {
37
- public function getSource($name)
38
- {
39
- @trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', \get_class($this)), E_USER_DEPRECATED);
40
-
41
- return $name;
42
- }
43
-
44
- public function getSourceContext($name)
45
- {
46
- return new Source($name, $name);
47
- }
48
-
49
- public function exists($name)
50
- {
51
- return true;
52
- }
53
-
54
- public function getCacheKey($name)
55
- {
56
- return $name;
57
- }
58
-
59
- public function isFresh($name, $time)
60
- {
61
- return true;
62
- }
63
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/LoaderInterface.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Loader\LoaderInterface;
4
 
5
  class_exists('Twig\Loader\LoaderInterface');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_LoaderInterface extends LoaderInterface
9
  {
10
  }
4
 
5
  class_exists('Twig\Loader\LoaderInterface');
6
 
7
+ @trigger_error('Using the "Twig_LoaderInterface" class is deprecated since Twig version 2.7, use "Twig\Loader\LoaderInterface" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Loader\LoaderInterface" instead */
11
  class Twig_LoaderInterface extends LoaderInterface
12
  {
13
  }
vendor/twig/twig/lib/Twig/Markup.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Markup;
4
 
5
  class_exists('Twig\Markup');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Markup extends Markup
9
  {
10
  }
4
 
5
  class_exists('Twig\Markup');
6
 
7
+ @trigger_error('Using the "Twig_Markup" class is deprecated since Twig version 2.7, use "Twig\Markup" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Markup" instead */
11
  class Twig_Markup extends Markup
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Node;
4
 
5
  class_exists('Twig\Node\Node');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node extends Node
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Node');
6
 
7
+ @trigger_error('Using the "Twig_Node" class is deprecated since Twig version 2.7, use "Twig\Node\Node" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Node" instead */
11
  class Twig_Node extends Node
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/AutoEscape.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\AutoEscapeNode;
4
 
5
  class_exists('Twig\Node\AutoEscapeNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_AutoEscape extends AutoEscapeNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\AutoEscapeNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_AutoEscape" class is deprecated since Twig version 2.7, use "Twig\Node\AutoEscapeNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\AutoEscapeNode" instead */
11
  class Twig_Node_AutoEscape extends AutoEscapeNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Block.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\BlockNode;
4
 
5
  class_exists('Twig\Node\BlockNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Block extends BlockNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\BlockNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_Block" class is deprecated since Twig version 2.7, use "Twig\Node\BlockNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\BlockNode" instead */
11
  class Twig_Node_Block extends BlockNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/BlockReference.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\BlockReferenceNode;
4
 
5
  class_exists('Twig\Node\BlockReferenceNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_BlockReference extends BlockReferenceNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\BlockReferenceNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_BlockReference" class is deprecated since Twig version 2.7, use "Twig\Node\BlockReferenceNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\BlockReferenceNode" instead */
11
  class Twig_Node_BlockReference extends BlockReferenceNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Body.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\BodyNode;
4
 
5
  class_exists('Twig\Node\BodyNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Body extends BodyNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\BodyNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_Body" class is deprecated since Twig version 2.7, use "Twig\Node\BodyNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\BodyNode" instead */
11
  class Twig_Node_Body extends BodyNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/CheckSecurity.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\CheckSecurityNode;
4
 
5
  class_exists('Twig\Node\CheckSecurityNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_CheckSecurity extends CheckSecurityNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\CheckSecurityNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_CheckSecurity" class is deprecated since Twig version 2.7, use "Twig\Node\CheckSecurityNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\CheckSecurityNode" instead */
11
  class Twig_Node_CheckSecurity extends CheckSecurityNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Deprecated.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\DeprecatedNode;
4
 
5
  class_exists('Twig\Node\DeprecatedNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Deprecated extends DeprecatedNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\DeprecatedNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_Deprecated" class is deprecated since Twig version 2.7, use "Twig\Node\DeprecatedNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\DeprecatedNode" instead */
11
  class Twig_Node_Deprecated extends DeprecatedNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Do.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\DoNode;
4
 
5
  class_exists('Twig\Node\DoNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Do extends DoNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\DoNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_Do" class is deprecated since Twig version 2.7, use "Twig\Node\DoNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\DoNode" instead */
11
  class Twig_Node_Do extends DoNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Embed.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\EmbedNode;
4
 
5
  class_exists('Twig\Node\EmbedNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Embed extends EmbedNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\EmbedNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_Embed" class is deprecated since Twig version 2.7, use "Twig\Node\EmbedNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\EmbedNode" instead */
11
  class Twig_Node_Embed extends EmbedNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\AbstractExpression;
4
 
5
  class_exists('Twig\Node\Expression\AbstractExpression');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression extends AbstractExpression
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\AbstractExpression');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\AbstractExpression" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\AbstractExpression" instead */
11
  class Twig_Node_Expression extends AbstractExpression
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Array.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\ArrayExpression;
4
 
5
  class_exists('Twig\Node\Expression\ArrayExpression');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Array extends ArrayExpression
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\ArrayExpression');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Array" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\ArrayExpression" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\ArrayExpression" instead */
11
  class Twig_Node_Expression_Array extends ArrayExpression
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\AssignNameExpression;
4
 
5
  class_exists('Twig\Node\Expression\AssignNameExpression');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_AssignName extends AssignNameExpression
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\AssignNameExpression');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_AssignName" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\AssignNameExpression" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\AssignNameExpression" instead */
11
  class Twig_Node_Expression_AssignName extends AssignNameExpression
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\AbstractBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\AbstractBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary extends AbstractBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\AbstractBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\AbstractBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\AbstractBinary" instead */
11
  class Twig_Node_Expression_Binary extends AbstractBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\AddBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\AddBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_Add extends AddBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\AddBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_Add" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\AddBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\AddBinary" instead */
11
  class Twig_Node_Expression_Binary_Add extends AddBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\AndBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\AndBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_And extends AndBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\AndBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_And" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\AndBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\AndBinary" instead */
11
  class Twig_Node_Expression_Binary_And extends AndBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\BitwiseAndBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\BitwiseAndBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_BitwiseAnd extends BitwiseAndBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\BitwiseAndBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_BitwiseAnd" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\BitwiseAndBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\BitwiseAndBinary" instead */
11
  class Twig_Node_Expression_Binary_BitwiseAnd extends BitwiseAndBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\BitwiseOrBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\BitwiseOrBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_BitwiseOr extends BitwiseOrBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\BitwiseOrBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_BitwiseOr" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\BitwiseOrBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\BitwiseOrBinary" instead */
11
  class Twig_Node_Expression_Binary_BitwiseOr extends BitwiseOrBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\BitwiseXorBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\BitwiseXorBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_BitwiseXor extends BitwiseXorBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\BitwiseXorBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_BitwiseXor" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\BitwiseXorBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\BitwiseXorBinary" instead */
11
  class Twig_Node_Expression_Binary_BitwiseXor extends BitwiseXorBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\ConcatBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\ConcatBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_Concat extends ConcatBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\ConcatBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_Concat" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\ConcatBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\ConcatBinary" instead */
11
  class Twig_Node_Expression_Binary_Concat extends ConcatBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\DivBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\DivBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_Div extends DivBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\DivBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_Div" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\DivBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\DivBinary" instead */
11
  class Twig_Node_Expression_Binary_Div extends DivBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\EndsWithBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\EndsWithBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_EndsWith extends EndsWithBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\EndsWithBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_EndsWith" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\EndsWithBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\EndsWithBinary" instead */
11
  class Twig_Node_Expression_Binary_EndsWith extends EndsWithBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\EqualBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\EqualBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_Equal extends EqualBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\EqualBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_Equal" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\EqualBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\EqualBinary" instead */
11
  class Twig_Node_Expression_Binary_Equal extends EqualBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\FloorDivBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\FloorDivBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_FloorDiv extends FloorDivBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\FloorDivBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_FloorDiv" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\FloorDivBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\FloorDivBinary" instead */
11
  class Twig_Node_Expression_Binary_FloorDiv extends FloorDivBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\GreaterBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\GreaterBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_Greater extends GreaterBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\GreaterBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_Greater" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\GreaterBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\GreaterBinary" instead */
11
  class Twig_Node_Expression_Binary_Greater extends GreaterBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\GreaterEqualBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\GreaterEqualBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_GreaterEqual extends GreaterEqualBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\GreaterEqualBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_GreaterEqual" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\GreaterEqualBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\GreaterEqualBinary" instead */
11
  class Twig_Node_Expression_Binary_GreaterEqual extends GreaterEqualBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\InBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\InBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_In extends InBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\InBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_In" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\InBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\InBinary" instead */
11
  class Twig_Node_Expression_Binary_In extends InBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\LessBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\LessBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_Less extends LessBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\LessBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_Less" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\LessBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\LessBinary" instead */
11
  class Twig_Node_Expression_Binary_Less extends LessBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\LessEqualBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\LessEqualBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_LessEqual extends LessEqualBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\LessEqualBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_LessEqual" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\LessEqualBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\LessEqualBinary" instead */
11
  class Twig_Node_Expression_Binary_LessEqual extends LessEqualBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\MatchesBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\MatchesBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_Matches extends MatchesBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\MatchesBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_Matches" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\MatchesBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\MatchesBinary" instead */
11
  class Twig_Node_Expression_Binary_Matches extends MatchesBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\ModBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\ModBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_Mod extends ModBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\ModBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_Mod" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\ModBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\ModBinary" instead */
11
  class Twig_Node_Expression_Binary_Mod extends ModBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\MulBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\MulBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_Mul extends MulBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\MulBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_Mul" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\MulBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\MulBinary" instead */
11
  class Twig_Node_Expression_Binary_Mul extends MulBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\NotEqualBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\NotEqualBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_NotEqual extends NotEqualBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\NotEqualBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_NotEqual" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\NotEqualBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\NotEqualBinary" instead */
11
  class Twig_Node_Expression_Binary_NotEqual extends NotEqualBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\NotInBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\NotInBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_NotIn extends NotInBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\NotInBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_NotIn" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\NotInBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\NotInBinary" instead */
11
  class Twig_Node_Expression_Binary_NotIn extends NotInBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\OrBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\OrBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_Or extends OrBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\OrBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_Or" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\OrBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\OrBinary" instead */
11
  class Twig_Node_Expression_Binary_Or extends OrBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\PowerBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\PowerBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_Power extends PowerBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\PowerBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_Power" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\PowerBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\PowerBinary" instead */
11
  class Twig_Node_Expression_Binary_Power extends PowerBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\RangeBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\RangeBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_Range extends RangeBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\RangeBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_Range" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\RangeBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\RangeBinary" instead */
11
  class Twig_Node_Expression_Binary_Range extends RangeBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\StartsWithBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\StartsWithBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_StartsWith extends StartsWithBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\StartsWithBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_StartsWith" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\StartsWithBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\StartsWithBinary" instead */
11
  class Twig_Node_Expression_Binary_StartsWith extends StartsWithBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Binary\SubBinary;
4
 
5
  class_exists('Twig\Node\Expression\Binary\SubBinary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Binary_Sub extends SubBinary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Binary\SubBinary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Binary_Sub" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Binary\SubBinary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Binary\SubBinary" instead */
11
  class Twig_Node_Expression_Binary_Sub extends SubBinary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\BlockReferenceExpression;
4
 
5
  class_exists('Twig\Node\Expression\BlockReferenceExpression');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_BlockReference extends BlockReferenceExpression
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\BlockReferenceExpression');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_BlockReference" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\BlockReferenceExpression" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\BlockReferenceExpression" instead */
11
  class Twig_Node_Expression_BlockReference extends BlockReferenceExpression
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Call.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\CallExpression;
4
 
5
  class_exists('Twig\Node\Expression\CallExpression');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Call extends CallExpression
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\CallExpression');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Call" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\CallExpression" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\CallExpression" instead */
11
  class Twig_Node_Expression_Call extends CallExpression
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\ConditionalExpression;
4
 
5
  class_exists('Twig\Node\Expression\ConditionalExpression');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Conditional extends ConditionalExpression
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\ConditionalExpression');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Conditional" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\ConditionalExpression" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\ConditionalExpression" instead */
11
  class Twig_Node_Expression_Conditional extends ConditionalExpression
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Constant.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\ConstantExpression;
4
 
5
  class_exists('Twig\Node\Expression\ConstantExpression');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Constant extends ConstantExpression
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\ConstantExpression');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Constant" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\ConstantExpression" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\ConstantExpression" instead */
11
  class Twig_Node_Expression_Constant extends ConstantExpression
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.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
-
12
- use Twig\Compiler;
13
- use Twig\Node\Expression\AbstractExpression;
14
-
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
- /**
18
- * Represents an extension call node.
19
- *
20
- * @author Fabien Potencier <fabien@symfony.com>
21
- *
22
- * @deprecated since 1.23 and will be removed in 2.0.
23
- */
24
- class Twig_Node_Expression_ExtensionReference extends AbstractExpression
25
- {
26
- public function __construct($name, $lineno, $tag = null)
27
- {
28
- parent::__construct([], ['name' => $name], $lineno, $tag);
29
- }
30
-
31
- public function compile(Compiler $compiler)
32
- {
33
- $compiler->raw(sprintf("\$this->env->getExtension('%s')", $this->getAttribute('name')));
34
- }
35
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/Node/Expression/Filter.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\FilterExpression;
4
 
5
  class_exists('Twig\Node\Expression\FilterExpression');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Filter extends FilterExpression
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\FilterExpression');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Filter" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\FilterExpression" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\FilterExpression" instead */
11
  class Twig_Node_Expression_Filter extends FilterExpression
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Filter\DefaultFilter;
4
 
5
  class_exists('Twig\Node\Expression\Filter\DefaultFilter');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Filter_Default extends DefaultFilter
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Filter\DefaultFilter');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Filter_Default" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Filter\DefaultFilter" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Filter\DefaultFilter" instead */
11
  class Twig_Node_Expression_Filter_Default extends DefaultFilter
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Function.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\FunctionExpression;
4
 
5
  class_exists('Twig\Node\Expression\FunctionExpression');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Function extends FunctionExpression
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\FunctionExpression');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Function" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\FunctionExpression" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\FunctionExpression" instead */
11
  class Twig_Node_Expression_Function extends FunctionExpression
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\GetAttrExpression;
4
 
5
  class_exists('Twig\Node\Expression\GetAttrExpression');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_GetAttr extends GetAttrExpression
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\GetAttrExpression');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_GetAttr" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\GetAttrExpression" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\GetAttrExpression" instead */
11
  class Twig_Node_Expression_GetAttr extends GetAttrExpression
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\MethodCallExpression;
4
 
5
  class_exists('Twig\Node\Expression\MethodCallExpression');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_MethodCall extends MethodCallExpression
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\MethodCallExpression');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_MethodCall" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\MethodCallExpression" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\MethodCallExpression" instead */
11
  class Twig_Node_Expression_MethodCall extends MethodCallExpression
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Name.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\NameExpression;
4
 
5
  class_exists('Twig\Node\Expression\NameExpression');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Name extends NameExpression
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\NameExpression');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Name" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\NameExpression" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\NameExpression" instead */
11
  class Twig_Node_Expression_Name extends NameExpression
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\NullCoalesceExpression;
4
 
5
  class_exists('Twig\Node\Expression\NullCoalesceExpression');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_NullCoalesce extends NullCoalesceExpression
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\NullCoalesceExpression');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_NullCoalesce" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\NullCoalesceExpression" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\NullCoalesceExpression" instead */
11
  class Twig_Node_Expression_NullCoalesce extends NullCoalesceExpression
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Parent.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\ParentExpression;
4
 
5
  class_exists('Twig\Node\Expression\ParentExpression');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Parent extends ParentExpression
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\ParentExpression');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Parent" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\ParentExpression" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\ParentExpression" instead */
11
  class Twig_Node_Expression_Parent extends ParentExpression
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/TempName.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\TempNameExpression;
4
 
5
  class_exists('Twig\Node\Expression\TempNameExpression');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_TempName extends TempNameExpression
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\TempNameExpression');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_TempName" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\TempNameExpression" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\TempNameExpression" instead */
11
  class Twig_Node_Expression_TempName extends TempNameExpression
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Test.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\TestExpression;
4
 
5
  class_exists('Twig\Node\Expression\TestExpression');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Test extends TestExpression
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\TestExpression');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Test" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\TestExpression" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\TestExpression" instead */
11
  class Twig_Node_Expression_Test extends TestExpression
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Test\ConstantTest;
4
 
5
  class_exists('Twig\Node\Expression\Test\ConstantTest');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Test_Constant extends ConstantTest
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Test\ConstantTest');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Test_Constant" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Test\ConstantTest" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Test\ConstantTest" instead */
11
  class Twig_Node_Expression_Test_Constant extends ConstantTest
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Test\DefinedTest;
4
 
5
  class_exists('Twig\Node\Expression\Test\DefinedTest');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Test_Defined extends DefinedTest
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Test\DefinedTest');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Test_Defined" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Test\DefinedTest" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Test\DefinedTest" instead */
11
  class Twig_Node_Expression_Test_Defined extends DefinedTest
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Test\DivisiblebyTest;
4
 
5
  class_exists('Twig\Node\Expression\Test\DivisiblebyTest');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Test_Divisibleby extends DivisiblebyTest
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Test\DivisiblebyTest');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Test_Divisibleby" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Test\DivisiblebyTest" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Test\DivisiblebyTest" instead */
11
  class Twig_Node_Expression_Test_Divisibleby extends DivisiblebyTest
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Test\EvenTest;
4
 
5
  class_exists('Twig\Node\Expression\Test\EvenTest');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Test_Even extends EvenTest
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Test\EvenTest');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Test_Even" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Test\EvenTest" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Test\EvenTest" instead */
11
  class Twig_Node_Expression_Test_Even extends EvenTest
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Test\NullTest;
4
 
5
  class_exists('Twig\Node\Expression\Test\NullTest');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Test_Null extends NullTest
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Test\NullTest');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Test_Null" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Test\NullTest" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Test\NullTest" instead */
11
  class Twig_Node_Expression_Test_Null extends NullTest
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Test\OddTest;
4
 
5
  class_exists('Twig\Node\Expression\Test\OddTest');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Test_Odd extends OddTest
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Test\OddTest');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Test_Odd" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Test\OddTest" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Test\OddTest" instead */
11
  class Twig_Node_Expression_Test_Odd extends OddTest
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Test\SameasTest;
4
 
5
  class_exists('Twig\Node\Expression\Test\SameasTest');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Test_Sameas extends SameasTest
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Test\SameasTest');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Test_Sameas" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Test\SameasTest" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Test\SameasTest" instead */
11
  class Twig_Node_Expression_Test_Sameas extends SameasTest
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Unary.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Unary\AbstractUnary;
4
 
5
  class_exists('Twig\Node\Expression\Unary\AbstractUnary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Unary extends AbstractUnary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Unary\AbstractUnary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Unary" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Unary\AbstractUnary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Unary\AbstractUnary" instead */
11
  class Twig_Node_Expression_Unary extends AbstractUnary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Unary\NegUnary;
4
 
5
  class_exists('Twig\Node\Expression\Unary\NegUnary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Unary_Neg extends NegUnary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Unary\NegUnary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Unary_Neg" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Unary\NegUnary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Unary\NegUnary" instead */
11
  class Twig_Node_Expression_Unary_Neg extends NegUnary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Unary\NotUnary;
4
 
5
  class_exists('Twig\Node\Expression\Unary\NotUnary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Unary_Not extends NotUnary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Unary\NotUnary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Unary_Not" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Unary\NotUnary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Unary\NotUnary" instead */
11
  class Twig_Node_Expression_Unary_Not extends NotUnary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\Expression\Unary\PosUnary;
4
 
5
  class_exists('Twig\Node\Expression\Unary\PosUnary');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Expression_Unary_Pos extends PosUnary
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\Expression\Unary\PosUnary');
6
 
7
+ @trigger_error('Using the "Twig_Node_Expression_Unary_Pos" class is deprecated since Twig version 2.7, use "Twig\Node\Expression\Unary\PosUnary" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\Expression\Unary\PosUnary" instead */
11
  class Twig_Node_Expression_Unary_Pos extends PosUnary
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Flush.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\FlushNode;
4
 
5
  class_exists('Twig\Node\FlushNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Flush extends FlushNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\FlushNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_Flush" class is deprecated since Twig version 2.7, use "Twig\Node\FlushNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\FlushNode" instead */
11
  class Twig_Node_Flush extends FlushNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/For.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\ForNode;
4
 
5
  class_exists('Twig\Node\ForNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_For extends ForNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\ForNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_For" class is deprecated since Twig version 2.7, use "Twig\Node\ForNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\ForNode" instead */
11
  class Twig_Node_For extends ForNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/ForLoop.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\ForLoopNode;
4
 
5
  class_exists('Twig\Node\ForLoopNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_ForLoop extends ForLoopNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\ForLoopNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_ForLoop" class is deprecated since Twig version 2.7, use "Twig\Node\ForLoopNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\ForLoopNode" instead */
11
  class Twig_Node_ForLoop extends ForLoopNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/If.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\IfNode;
4
 
5
  class_exists('Twig\Node\IfNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_If extends IfNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\IfNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_If" class is deprecated since Twig version 2.7, use "Twig\Node\IfNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\IfNode" instead */
11
  class Twig_Node_If extends IfNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Import.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\ImportNode;
4
 
5
  class_exists('Twig\Node\ImportNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Import extends ImportNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\ImportNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_Import" class is deprecated since Twig version 2.7, use "Twig\Node\ImportNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\ImportNode" instead */
11
  class Twig_Node_Import extends ImportNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Include.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\IncludeNode;
4
 
5
  class_exists('Twig\Node\IncludeNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Include extends IncludeNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\IncludeNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_Include" class is deprecated since Twig version 2.7, use "Twig\Node\IncludeNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\IncludeNode" instead */
11
  class Twig_Node_Include extends IncludeNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Macro.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\MacroNode;
4
 
5
  class_exists('Twig\Node\MacroNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Macro extends MacroNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\MacroNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_Macro" class is deprecated since Twig version 2.7, use "Twig\Node\MacroNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\MacroNode" instead */
11
  class Twig_Node_Macro extends MacroNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Module.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\ModuleNode;
4
 
5
  class_exists('Twig\Node\ModuleNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Module extends ModuleNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\ModuleNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_Module" class is deprecated since Twig version 2.7, use "Twig\Node\ModuleNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\ModuleNode" instead */
11
  class Twig_Node_Module extends ModuleNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Print.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\PrintNode;
4
 
5
  class_exists('Twig\Node\PrintNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Print extends PrintNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\PrintNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_Print" class is deprecated since Twig version 2.7, use "Twig\Node\PrintNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\PrintNode" instead */
11
  class Twig_Node_Print extends PrintNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Sandbox.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\SandboxNode;
4
 
5
  class_exists('Twig\Node\SandboxNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Sandbox extends SandboxNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\SandboxNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_Sandbox" class is deprecated since Twig version 2.7, use "Twig\Node\SandboxNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\SandboxNode" instead */
11
  class Twig_Node_Sandbox extends SandboxNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\SandboxedPrintNode;
4
 
5
  class_exists('Twig\Node\SandboxedPrintNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_SandboxedPrint extends SandboxedPrintNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\SandboxedPrintNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_SandboxedPrint" class is deprecated since Twig version 2.7, use "Twig\Node\SandboxedPrintNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\SandboxedPrintNode" instead */
11
  class Twig_Node_SandboxedPrint extends SandboxedPrintNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Set.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\SetNode;
4
 
5
  class_exists('Twig\Node\SetNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Set extends SetNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\SetNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_Set" class is deprecated since Twig version 2.7, use "Twig\Node\SetNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\SetNode" instead */
11
  class Twig_Node_Set extends SetNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/SetTemp.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- use Twig\Node\SetTempNode;
4
-
5
- class_exists('Twig\Node\SetTempNode');
6
-
7
- if (\false) {
8
- class Twig_Node_SetTemp extends SetTempNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/Node/Spaceless.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\SpacelessNode;
4
 
5
  class_exists('Twig\Node\SpacelessNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Spaceless extends SpacelessNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\SpacelessNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_Spaceless" class is deprecated since Twig version 2.7, use "Twig\Node\SpacelessNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\SpacelessNode" instead */
11
  class Twig_Node_Spaceless extends SpacelessNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/Text.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\TextNode;
4
 
5
  class_exists('Twig\Node\TextNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_Text extends TextNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\TextNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_Text" class is deprecated since Twig version 2.7, use "Twig\Node\TextNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\TextNode" instead */
11
  class Twig_Node_Text extends TextNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Node/With.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\WithNode;
4
 
5
  class_exists('Twig\Node\WithNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Node_With extends WithNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\WithNode');
6
 
7
+ @trigger_error('Using the "Twig_Node_With" class is deprecated since Twig version 2.7, use "Twig\Node\WithNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\WithNode" instead */
11
  class Twig_Node_With extends WithNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/NodeCaptureInterface.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\NodeCaptureInterface;
4
 
5
  class_exists('Twig\Node\NodeCaptureInterface');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_NodeCaptureInterface extends NodeCaptureInterface
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\NodeCaptureInterface');
6
 
7
+ @trigger_error('Using the "Twig_NodeCaptureInterface" class is deprecated since Twig version 2.7, use "Twig\Node\NodeCaptureInterface" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\NodeCaptureInterface" instead */
11
  class Twig_NodeCaptureInterface extends NodeCaptureInterface
12
  {
13
  }
vendor/twig/twig/lib/Twig/NodeInterface.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
-
12
- use Twig\Compiler;
13
-
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(Compiler $compiler);
27
-
28
- /**
29
- * @deprecated since 1.27 (to be removed in 2.0)
30
- */
31
- public function getLine();
32
-
33
- public function getNodeTag();
34
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/NodeOutputInterface.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Node\NodeOutputInterface;
4
 
5
  class_exists('Twig\Node\NodeOutputInterface');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_NodeOutputInterface extends NodeOutputInterface
9
  {
10
  }
4
 
5
  class_exists('Twig\Node\NodeOutputInterface');
6
 
7
+ @trigger_error('Using the "Twig_NodeOutputInterface" class is deprecated since Twig version 2.7, use "Twig\Node\NodeOutputInterface" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Node\NodeOutputInterface" instead */
11
  class Twig_NodeOutputInterface extends NodeOutputInterface
12
  {
13
  }
vendor/twig/twig/lib/Twig/NodeTraverser.php CHANGED
@@ -4,7 +4,10 @@ use Twig\NodeTraverser;
4
 
5
  class_exists('Twig\NodeTraverser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_NodeTraverser extends NodeTraverser
9
  {
10
  }
4
 
5
  class_exists('Twig\NodeTraverser');
6
 
7
+ @trigger_error('Using the "Twig_NodeTraverser" class is deprecated since Twig version 2.7, use "Twig\NodeTraverser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\NodeTraverser" instead */
11
  class Twig_NodeTraverser extends NodeTraverser
12
  {
13
  }
vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php CHANGED
@@ -4,7 +4,10 @@ use Twig\NodeVisitor\EscaperNodeVisitor;
4
 
5
  class_exists('Twig\NodeVisitor\EscaperNodeVisitor');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_NodeVisitor_Escaper extends EscaperNodeVisitor
9
  {
10
  }
4
 
5
  class_exists('Twig\NodeVisitor\EscaperNodeVisitor');
6
 
7
+ @trigger_error('Using the "Twig_NodeVisitor_Escaper" class is deprecated since Twig version 2.7, use "Twig\NodeVisitor\EscaperNodeVisitor" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\NodeVisitor\EscaperNodeVisitor" instead */
11
  class Twig_NodeVisitor_Escaper extends EscaperNodeVisitor
12
  {
13
  }
vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php CHANGED
@@ -4,7 +4,10 @@ use Twig\NodeVisitor\OptimizerNodeVisitor;
4
 
5
  class_exists('Twig\NodeVisitor\OptimizerNodeVisitor');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_NodeVisitor_Optimizer extends OptimizerNodeVisitor
9
  {
10
  }
4
 
5
  class_exists('Twig\NodeVisitor\OptimizerNodeVisitor');
6
 
7
+ @trigger_error('Using the "Twig_NodeVisitor_Optimizer" class is deprecated since Twig version 2.7, use "Twig\NodeVisitor\OptimizerNodeVisitor" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\NodeVisitor\OptimizerNodeVisitor" instead */
11
  class Twig_NodeVisitor_Optimizer extends OptimizerNodeVisitor
12
  {
13
  }
vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php CHANGED
@@ -4,7 +4,10 @@ use Twig\NodeVisitor\SafeAnalysisNodeVisitor;
4
 
5
  class_exists('Twig\NodeVisitor\SafeAnalysisNodeVisitor');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_NodeVisitor_SafeAnalysis extends SafeAnalysisNodeVisitor
9
  {
10
  }
4
 
5
  class_exists('Twig\NodeVisitor\SafeAnalysisNodeVisitor');
6
 
7
+ @trigger_error('Using the "Twig_NodeVisitor_SafeAnalysis" class is deprecated since Twig version 2.7, use "Twig\NodeVisitor\SafeAnalysisNodeVisitor" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\NodeVisitor\SafeAnalysisNodeVisitor" instead */
11
  class Twig_NodeVisitor_SafeAnalysis extends SafeAnalysisNodeVisitor
12
  {
13
  }
vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php CHANGED
@@ -4,7 +4,10 @@ use Twig\NodeVisitor\SandboxNodeVisitor;
4
 
5
  class_exists('Twig\NodeVisitor\SandboxNodeVisitor');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_NodeVisitor_Sandbox extends SandboxNodeVisitor
9
  {
10
  }
4
 
5
  class_exists('Twig\NodeVisitor\SandboxNodeVisitor');
6
 
7
+ @trigger_error('Using the "Twig_NodeVisitor_Sandbox" class is deprecated since Twig version 2.7, use "Twig\NodeVisitor\SandboxNodeVisitor" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\NodeVisitor\SandboxNodeVisitor" instead */
11
  class Twig_NodeVisitor_Sandbox extends SandboxNodeVisitor
12
  {
13
  }
vendor/twig/twig/lib/Twig/NodeVisitorInterface.php CHANGED
@@ -4,7 +4,10 @@ use Twig\NodeVisitor\NodeVisitorInterface;
4
 
5
  class_exists('Twig\NodeVisitor\NodeVisitorInterface');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_NodeVisitorInterface extends NodeVisitorInterface
9
  {
10
  }
4
 
5
  class_exists('Twig\NodeVisitor\NodeVisitorInterface');
6
 
7
+ @trigger_error('Using the "Twig_NodeVisitorInterface" class is deprecated since Twig version 2.7, use "Twig\NodeVisitor\NodeVisitorInterface" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\NodeVisitor\NodeVisitorInterface" instead */
11
  class Twig_NodeVisitorInterface extends NodeVisitorInterface
12
  {
13
  }
vendor/twig/twig/lib/Twig/Parser.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Parser;
4
 
5
  class_exists('Twig\Parser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Parser extends Parser
9
  {
10
  }
4
 
5
  class_exists('Twig\Parser');
6
 
7
+ @trigger_error('Using the "Twig_Parser" class is deprecated since Twig version 2.7, use "Twig\Parser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Parser" instead */
11
  class Twig_Parser extends Parser
12
  {
13
  }
vendor/twig/twig/lib/Twig/ParserInterface.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
-
12
- use Twig\Error\SyntaxError;
13
- use Twig\Node\ModuleNode;
14
- use Twig\TokenStream;
15
-
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(TokenStream $stream);
33
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/Profiler/Dumper/Base.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Profiler\Dumper\BaseDumper;
4
 
5
  class_exists('Twig\Profiler\Dumper\BaseDumper');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Profiler_Dumper_Base extends BaseDumper
9
  {
10
  }
4
 
5
  class_exists('Twig\Profiler\Dumper\BaseDumper');
6
 
7
+ @trigger_error('Using the "Twig_Profiler_Dumper_Base" class is deprecated since Twig version 2.7, use "Twig\Profiler\Dumper\BaseDumper" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Profiler\Dumper\BaseDumper" instead */
11
  class Twig_Profiler_Dumper_Base extends BaseDumper
12
  {
13
  }
vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Profiler\Dumper\BlackfireDumper;
4
 
5
  class_exists('Twig\Profiler\Dumper\BlackfireDumper');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Profiler_Dumper_Blackfire extends BlackfireDumper
9
  {
10
  }
4
 
5
  class_exists('Twig\Profiler\Dumper\BlackfireDumper');
6
 
7
+ @trigger_error('Using the "Twig_Profiler_Dumper_Blackfire" class is deprecated since Twig version 2.7, use "Twig\Profiler\Dumper\BlackfireDumper" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Profiler\Dumper\BlackfireDumper" instead */
11
  class Twig_Profiler_Dumper_Blackfire extends BlackfireDumper
12
  {
13
  }
vendor/twig/twig/lib/Twig/Profiler/Dumper/Html.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Profiler\Dumper\HtmlDumper;
4
 
5
  class_exists('Twig\Profiler\Dumper\HtmlDumper');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Profiler_Dumper_Html extends HtmlDumper
9
  {
10
  }
4
 
5
  class_exists('Twig\Profiler\Dumper\HtmlDumper');
6
 
7
+ @trigger_error('Using the "Twig_Profiler_Dumper_Html" class is deprecated since Twig version 2.7, use "Twig\Profiler\Dumper\HtmlDumper" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Profiler\Dumper\HtmlDumper" instead */
11
  class Twig_Profiler_Dumper_Html extends HtmlDumper
12
  {
13
  }
vendor/twig/twig/lib/Twig/Profiler/Dumper/Text.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Profiler\Dumper\TextDumper;
4
 
5
  class_exists('Twig\Profiler\Dumper\TextDumper');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Profiler_Dumper_Text extends TextDumper
9
  {
10
  }
4
 
5
  class_exists('Twig\Profiler\Dumper\TextDumper');
6
 
7
+ @trigger_error('Using the "Twig_Profiler_Dumper_Text" class is deprecated since Twig version 2.7, use "Twig\Profiler\Dumper\TextDumper" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Profiler\Dumper\TextDumper" instead */
11
  class Twig_Profiler_Dumper_Text extends TextDumper
12
  {
13
  }
vendor/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Profiler\Node\EnterProfileNode;
4
 
5
  class_exists('Twig\Profiler\Node\EnterProfileNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Profiler_Node_EnterProfile extends EnterProfileNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Profiler\Node\EnterProfileNode');
6
 
7
+ @trigger_error('Using the "Twig_Profiler_Node_EnterProfile" class is deprecated since Twig version 2.7, use "Twig\Profiler\Node\EnterProfileNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Profiler\Node\EnterProfileNode" instead */
11
  class Twig_Profiler_Node_EnterProfile extends EnterProfileNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Profiler\Node\LeaveProfileNode;
4
 
5
  class_exists('Twig\Profiler\Node\LeaveProfileNode');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Profiler_Node_LeaveProfile extends LeaveProfileNode
9
  {
10
  }
4
 
5
  class_exists('Twig\Profiler\Node\LeaveProfileNode');
6
 
7
+ @trigger_error('Using the "Twig_Profiler_Node_LeaveProfile" class is deprecated since Twig version 2.7, use "Twig\Profiler\Node\LeaveProfileNode" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Profiler\Node\LeaveProfileNode" instead */
11
  class Twig_Profiler_Node_LeaveProfile extends LeaveProfileNode
12
  {
13
  }
vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Profiler\NodeVisitor\ProfilerNodeVisitor;
4
 
5
  class_exists('Twig\Profiler\NodeVisitor\ProfilerNodeVisitor');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Profiler_NodeVisitor_Profiler extends ProfilerNodeVisitor
9
  {
10
  }
4
 
5
  class_exists('Twig\Profiler\NodeVisitor\ProfilerNodeVisitor');
6
 
7
+ @trigger_error('Using the "Twig_Profiler_NodeVisitor_Profiler" class is deprecated since Twig version 2.7, use "Twig\Profiler\NodeVisitor\ProfilerNodeVisitor" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Profiler\NodeVisitor\ProfilerNodeVisitor" instead */
11
  class Twig_Profiler_NodeVisitor_Profiler extends ProfilerNodeVisitor
12
  {
13
  }
vendor/twig/twig/lib/Twig/Profiler/Profile.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Profiler\Profile;
4
 
5
  class_exists('Twig\Profiler\Profile');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Profiler_Profile extends Profile
9
  {
10
  }
4
 
5
  class_exists('Twig\Profiler\Profile');
6
 
7
+ @trigger_error('Using the "Twig_Profiler_Profile" class is deprecated since Twig version 2.7, use "Twig\Profiler\Profile" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Profiler\Profile" instead */
11
  class Twig_Profiler_Profile extends Profile
12
  {
13
  }
vendor/twig/twig/lib/Twig/RuntimeLoaderInterface.php CHANGED
@@ -4,7 +4,10 @@ use Twig\RuntimeLoader\RuntimeLoaderInterface;
4
 
5
  class_exists('Twig\RuntimeLoader\RuntimeLoaderInterface');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_RuntimeLoaderInterface extends RuntimeLoaderInterface
9
  {
10
  }
4
 
5
  class_exists('Twig\RuntimeLoader\RuntimeLoaderInterface');
6
 
7
+ @trigger_error('Using the "Twig_RuntimeLoaderInterface" class is deprecated since Twig version 2.7, use "Twig\RuntimeLoader\RuntimeLoaderInterface" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\RuntimeLoader\RuntimeLoaderInterface" instead */
11
  class Twig_RuntimeLoaderInterface extends RuntimeLoaderInterface
12
  {
13
  }
vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Sandbox\SecurityError;
4
 
5
  class_exists('Twig\Sandbox\SecurityError');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Sandbox_SecurityError extends SecurityError
9
  {
10
  }
4
 
5
  class_exists('Twig\Sandbox\SecurityError');
6
 
7
+ @trigger_error('Using the "Twig_Sandbox_SecurityError" class is deprecated since Twig version 2.7, use "Twig\Sandbox\SecurityError" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Sandbox\SecurityError" instead */
11
  class Twig_Sandbox_SecurityError extends SecurityError
12
  {
13
  }
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Sandbox\SecurityNotAllowedFilterError;
4
 
5
  class_exists('Twig\Sandbox\SecurityNotAllowedFilterError');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Sandbox_SecurityNotAllowedFilterError extends SecurityNotAllowedFilterError
9
  {
10
  }
4
 
5
  class_exists('Twig\Sandbox\SecurityNotAllowedFilterError');
6
 
7
+ @trigger_error('Using the "Twig_Sandbox_SecurityNotAllowedFilterError" class is deprecated since Twig version 2.7, use "Twig\Sandbox\SecurityNotAllowedFilterError" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Sandbox\SecurityNotAllowedFilterError" instead */
11
  class Twig_Sandbox_SecurityNotAllowedFilterError extends SecurityNotAllowedFilterError
12
  {
13
  }
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Sandbox\SecurityNotAllowedFunctionError;
4
 
5
  class_exists('Twig\Sandbox\SecurityNotAllowedFunctionError');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Sandbox_SecurityNotAllowedFunctionError extends SecurityNotAllowedFunctionError
9
  {
10
  }
4
 
5
  class_exists('Twig\Sandbox\SecurityNotAllowedFunctionError');
6
 
7
+ @trigger_error('Using the "Twig_Sandbox_SecurityNotAllowedFunctionError" class is deprecated since Twig version 2.7, use "Twig\Sandbox\SecurityNotAllowedFunctionError" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Sandbox\SecurityNotAllowedFunctionError" instead */
11
  class Twig_Sandbox_SecurityNotAllowedFunctionError extends SecurityNotAllowedFunctionError
12
  {
13
  }
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Sandbox\SecurityNotAllowedMethodError;
4
 
5
  class_exists('Twig\Sandbox\SecurityNotAllowedMethodError');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Sandbox_SecurityNotAllowedMethodError extends SecurityNotAllowedMethodError
9
  {
10
  }
4
 
5
  class_exists('Twig\Sandbox\SecurityNotAllowedMethodError');
6
 
7
+ @trigger_error('Using the "Twig_Sandbox_SecurityNotAllowedMethodError" class is deprecated since Twig version 2.7, use "Twig\Sandbox\SecurityNotAllowedMethodError" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Sandbox\SecurityNotAllowedMethodError" instead */
11
  class Twig_Sandbox_SecurityNotAllowedMethodError extends SecurityNotAllowedMethodError
12
  {
13
  }
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Sandbox\SecurityNotAllowedPropertyError;
4
 
5
  class_exists('Twig\Sandbox\SecurityNotAllowedPropertyError');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Sandbox_SecurityNotAllowedPropertyError extends SecurityNotAllowedPropertyError
9
  {
10
  }
4
 
5
  class_exists('Twig\Sandbox\SecurityNotAllowedPropertyError');
6
 
7
+ @trigger_error('Using the "Twig_Sandbox_SecurityNotAllowedPropertyError" class is deprecated since Twig version 2.7, use "Twig\Sandbox\SecurityNotAllowedPropertyError" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Sandbox\SecurityNotAllowedPropertyError" instead */
11
  class Twig_Sandbox_SecurityNotAllowedPropertyError extends SecurityNotAllowedPropertyError
12
  {
13
  }
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Sandbox\SecurityNotAllowedTagError;
4
 
5
  class_exists('Twig\Sandbox\SecurityNotAllowedTagError');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Sandbox_SecurityNotAllowedTagError extends SecurityNotAllowedTagError
9
  {
10
  }
4
 
5
  class_exists('Twig\Sandbox\SecurityNotAllowedTagError');
6
 
7
+ @trigger_error('Using the "Twig_Sandbox_SecurityNotAllowedTagError" class is deprecated since Twig version 2.7, use "Twig\Sandbox\SecurityNotAllowedTagError" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Sandbox\SecurityNotAllowedTagError" instead */
11
  class Twig_Sandbox_SecurityNotAllowedTagError extends SecurityNotAllowedTagError
12
  {
13
  }
vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Sandbox\SecurityPolicy;
4
 
5
  class_exists('Twig\Sandbox\SecurityPolicy');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Sandbox_SecurityPolicy extends SecurityPolicy
9
  {
10
  }
4
 
5
  class_exists('Twig\Sandbox\SecurityPolicy');
6
 
7
+ @trigger_error('Using the "Twig_Sandbox_SecurityPolicy" class is deprecated since Twig version 2.7, use "Twig\Sandbox\SecurityPolicy" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Sandbox\SecurityPolicy" instead */
11
  class Twig_Sandbox_SecurityPolicy extends SecurityPolicy
12
  {
13
  }
vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Sandbox\SecurityPolicyInterface;
4
 
5
  class_exists('Twig\Sandbox\SecurityPolicyInterface');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Sandbox_SecurityPolicyInterface extends SecurityPolicyInterface
9
  {
10
  }
4
 
5
  class_exists('Twig\Sandbox\SecurityPolicyInterface');
6
 
7
+ @trigger_error('Using the "Twig_Sandbox_SecurityPolicyInterface" class is deprecated since Twig version 2.7, use "Twig\Sandbox\SecurityPolicyInterface" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Sandbox\SecurityPolicyInterface" instead */
11
  class Twig_Sandbox_SecurityPolicyInterface extends SecurityPolicyInterface
12
  {
13
  }
vendor/twig/twig/lib/Twig/SimpleFilter.php CHANGED
@@ -1,11 +1,26 @@
1
  <?php
2
 
 
 
 
 
 
 
 
 
 
3
  use Twig\TwigFilter;
4
 
5
- class_exists('Twig\TwigFilter');
 
 
 
 
 
6
 
7
- if (\false) {
8
- class Twig_SimpleFilter extends TwigFilter
 
9
  {
10
  }
11
  }
1
  <?php
2
 
3
+ /*
4
+ * This file is part of Twig.
5
+ *
6
+ * (c) Fabien Potencier
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
  use Twig\TwigFilter;
13
 
14
+ /*
15
+ * For Twig 1.x compatibility.
16
+ */
17
+ class_exists(TwigFilter::class);
18
+
19
+ @trigger_error('Using the "Twig_SimpleFilter" class is deprecated since Twig version 2.7, use "Twig\TwigFilter" instead.', \E_USER_DEPRECATED);
20
 
21
+ if (false) {
22
+ /** @deprecated since Twig 2.7, use "Twig\TwigFilter" instead */
23
+ final class Twig_SimpleFilter extends TwigFilter
24
  {
25
  }
26
  }
vendor/twig/twig/lib/Twig/SimpleFunction.php CHANGED
@@ -1,11 +1,26 @@
1
  <?php
2
 
 
 
 
 
 
 
 
 
 
3
  use Twig\TwigFunction;
4
 
5
- class_exists('Twig\TwigFunction');
 
 
 
 
 
6
 
7
- if (\false) {
8
- class Twig_SimpleFunction extends TwigFunction
 
9
  {
10
  }
11
  }
1
  <?php
2
 
3
+ /*
4
+ * This file is part of Twig.
5
+ *
6
+ * (c) Fabien Potencier
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
  use Twig\TwigFunction;
13
 
14
+ /*
15
+ * For Twig 1.x compatibility.
16
+ */
17
+ class_exists(TwigFunction::class);
18
+
19
+ @trigger_error('Using the "Twig_SimpleFunction" class is deprecated since Twig version 2.7, use "Twig\TwigFunction" instead.', \E_USER_DEPRECATED);
20
 
21
+ if (false) {
22
+ /** @deprecated since Twig 2.7, use "Twig\TwigFunction" instead */
23
+ final class Twig_SimpleFunction extends TwigFunction
24
  {
25
  }
26
  }
vendor/twig/twig/lib/Twig/SimpleTest.php CHANGED
@@ -1,11 +1,26 @@
1
  <?php
2
 
 
 
 
 
 
 
 
 
 
3
  use Twig\TwigTest;
4
 
5
- class_exists('Twig\TwigTest');
 
 
 
 
 
6
 
7
- if (\false) {
8
- class Twig_SimpleTest extends TwigTest
 
9
  {
10
  }
11
  }
1
  <?php
2
 
3
+ /*
4
+ * This file is part of Twig.
5
+ *
6
+ * (c) Fabien Potencier
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
  use Twig\TwigTest;
13
 
14
+ /*
15
+ * For Twig 1.x compatibility.
16
+ */
17
+ class_exists(TwigTest::class);
18
+
19
+ @trigger_error('Using the "Twig_SimpleTest" class is deprecated since Twig version 2.7, use "Twig\TwigTest" instead.', \E_USER_DEPRECATED);
20
 
21
+ if (false) {
22
+ /** @deprecated since Twig 2.7, use "Twig\TwigTest" instead */
23
+ final class Twig_SimpleTest extends TwigTest
24
  {
25
  }
26
  }
vendor/twig/twig/lib/Twig/Source.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Source;
4
 
5
  class_exists('Twig\Source');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Source extends Source
9
  {
10
  }
4
 
5
  class_exists('Twig\Source');
6
 
7
+ @trigger_error('Using the "Twig_Source" class is deprecated since Twig version 2.7, use "Twig\Source" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Source" instead */
11
  class Twig_Source extends Source
12
  {
13
  }
vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Loader\SourceContextLoaderInterface;
4
 
5
  class_exists('Twig\Loader\SourceContextLoaderInterface');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_SourceContextLoaderInterface extends SourceContextLoaderInterface
9
  {
10
  }
4
 
5
  class_exists('Twig\Loader\SourceContextLoaderInterface');
6
 
7
+ @trigger_error('Using the "Twig_SourceContextLoaderInterface" class is deprecated since Twig version 2.7, use "Twig\Loader\SourceContextLoaderInterface" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Loader\SourceContextLoaderInterface" instead */
11
  class Twig_SourceContextLoaderInterface extends SourceContextLoaderInterface
12
  {
13
  }
vendor/twig/twig/lib/Twig/Template.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Template;
4
 
5
  class_exists('Twig\Template');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Template extends Template
9
  {
10
  }
4
 
5
  class_exists('Twig\Template');
6
 
7
+ @trigger_error('Using the "Twig_Template" class is deprecated since Twig version 2.7, use "Twig\Template" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Template" instead */
11
  class Twig_Template extends Template
12
  {
13
  }
vendor/twig/twig/lib/Twig/TemplateInterface.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
-
12
- use Twig\Environment;
13
-
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
- /**
28
- * Renders the template with the given context and returns it as string.
29
- *
30
- * @param array $context An array of parameters to pass to the template
31
- *
32
- * @return string The rendered template
33
- */
34
- public function render(array $context);
35
-
36
- /**
37
- * Displays the template with the given context.
38
- *
39
- * @param array $context An array of parameters to pass to the template
40
- * @param array $blocks An array of blocks to pass to the template
41
- */
42
- public function display(array $context, array $blocks = []);
43
-
44
- /**
45
- * Returns the bound environment for this template.
46
- *
47
- * @return Environment
48
- */
49
- public function getEnvironment();
50
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/TemplateWrapper.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TemplateWrapper;
4
 
5
  class_exists('Twig\TemplateWrapper');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TemplateWrapper extends TemplateWrapper
9
  {
10
  }
4
 
5
  class_exists('Twig\TemplateWrapper');
6
 
7
+ @trigger_error('Using the "Twig_TemplateWrapper" class is deprecated since Twig version 2.7, use "Twig\TemplateWrapper" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TemplateWrapper" instead */
11
  class Twig_TemplateWrapper extends TemplateWrapper
12
  {
13
  }
vendor/twig/twig/lib/Twig/Test.php CHANGED
@@ -1,37 +1,14 @@
1
  <?php
2
 
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
 
12
- @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);
13
 
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 Twig_TestInterface, Twig_TestCallableInterface
22
- {
23
- protected $options;
24
- protected $arguments = [];
25
 
26
- public function __construct(array $options = [])
 
 
27
  {
28
- $this->options = array_merge([
29
- 'callable' => null,
30
- ], $options);
31
- }
32
-
33
- public function getCallable()
34
- {
35
- return $this->options['callable'];
36
  }
37
  }
1
  <?php
2
 
3
+ use Twig\TwigTest;
 
 
 
 
 
 
 
4
 
5
+ class_exists('Twig\TwigTest');
6
 
7
+ @trigger_error('Using the "Twig_Test" class is deprecated since Twig version 2.7, use "Twig\TwigTest" instead.', \E_USER_DEPRECATED);
 
 
 
 
 
 
 
 
 
 
8
 
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TwigTest" instead */
11
+ class Twig_Test extends TwigTest
12
  {
 
 
 
 
 
 
 
 
13
  }
14
  }
vendor/twig/twig/lib/Twig/Test/Function.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
-
12
- @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);
13
-
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 Twig_Test
22
- {
23
- protected $function;
24
-
25
- public function __construct($function, array $options = [])
26
- {
27
- $options['callable'] = $function;
28
-
29
- parent::__construct($options);
30
-
31
- $this->function = $function;
32
- }
33
-
34
- public function compile()
35
- {
36
- return $this->function;
37
- }
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Test\IntegrationTestCase;
4
 
5
  class_exists('Twig\Test\IntegrationTestCase');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Test_IntegrationTestCase extends IntegrationTestCase
9
  {
10
  }
4
 
5
  class_exists('Twig\Test\IntegrationTestCase');
6
 
7
+ @trigger_error('Using the "Twig_Test_IntegrationTestCase" class is deprecated since Twig version 2.7, use "Twig\Test\IntegrationTestCase" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Test\IntegrationTestCase" instead */
11
  class Twig_Test_IntegrationTestCase extends IntegrationTestCase
12
  {
13
  }
vendor/twig/twig/lib/Twig/Test/Method.php DELETED
@@ -1,42 +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
-
12
- use Twig\Extension\ExtensionInterface;
13
-
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
- /**
17
- * Represents a method template test.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- *
21
- * @deprecated since 1.12 (to be removed in 2.0)
22
- */
23
- class Twig_Test_Method extends Twig_Test
24
- {
25
- protected $extension;
26
- protected $method;
27
-
28
- public function __construct(ExtensionInterface $extension, $method, array $options = [])
29
- {
30
- $options['callable'] = [$extension, $method];
31
-
32
- parent::__construct($options);
33
-
34
- $this->extension = $extension;
35
- $this->method = $method;
36
- }
37
-
38
- public function compile()
39
- {
40
- return sprintf('$this->env->getExtension(\'%s\')->%s', \get_class($this->extension), $this->method);
41
- }
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/Test/Node.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
-
12
- @trigger_error('The Twig_Test_Node class is deprecated since version 1.12 and will be removed in 2.0.', E_USER_DEPRECATED);
13
-
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 Twig_Test
22
- {
23
- protected $class;
24
-
25
- public function __construct($class, array $options = [])
26
- {
27
- parent::__construct($options);
28
-
29
- $this->class = $class;
30
- }
31
-
32
- public function getClass()
33
- {
34
- return $this->class;
35
- }
36
-
37
- public function compile()
38
- {
39
- }
40
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/Test/NodeTestCase.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Test\NodeTestCase;
4
 
5
  class_exists('Twig\Test\NodeTestCase');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Test_NodeTestCase extends NodeTestCase
9
  {
10
  }
4
 
5
  class_exists('Twig\Test\NodeTestCase');
6
 
7
+ @trigger_error('Using the "Twig_Test_NodeTestCase" class is deprecated since Twig version 2.7, use "Twig\Test\NodeTestCase" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Test\NodeTestCase" instead */
11
  class Twig_Test_NodeTestCase extends NodeTestCase
12
  {
13
  }
vendor/twig/twig/lib/Twig/TestCallableInterface.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
-
12
- /**
13
- * Represents a callable template test.
14
- *
15
- * @author Fabien Potencier <fabien@symfony.com>
16
- *
17
- * @deprecated since 1.12 (to be removed in 2.0)
18
- */
19
- interface Twig_TestCallableInterface
20
- {
21
- public function getCallable();
22
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/TestInterface.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
-
12
- /**
13
- * Represents a template test.
14
- *
15
- * @author Fabien Potencier <fabien@symfony.com>
16
- *
17
- * @deprecated since 1.12 (to be removed in 2.0)
18
- */
19
- interface Twig_TestInterface
20
- {
21
- /**
22
- * Compiles a test.
23
- *
24
- * @return string The PHP code for the test
25
- */
26
- public function compile();
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/Token.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Token;
4
 
5
  class_exists('Twig\Token');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Token extends Token
9
  {
10
  }
4
 
5
  class_exists('Twig\Token');
6
 
7
+ @trigger_error('Using the "Twig_Token" class is deprecated since Twig version 2.7, use "Twig\Token" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Token" instead */
11
  class Twig_Token extends Token
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\AbstractTokenParser;
4
 
5
  class_exists('Twig\TokenParser\AbstractTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser extends AbstractTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\AbstractTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser" class is deprecated since Twig version 2.7, use "Twig\TokenParser\AbstractTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\AbstractTokenParser" instead */
11
  class Twig_TokenParser extends AbstractTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\AutoEscapeTokenParser;
4
 
5
  class_exists('Twig\TokenParser\AutoEscapeTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_AutoEscape extends AutoEscapeTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\AutoEscapeTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_AutoEscape" class is deprecated since Twig version 2.7, use "Twig\TokenParser\AutoEscapeTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\AutoEscapeTokenParser" instead */
11
  class Twig_TokenParser_AutoEscape extends AutoEscapeTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/Block.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\BlockTokenParser;
4
 
5
  class_exists('Twig\TokenParser\BlockTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_Block extends BlockTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\BlockTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_Block" class is deprecated since Twig version 2.7, use "Twig\TokenParser\BlockTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\BlockTokenParser" instead */
11
  class Twig_TokenParser_Block extends BlockTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/Deprecated.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\DeprecatedTokenParser;
4
 
5
  class_exists('Twig\TokenParser\DeprecatedTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_Deprecated extends DeprecatedTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\DeprecatedTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_Deprecated" class is deprecated since Twig version 2.7, use "Twig\TokenParser\DeprecatedTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\DeprecatedTokenParser" instead */
11
  class Twig_TokenParser_Deprecated extends DeprecatedTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/Do.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\DoTokenParser;
4
 
5
  class_exists('Twig\TokenParser\DoTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_Do extends DoTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\DoTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_Do" class is deprecated since Twig version 2.7, use "Twig\TokenParser\DoTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\DoTokenParser" instead */
11
  class Twig_TokenParser_Do extends DoTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/Embed.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\EmbedTokenParser;
4
 
5
  class_exists('Twig\TokenParser\EmbedTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_Embed extends EmbedTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\EmbedTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_Embed" class is deprecated since Twig version 2.7, use "Twig\TokenParser\EmbedTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\EmbedTokenParser" instead */
11
  class Twig_TokenParser_Embed extends EmbedTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/Extends.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\ExtendsTokenParser;
4
 
5
  class_exists('Twig\TokenParser\ExtendsTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_Extends extends ExtendsTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\ExtendsTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_Extends" class is deprecated since Twig version 2.7, use "Twig\TokenParser\ExtendsTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\ExtendsTokenParser" instead */
11
  class Twig_TokenParser_Extends extends ExtendsTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/Filter.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\FilterTokenParser;
4
 
5
  class_exists('Twig\TokenParser\FilterTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_Filter extends FilterTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\FilterTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_Filter" class is deprecated since Twig version 2.7, use "Twig\TokenParser\FilterTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\FilterTokenParser" instead */
11
  class Twig_TokenParser_Filter extends FilterTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/Flush.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\FlushTokenParser;
4
 
5
  class_exists('Twig\TokenParser\FlushTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_Flush extends FlushTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\FlushTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_Flush" class is deprecated since Twig version 2.7, use "Twig\TokenParser\FlushTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\FlushTokenParser" instead */
11
  class Twig_TokenParser_Flush extends FlushTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/For.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\ForTokenParser;
4
 
5
  class_exists('Twig\TokenParser\ForTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_For extends ForTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\ForTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_For" class is deprecated since Twig version 2.7, use "Twig\TokenParser\ForTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\ForTokenParser" instead */
11
  class Twig_TokenParser_For extends ForTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/From.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\FromTokenParser;
4
 
5
  class_exists('Twig\TokenParser\FromTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_From extends FromTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\FromTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_From" class is deprecated since Twig version 2.7, use "Twig\TokenParser\FromTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\FromTokenParser" instead */
11
  class Twig_TokenParser_From extends FromTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/If.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\IfTokenParser;
4
 
5
  class_exists('Twig\TokenParser\IfTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_If extends IfTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\IfTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_If" class is deprecated since Twig version 2.7, use "Twig\TokenParser\IfTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\IfTokenParser" instead */
11
  class Twig_TokenParser_If extends IfTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/Import.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\ImportTokenParser;
4
 
5
  class_exists('Twig\TokenParser\ImportTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_Import extends ImportTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\ImportTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_Import" class is deprecated since Twig version 2.7, use "Twig\TokenParser\ImportTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\ImportTokenParser" instead */
11
  class Twig_TokenParser_Import extends ImportTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/Include.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\IncludeTokenParser;
4
 
5
  class_exists('Twig\TokenParser\IncludeTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_Include extends IncludeTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\IncludeTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_Include" class is deprecated since Twig version 2.7, use "Twig\TokenParser\IncludeTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\IncludeTokenParser" instead */
11
  class Twig_TokenParser_Include extends IncludeTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/Macro.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\MacroTokenParser;
4
 
5
  class_exists('Twig\TokenParser\MacroTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_Macro extends MacroTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\MacroTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_Macro" class is deprecated since Twig version 2.7, use "Twig\TokenParser\MacroTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\MacroTokenParser" instead */
11
  class Twig_TokenParser_Macro extends MacroTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\SandboxTokenParser;
4
 
5
  class_exists('Twig\TokenParser\SandboxTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_Sandbox extends SandboxTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\SandboxTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_Sandbox" class is deprecated since Twig version 2.7, use "Twig\TokenParser\SandboxTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\SandboxTokenParser" instead */
11
  class Twig_TokenParser_Sandbox extends SandboxTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/Set.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\SetTokenParser;
4
 
5
  class_exists('Twig\TokenParser\SetTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_Set extends SetTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\SetTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_Set" class is deprecated since Twig version 2.7, use "Twig\TokenParser\SetTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\SetTokenParser" instead */
11
  class Twig_TokenParser_Set extends SetTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\SpacelessTokenParser;
4
 
5
  class_exists('Twig\TokenParser\SpacelessTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_Spaceless extends SpacelessTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\SpacelessTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_Spaceless" class is deprecated since Twig version 2.7, use "Twig\TokenParser\SpacelessTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\SpacelessTokenParser" instead */
11
  class Twig_TokenParser_Spaceless extends SpacelessTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/Use.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\UseTokenParser;
4
 
5
  class_exists('Twig\TokenParser\UseTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_Use extends UseTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\UseTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_Use" class is deprecated since Twig version 2.7, use "Twig\TokenParser\UseTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\UseTokenParser" instead */
11
  class Twig_TokenParser_Use extends UseTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParser/With.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\WithTokenParser;
4
 
5
  class_exists('Twig\TokenParser\WithTokenParser');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParser_With extends WithTokenParser
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\WithTokenParser');
6
 
7
+ @trigger_error('Using the "Twig_TokenParser_With" class is deprecated since Twig version 2.7, use "Twig\TokenParser\WithTokenParser" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\WithTokenParser" instead */
11
  class Twig_TokenParser_With extends WithTokenParser
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenParserBroker.php DELETED
@@ -1,122 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Arnaud Le Blanc
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
-
13
- use Twig\TokenParser\TokenParserInterface;
14
-
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 Twig_TokenParserBrokerInterface
23
- {
24
- protected $parser;
25
- protected $parsers = [];
26
- protected $brokers = [];
27
-
28
- /**
29
- * @param array|\Traversable $parsers A \Traversable of Twig_TokenParserInterface instances
30
- * @param array|\Traversable $brokers A \Traversable of Twig_TokenParserBrokerInterface instances
31
- * @param bool $triggerDeprecationError
32
- */
33
- public function __construct($parsers = [], $brokers = [], $triggerDeprecationError = true)
34
- {
35
- if ($triggerDeprecationError) {
36
- @trigger_error('The '.__CLASS__.' class is deprecated since version 1.12 and will be removed in 2.0.', E_USER_DEPRECATED);
37
- }
38
-
39
- foreach ($parsers as $parser) {
40
- if (!$parser instanceof TokenParserInterface) {
41
- throw new \LogicException('$parsers must a an array of Twig_TokenParserInterface.');
42
- }
43
- $this->parsers[$parser->getTag()] = $parser;
44
- }
45
- foreach ($brokers as $broker) {
46
- if (!$broker instanceof Twig_TokenParserBrokerInterface) {
47
- throw new \LogicException('$brokers must a an array of Twig_TokenParserBrokerInterface.');
48
- }
49
- $this->brokers[] = $broker;
50
- }
51
- }
52
-
53
- public function addTokenParser(TokenParserInterface $parser)
54
- {
55
- $this->parsers[$parser->getTag()] = $parser;
56
- }
57
-
58
- public function removeTokenParser(TokenParserInterface $parser)
59
- {
60
- $name = $parser->getTag();
61
- if (isset($this->parsers[$name]) && $parser === $this->parsers[$name]) {
62
- unset($this->parsers[$name]);
63
- }
64
- }
65
-
66
- public function addTokenParserBroker(self $broker)
67
- {
68
- $this->brokers[] = $broker;
69
- }
70
-
71
- public function removeTokenParserBroker(self $broker)
72
- {
73
- if (false !== $pos = array_search($broker, $this->brokers)) {
74
- unset($this->brokers[$pos]);
75
- }
76
- }
77
-
78
- /**
79
- * Gets a suitable TokenParser for a tag.
80
- *
81
- * First looks in parsers, then in brokers.
82
- *
83
- * @param string $tag A tag name
84
- *
85
- * @return TokenParserInterface|null A Twig_TokenParserInterface or null if no suitable TokenParser was found
86
- */
87
- public function getTokenParser($tag)
88
- {
89
- if (isset($this->parsers[$tag])) {
90
- return $this->parsers[$tag];
91
- }
92
- $broker = end($this->brokers);
93
- while (false !== $broker) {
94
- $parser = $broker->getTokenParser($tag);
95
- if (null !== $parser) {
96
- return $parser;
97
- }
98
- $broker = prev($this->brokers);
99
- }
100
- }
101
-
102
- public function getParsers()
103
- {
104
- return $this->parsers;
105
- }
106
-
107
- public function getParser()
108
- {
109
- return $this->parser;
110
- }
111
-
112
- public function setParser(Twig_ParserInterface $parser)
113
- {
114
- $this->parser = $parser;
115
- foreach ($this->parsers as $tokenParser) {
116
- $tokenParser->setParser($parser);
117
- }
118
- foreach ($this->brokers as $broker) {
119
- $broker->setParser($parser);
120
- }
121
- }
122
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php DELETED
@@ -1,46 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Arnaud Le Blanc
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
-
13
- use Twig\TokenParser\TokenParserInterface;
14
-
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
- /**
36
- * Calls Twig\TokenParser\TokenParserInterface::setParser on all parsers the implementation knows of.
37
- */
38
- public function setParser(Twig_ParserInterface $parser);
39
-
40
- /**
41
- * Gets the Twig_ParserInterface.
42
- *
43
- * @return Twig_ParserInterface|null A Twig_ParserInterface instance or null
44
- */
45
- public function getParser();
46
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/twig/twig/lib/Twig/TokenParserInterface.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenParser\TokenParserInterface;
4
 
5
  class_exists('Twig\TokenParser\TokenParserInterface');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenParserInterface extends TokenParserInterface
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenParser\TokenParserInterface');
6
 
7
+ @trigger_error('Using the "Twig_TokenParserInterface" class is deprecated since Twig version 2.7, use "Twig\TokenParser\TokenParserInterface" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenParser\TokenParserInterface" instead */
11
  class Twig_TokenParserInterface extends TokenParserInterface
12
  {
13
  }
vendor/twig/twig/lib/Twig/TokenStream.php CHANGED
@@ -4,7 +4,10 @@ use Twig\TokenStream;
4
 
5
  class_exists('Twig\TokenStream');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_TokenStream extends TokenStream
9
  {
10
  }
4
 
5
  class_exists('Twig\TokenStream');
6
 
7
+ @trigger_error('Using the "Twig_TokenStream" class is deprecated since Twig version 2.7, use "Twig\TokenStream" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\TokenStream" instead */
11
  class Twig_TokenStream extends TokenStream
12
  {
13
  }
vendor/twig/twig/lib/Twig/Util/DeprecationCollector.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Util\DeprecationCollector;
4
 
5
  class_exists('Twig\Util\DeprecationCollector');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Util_DeprecationCollector extends DeprecationCollector
9
  {
10
  }
4
 
5
  class_exists('Twig\Util\DeprecationCollector');
6
 
7
+ @trigger_error('Using the "Twig_Util_DeprecationCollector" class is deprecated since Twig version 2.7, use "Twig\Util\DeprecationCollector" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Util\DeprecationCollector" instead */
11
  class Twig_Util_DeprecationCollector extends DeprecationCollector
12
  {
13
  }
vendor/twig/twig/lib/Twig/Util/TemplateDirIterator.php CHANGED
@@ -4,7 +4,10 @@ use Twig\Util\TemplateDirIterator;
4
 
5
  class_exists('Twig\Util\TemplateDirIterator');
6
 
7
- if (\false) {
 
 
 
8
  class Twig_Util_TemplateDirIterator extends TemplateDirIterator
9
  {
10
  }
4
 
5
  class_exists('Twig\Util\TemplateDirIterator');
6
 
7
+ @trigger_error('Using the "Twig_Util_TemplateDirIterator" class is deprecated since Twig version 2.7, use "Twig\Util\TemplateDirIterator" instead.', \E_USER_DEPRECATED);
8
+
9
+ if (false) {
10
+ /** @deprecated since Twig 2.7, use "Twig\Util\TemplateDirIterator" instead */
11
  class Twig_Util_TemplateDirIterator extends TemplateDirIterator
12
  {
13
  }
vendor/twig/twig/src/Cache/FilesystemCache.php CHANGED
@@ -18,7 +18,7 @@ namespace Twig\Cache;
18
  */
19
  class FilesystemCache implements CacheInterface
20
  {
21
- const FORCE_BYTECODE_INVALIDATION = 1;
22
 
23
  private $directory;
24
  private $options;
@@ -35,7 +35,7 @@ class FilesystemCache implements CacheInterface
35
 
36
  public function generateKey($name, $className)
37
  {
38
- $hash = hash('sha256', $className);
39
 
40
  return $this->directory.$hash[0].$hash[1].'/'.$hash.'.php';
41
  }
@@ -67,7 +67,7 @@ class FilesystemCache implements CacheInterface
67
 
68
  if (self::FORCE_BYTECODE_INVALIDATION == ($this->options & self::FORCE_BYTECODE_INVALIDATION)) {
69
  // Compile cached file into bytecode cache
70
- if (\function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) {
71
  @opcache_invalidate($key, true);
72
  } elseif (\function_exists('apc_compile_file')) {
73
  apc_compile_file($key);
18
  */
19
  class FilesystemCache implements CacheInterface
20
  {
21
+ public const FORCE_BYTECODE_INVALIDATION = 1;
22
 
23
  private $directory;
24
  private $options;
35
 
36
  public function generateKey($name, $className)
37
  {
38
+ $hash = hash(\PHP_VERSION_ID < 80100 ? 'sha256' : 'xxh128', $className);
39
 
40
  return $this->directory.$hash[0].$hash[1].'/'.$hash.'.php';
41
  }
67
 
68
  if (self::FORCE_BYTECODE_INVALIDATION == ($this->options & self::FORCE_BYTECODE_INVALIDATION)) {
69
  // Compile cached file into bytecode cache
70
+ if (\function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN)) {
71
  @opcache_invalidate($key, true);
72
  } elseif (\function_exists('apc_compile_file')) {
73
  apc_compile_file($key);
vendor/twig/twig/src/Cache/NullCache.php CHANGED
@@ -14,11 +14,9 @@ namespace Twig\Cache;
14
  /**
15
  * Implements a no-cache strategy.
16
  *
17
- * @final
18
- *
19
  * @author Fabien Potencier <fabien@symfony.com>
20
  */
21
- class NullCache implements CacheInterface
22
  {
23
  public function generateKey($name, $className)
24
  {
14
  /**
15
  * Implements a no-cache strategy.
16
  *
 
 
17
  * @author Fabien Potencier <fabien@symfony.com>
18
  */
19
+ final class NullCache implements CacheInterface
20
  {
21
  public function generateKey($name, $className)
22
  {
vendor/twig/twig/src/Compiler.php CHANGED
@@ -12,23 +12,22 @@
12
 
13
  namespace Twig;
14
 
15
- use Twig\Node\ModuleNode;
16
 
17
  /**
18
  * Compiles a node to PHP code.
19
  *
20
  * @author Fabien Potencier <fabien@symfony.com>
21
  */
22
- class Compiler implements \Twig_CompilerInterface
23
  {
24
- protected $lastLine;
25
- protected $source;
26
- protected $indentation;
27
- protected $env;
28
- protected $debugInfo = [];
29
- protected $sourceOffset;
30
- protected $sourceLine;
31
- protected $filename;
32
  private $varNameSalt = 0;
33
 
34
  public function __construct(Environment $env)
@@ -36,16 +35,6 @@ class Compiler implements \Twig_CompilerInterface
36
  $this->env = $env;
37
  }
38
 
39
- /**
40
- * @deprecated since 1.25 (to be removed in 2.0)
41
- */
42
- public function getFilename()
43
- {
44
- @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
45
-
46
- return $this->filename;
47
- }
48
-
49
  /**
50
  * Returns the environment instance related to this compiler.
51
  *
@@ -73,7 +62,7 @@ class Compiler implements \Twig_CompilerInterface
73
  *
74
  * @return $this
75
  */
76
- public function compile(\Twig_NodeInterface $node, $indentation = 0)
77
  {
78
  $this->lastLine = null;
79
  $this->source = '';
@@ -84,17 +73,12 @@ class Compiler implements \Twig_CompilerInterface
84
  $this->indentation = $indentation;
85
  $this->varNameSalt = 0;
86
 
87
- if ($node instanceof ModuleNode) {
88
- // to be removed in 2.0
89
- $this->filename = $node->getTemplateName();
90
- }
91
-
92
  $node->compile($this);
93
 
94
  return $this;
95
  }
96
 
97
- public function subcompile(\Twig_NodeInterface $node, $raw = true)
98
  {
99
  if (false === $raw) {
100
  $this->source .= str_repeat(' ', $this->indentation * 4);
@@ -124,9 +108,8 @@ class Compiler implements \Twig_CompilerInterface
124
  *
125
  * @return $this
126
  */
127
- public function write()
128
  {
129
- $strings = \func_get_args();
130
  foreach ($strings as $string) {
131
  $this->source .= str_repeat(' ', $this->indentation * 4).$string;
132
  }
@@ -134,22 +117,6 @@ class Compiler implements \Twig_CompilerInterface
134
  return $this;
135
  }
136
 
137
- /**
138
- * Appends an indentation to the current PHP code after compilation.
139
- *
140
- * @return $this
141
- *
142
- * @deprecated since 1.27 (to be removed in 2.0).
143
- */
144
- public function addIndentation()
145
- {
146
- @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use write(\'\') instead.', E_USER_DEPRECATED);
147
-
148
- $this->source .= str_repeat(' ', $this->indentation * 4);
149
-
150
- return $this;
151
- }
152
-
153
  /**
154
  * Adds a quoted string to the compiled code.
155
  *
@@ -174,21 +141,21 @@ class Compiler implements \Twig_CompilerInterface
174
  public function repr($value)
175
  {
176
  if (\is_int($value) || \is_float($value)) {
177
- if (false !== $locale = setlocale(LC_NUMERIC, '0')) {
178
- setlocale(LC_NUMERIC, 'C');
179
  }
180
 
181
  $this->raw(var_export($value, true));
182
 
183
  if (false !== $locale) {
184
- setlocale(LC_NUMERIC, $locale);
185
  }
186
  } elseif (null === $value) {
187
  $this->raw('null');
188
  } elseif (\is_bool($value)) {
189
  $this->raw($value ? 'true' : 'false');
190
  } elseif (\is_array($value)) {
191
- $this->raw('[');
192
  $first = true;
193
  foreach ($value as $key => $v) {
194
  if (!$first) {
@@ -199,7 +166,7 @@ class Compiler implements \Twig_CompilerInterface
199
  $this->raw(' => ');
200
  $this->repr($v);
201
  }
202
- $this->raw(']');
203
  } else {
204
  $this->string($value);
205
  }
@@ -212,22 +179,12 @@ class Compiler implements \Twig_CompilerInterface
212
  *
213
  * @return $this
214
  */
215
- public function addDebugInfo(\Twig_NodeInterface $node)
216
  {
217
  if ($node->getTemplateLine() != $this->lastLine) {
218
  $this->write(sprintf("// line %d\n", $node->getTemplateLine()));
219
 
220
- // when mbstring.func_overload is set to 2
221
- // mb_substr_count() replaces substr_count()
222
- // but they have different signatures!
223
- if (((int) ini_get('mbstring.func_overload')) & 2) {
224
- @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);
225
-
226
- // this is much slower than the "right" version
227
- $this->sourceLine += mb_substr_count(mb_substr($this->source, $this->sourceOffset), "\n");
228
- } else {
229
- $this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset);
230
- }
231
  $this->sourceOffset = \strlen($this->source);
232
  $this->debugInfo[$this->sourceLine] = $node->getTemplateLine();
233
 
@@ -281,7 +238,7 @@ class Compiler implements \Twig_CompilerInterface
281
 
282
  public function getVarName()
283
  {
284
- return sprintf('__internal_%s', hash('sha256', __METHOD__.$this->varNameSalt++));
285
  }
286
  }
287
 
12
 
13
  namespace Twig;
14
 
15
+ use Twig\Node\Node;
16
 
17
  /**
18
  * Compiles a node to PHP code.
19
  *
20
  * @author Fabien Potencier <fabien@symfony.com>
21
  */
22
+ class Compiler
23
  {
24
+ private $lastLine;
25
+ private $source;
26
+ private $indentation;
27
+ private $env;
28
+ private $debugInfo = [];
29
+ private $sourceOffset;
30
+ private $sourceLine;
 
31
  private $varNameSalt = 0;
32
 
33
  public function __construct(Environment $env)
35
  $this->env = $env;
36
  }
37
 
 
 
 
 
 
 
 
 
 
 
38
  /**
39
  * Returns the environment instance related to this compiler.
40
  *
62
  *
63
  * @return $this
64
  */
65
+ public function compile(Node $node, $indentation = 0)
66
  {
67
  $this->lastLine = null;
68
  $this->source = '';
73
  $this->indentation = $indentation;
74
  $this->varNameSalt = 0;
75
 
 
 
 
 
 
76
  $node->compile($this);
77
 
78
  return $this;
79
  }
80
 
81
+ public function subcompile(Node $node, $raw = true)
82
  {
83
  if (false === $raw) {
84
  $this->source .= str_repeat(' ', $this->indentation * 4);
108
  *
109
  * @return $this
110
  */
111
+ public function write(...$strings)
112
  {
 
113
  foreach ($strings as $string) {
114
  $this->source .= str_repeat(' ', $this->indentation * 4).$string;
115
  }
117
  return $this;
118
  }
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  /**
121
  * Adds a quoted string to the compiled code.
122
  *
141
  public function repr($value)
142
  {
143
  if (\is_int($value) || \is_float($value)) {
144
+ if (false !== $locale = setlocale(\LC_NUMERIC, '0')) {
145
+ setlocale(\LC_NUMERIC, 'C');
146
  }
147
 
148
  $this->raw(var_export($value, true));
149
 
150
  if (false !== $locale) {
151
+ setlocale(\LC_NUMERIC, $locale);
152
  }
153
  } elseif (null === $value) {
154
  $this->raw('null');
155
  } elseif (\is_bool($value)) {
156
  $this->raw($value ? 'true' : 'false');
157
  } elseif (\is_array($value)) {
158
+ $this->raw('array(');
159
  $first = true;
160
  foreach ($value as $key => $v) {
161
  if (!$first) {
166
  $this->raw(' => ');
167
  $this->repr($v);
168
  }
169
+ $this->raw(')');
170
  } else {
171
  $this->string($value);
172
  }
179
  *
180
  * @return $this
181
  */
182
+ public function addDebugInfo(Node $node)
183
  {
184
  if ($node->getTemplateLine() != $this->lastLine) {
185
  $this->write(sprintf("// line %d\n", $node->getTemplateLine()));
186
 
187
+ $this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset);
 
 
 
 
 
 
 
 
 
 
188
  $this->sourceOffset = \strlen($this->source);
189
  $this->debugInfo[$this->sourceLine] = $node->getTemplateLine();
190
 
238
 
239
  public function getVarName()
240
  {
241
+ return sprintf('__internal_compile_%d', $this->varNameSalt++);
242
  }
243
  }
244
 
vendor/twig/twig/src/Environment.php CHANGED
@@ -21,65 +21,46 @@ use Twig\Error\SyntaxError;
21
  use Twig\Extension\CoreExtension;
22
  use Twig\Extension\EscaperExtension;
23
  use Twig\Extension\ExtensionInterface;
24
- use Twig\Extension\GlobalsInterface;
25
- use Twig\Extension\InitRuntimeInterface;
26
  use Twig\Extension\OptimizerExtension;
27
- use Twig\Extension\StagingExtension;
28
  use Twig\Loader\ArrayLoader;
29
  use Twig\Loader\ChainLoader;
30
  use Twig\Loader\LoaderInterface;
31
- use Twig\Loader\SourceContextLoaderInterface;
32
  use Twig\Node\ModuleNode;
 
33
  use Twig\NodeVisitor\NodeVisitorInterface;
34
  use Twig\RuntimeLoader\RuntimeLoaderInterface;
35
  use Twig\TokenParser\TokenParserInterface;
36
 
37
  /**
38
- * Stores the Twig configuration.
39
  *
40
  * @author Fabien Potencier <fabien@symfony.com>
41
  */
42
  class Environment
43
  {
44
- const VERSION = '1.42.5';
45
- const VERSION_ID = 14205;
46
- const MAJOR_VERSION = 1;
47
- const MINOR_VERSION = 42;
48
- const RELEASE_VERSION = 5;
49
- const EXTRA_VERSION = '';
50
-
51
- protected $charset;
52
- protected $loader;
53
- protected $debug;
54
- protected $autoReload;
55
- protected $cache;
56
- protected $lexer;
57
- protected $parser;
58
- protected $compiler;
59
- protected $baseTemplateClass;
60
- protected $extensions;
61
- protected $parsers;
62
- protected $visitors;
63
- protected $filters;
64
- protected $tests;
65
- protected $functions;
66
- protected $globals;
67
- protected $runtimeInitialized = false;
68
- protected $extensionInitialized = false;
69
- protected $loadedTemplates;
70
- protected $strictVariables;
71
- protected $unaryOperators;
72
- protected $binaryOperators;
73
- protected $templateClassPrefix = '__TwigTemplate_';
74
- protected $functionCallbacks = [];
75
- protected $filterCallbacks = [];
76
- protected $staging;
77
-
78
  private $originalCache;
79
- private $bcWriteCacheFile = false;
80
- private $bcGetCacheFilename = false;
81
- private $lastModifiedExtension = 0;
82
- private $extensionsByClass = [];
83
  private $runtimeLoaders = [];
84
  private $runtimes = [];
85
  private $optionsHash;
@@ -110,7 +91,6 @@ class Environment
110
  *
111
  * * autoescape: Whether to enable auto-escaping (default to html):
112
  * * false: disable auto-escaping
113
- * * true: equivalent to html
114
  * * html, js: set the autoescaping to one of the supported strategies
115
  * * name: set the autoescaping strategy based on the template name extension
116
  * * PHP callback: a PHP callback that returns an escaping strategy based on the template "name"
@@ -119,18 +99,14 @@ class Environment
119
  * (default to -1 which means that all optimizations are enabled;
120
  * set it to 0 to disable).
121
  */
122
- public function __construct(LoaderInterface $loader = null, $options = [])
123
  {
124
- if (null !== $loader) {
125
- $this->setLoader($loader);
126
- } else {
127
- @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);
128
- }
129
 
130
  $options = array_merge([
131
  'debug' => false,
132
  'charset' => 'UTF-8',
133
- 'base_template_class' => '\Twig\Template',
134
  'strict_variables' => false,
135
  'autoescape' => 'html',
136
  'cache' => false,
@@ -139,33 +115,19 @@ class Environment
139
  ], $options);
140
 
141
  $this->debug = (bool) $options['debug'];
142
- $this->charset = strtoupper($options['charset']);
143
- $this->baseTemplateClass = $options['base_template_class'];
 
 
 
144
  $this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload'];
145
  $this->strictVariables = (bool) $options['strict_variables'];
146
  $this->setCache($options['cache']);
 
147
 
148
  $this->addExtension(new CoreExtension());
149
  $this->addExtension(new EscaperExtension($options['autoescape']));
150
  $this->addExtension(new OptimizerExtension($options['optimizations']));
151
- $this->staging = new StagingExtension();
152
-
153
- // For BC
154
- if (\is_string($this->originalCache)) {
155
- $r = new \ReflectionMethod($this, 'writeCacheFile');
156
- if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
157
- @trigger_error('The Twig\Environment::writeCacheFile method is deprecated since version 1.22 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
158
-
159
- $this->bcWriteCacheFile = true;
160
- }
161
-
162
- $r = new \ReflectionMethod($this, 'getCacheFilename');
163
- if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
164
- @trigger_error('The Twig\Environment::getCacheFilename method is deprecated since version 1.22 and will be removed in Twig 2.0.', E_USER_DEPRECATED);
165
-
166
- $this->bcGetCacheFilename = true;
167
- }
168
- }
169
  }
170
 
171
  /**
@@ -175,6 +137,10 @@ class Environment
175
  */
176
  public function getBaseTemplateClass()
177
  {
 
 
 
 
178
  return $this->baseTemplateClass;
179
  }
180
 
@@ -185,6 +151,8 @@ class Environment
185
  */
186
  public function setBaseTemplateClass($class)
187
  {
 
 
188
  $this->baseTemplateClass = $class;
189
  $this->updateOptionsHash();
190
  }
@@ -296,39 +264,17 @@ class Environment
296
  {
297
  if (\is_string($cache)) {
298
  $this->originalCache = $cache;
299
- $this->cache = new FilesystemCache($cache);
300
  } elseif (false === $cache) {
301
  $this->originalCache = $cache;
302
  $this->cache = new NullCache();
303
- } elseif (null === $cache) {
304
- @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);
305
- $this->originalCache = false;
306
- $this->cache = new NullCache();
307
  } elseif ($cache instanceof CacheInterface) {
308
  $this->originalCache = $this->cache = $cache;
309
  } else {
310
- throw new \LogicException(sprintf('Cache can only be a string, false, or a \Twig\Cache\CacheInterface implementation.'));
311
  }
312
  }
313
 
314
- /**
315
- * Gets the cache filename for a given template.
316
- *
317
- * @param string $name The template name
318
- *
319
- * @return string|false The cache file name or false when caching is disabled
320
- *
321
- * @deprecated since 1.22 (to be removed in 2.0)
322
- */
323
- public function getCacheFilename($name)
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
-
327
- $key = $this->cache->generateKey($name, $this->getTemplateClass($name));
328
-
329
- return !$key ? false : $key;
330
- }
331
-
332
  /**
333
  * Gets the template class associated with the given string.
334
  *
@@ -345,26 +291,14 @@ class Environment
345
  * @param int|null $index The index if it is an embedded template
346
  *
347
  * @return string The template class name
 
 
348
  */
349
  public function getTemplateClass($name, $index = null)
350
  {
351
  $key = $this->getLoader()->getCacheKey($name).$this->optionsHash;
352
 
353
- return $this->templateClassPrefix.hash('sha256', $key).(null === $index ? '' : '___'.$index);
354
- }
355
-
356
- /**
357
- * Gets the template class prefix.
358
- *
359
- * @return string The template class prefix
360
- *
361
- * @deprecated since 1.22 (to be removed in 2.0)
362
- */
363
- public function getTemplateClassPrefix()
364
- {
365
- @trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
366
-
367
- return $this->templateClassPrefix;
368
  }
369
 
370
  /**
@@ -402,7 +336,7 @@ class Environment
402
  /**
403
  * Loads a template.
404
  *
405
- * @param string|TemplateWrapper|\Twig\Template $name The template name
406
  *
407
  * @throws LoaderError When the template cannot be found
408
  * @throws RuntimeError When a previously generated cache is corrupted
@@ -417,6 +351,8 @@ class Environment
417
  }
418
 
419
  if ($name instanceof Template) {
 
 
420
  return new TemplateWrapper($this, $name);
421
  }
422
 
@@ -432,7 +368,7 @@ class Environment
432
  * @param string $name The template name
433
  * @param int $index The index if it is an embedded template
434
  *
435
- * @return \Twig_TemplateInterface A template instance representing the given template name
436
  *
437
  * @throws LoaderError When the template cannot be found
438
  * @throws RuntimeError When a previously generated cache is corrupted
@@ -460,11 +396,7 @@ class Environment
460
  }
461
 
462
  if (!class_exists($cls, false)) {
463
- if ($this->bcGetCacheFilename) {
464
- $key = $this->getCacheFilename($name);
465
- } else {
466
- $key = $this->cache->generateKey($name, $mainCls);
467
- }
468
 
469
  if (!$this->isAutoReload() || $this->isTemplateFresh($name, $this->cache->getTimestamp($key))) {
470
  $this->cache->load($key);
@@ -472,21 +404,10 @@ class Environment
472
 
473
  $source = null;
474
  if (!class_exists($cls, false)) {
475
- $loader = $this->getLoader();
476
- if (!$loader instanceof SourceContextLoaderInterface) {
477
- $source = new Source($loader->getSource($name), $name);
478
- } else {
479
- $source = $loader->getSourceContext($name);
480
- }
481
-
482
  $content = $this->compileSource($source);
483
-
484
- if ($this->bcWriteCacheFile) {
485
- $this->writeCacheFile($key, $content);
486
- } else {
487
- $this->cache->write($key, $content);
488
- $this->cache->load($key);
489
- }
490
 
491
  if (!class_exists($mainCls, false)) {
492
  /* Last line of defense if either $this->bcWriteCacheFile was used,
@@ -496,16 +417,15 @@ class Environment
496
  */
497
  eval('?>'.$content);
498
  }
499
- }
500
 
501
- if (!class_exists($cls, false)) {
502
- throw new RuntimeError(sprintf('Failed to load Twig template "%s", index "%s": cache might be corrupted.', $name, $index), -1, $source);
 
503
  }
504
  }
505
 
506
- if (!$this->runtimeInitialized) {
507
- $this->initRuntime();
508
- }
509
 
510
  return $this->loadedTemplates[$cls] = new $cls($this);
511
  }
@@ -523,9 +443,9 @@ class Environment
523
  * @throws LoaderError When the template cannot be found
524
  * @throws SyntaxError When an error occurred during compilation
525
  */
526
- public function createTemplate($template, $name = null)
527
  {
528
- $hash = hash('sha256', $template, false);
529
  if (null !== $name) {
530
  $name = sprintf('%s (string template %s)', $name, $hash);
531
  } else {
@@ -539,19 +459,10 @@ class Environment
539
 
540
  $this->setLoader($loader);
541
  try {
542
- $template = new TemplateWrapper($this, $this->loadTemplate($name));
543
- } catch (\Exception $e) {
544
  $this->setLoader($current);
545
-
546
- throw $e;
547
- } catch (\Throwable $e) {
548
- $this->setLoader($current);
549
-
550
- throw $e;
551
  }
552
- $this->setLoader($current);
553
-
554
- return $template;
555
  }
556
 
557
  /**
@@ -568,16 +479,7 @@ class Environment
568
  */
569
  public function isTemplateFresh($name, $time)
570
  {
571
- if (0 === $this->lastModifiedExtension) {
572
- foreach ($this->extensions as $extension) {
573
- $r = new \ReflectionObject($extension);
574
- if (file_exists($r->getFileName()) && ($extensionTime = filemtime($r->getFileName())) > $this->lastModifiedExtension) {
575
- $this->lastModifiedExtension = $extensionTime;
576
- }
577
- }
578
- }
579
-
580
- return $this->lastModifiedExtension <= $time && $this->getLoader()->isFresh($name, $time);
581
  }
582
 
583
  /**
@@ -586,7 +488,7 @@ class Environment
586
  * Similar to load() but it also accepts instances of \Twig\Template and
587
  * \Twig\TemplateWrapper, and an array of templates where each is tried to be loaded.
588
  *
589
- * @param string|Template|\Twig\TemplateWrapper|array $names A template or an array of templates to try consecutively
590
  *
591
  * @return TemplateWrapper|Template
592
  *
@@ -599,6 +501,7 @@ class Environment
599
  $names = [$names];
600
  }
601
 
 
602
  foreach ($names as $name) {
603
  if ($name instanceof Template) {
604
  return $name;
@@ -607,67 +510,17 @@ class Environment
607
  return $name;
608
  }
609
 
610
- try {
611
- return $this->loadTemplate($name);
612
- } catch (LoaderError $e) {
613
- if (1 === \count($names)) {
614
- throw $e;
615
- }
616
- }
617
- }
618
-
619
- throw new LoaderError(sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names)));
620
- }
621
-
622
- /**
623
- * Clears the internal template cache.
624
- *
625
- * @deprecated since 1.18.3 (to be removed in 2.0)
626
- */
627
- public function clearTemplateCache()
628
- {
629
- @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);
630
-
631
- $this->loadedTemplates = [];
632
- }
633
-
634
- /**
635
- * Clears the template cache files on the filesystem.
636
- *
637
- * @deprecated since 1.22 (to be removed in 2.0)
638
- */
639
- public function clearCacheFiles()
640
- {
641
- @trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
642
-
643
- if (\is_string($this->originalCache)) {
644
- foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->originalCache), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
645
- if ($file->isFile()) {
646
- @unlink($file->getPathname());
647
- }
648
  }
649
- }
650
- }
651
-
652
- /**
653
- * Gets the Lexer instance.
654
- *
655
- * @return \Twig_LexerInterface
656
- *
657
- * @deprecated since 1.25 (to be removed in 2.0)
658
- */
659
- public function getLexer()
660
- {
661
- @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
662
 
663
- if (null === $this->lexer) {
664
- $this->lexer = new Lexer($this);
665
  }
666
 
667
- return $this->lexer;
668
  }
669
 
670
- public function setLexer(\Twig_LexerInterface $lexer)
671
  {
672
  $this->lexer = $lexer;
673
  }
@@ -675,20 +528,12 @@ class Environment
675
  /**
676
  * Tokenizes a source code.
677
  *
678
- * @param string|Source $source The template source code
679
- * @param string $name The template name (deprecated)
680
- *
681
  * @return TokenStream
682
  *
683
  * @throws SyntaxError When the code is syntactically wrong
684
  */
685
- public function tokenize($source, $name = null)
686
  {
687
- if (!$source instanceof Source) {
688
- @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);
689
- $source = new Source($source, $name);
690
- }
691
-
692
  if (null === $this->lexer) {
693
  $this->lexer = new Lexer($this);
694
  }
@@ -696,25 +541,7 @@ class Environment
696
  return $this->lexer->tokenize($source);
697
  }
698
 
699
- /**
700
- * Gets the Parser instance.
701
- *
702
- * @return \Twig_ParserInterface
703
- *
704
- * @deprecated since 1.25 (to be removed in 2.0)
705
- */
706
- public function getParser()
707
- {
708
- @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
709
-
710
- if (null === $this->parser) {
711
- $this->parser = new Parser($this);
712
- }
713
-
714
- return $this->parser;
715
- }
716
-
717
- public function setParser(\Twig_ParserInterface $parser)
718
  {
719
  $this->parser = $parser;
720
  }
@@ -735,25 +562,7 @@ class Environment
735
  return $this->parser->parse($stream);
736
  }
737
 
738
- /**
739
- * Gets the Compiler instance.
740
- *
741
- * @return \Twig_CompilerInterface
742
- *
743
- * @deprecated since 1.25 (to be removed in 2.0)
744
- */
745
- public function getCompiler()
746
- {
747
- @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
748
-
749
- if (null === $this->compiler) {
750
- $this->compiler = new Compiler($this);
751
- }
752
-
753
- return $this->compiler;
754
- }
755
-
756
- public function setCompiler(\Twig_CompilerInterface $compiler)
757
  {
758
  $this->compiler = $compiler;
759
  }
@@ -763,7 +572,7 @@ class Environment
763
  *
764
  * @return string The compiled PHP source code
765
  */
766
- public function compile(\Twig_NodeInterface $node)
767
  {
768
  if (null === $this->compiler) {
769
  $this->compiler = new Compiler($this);
@@ -775,20 +584,12 @@ class Environment
775
  /**
776
  * Compiles a template source code.
777
  *
778
- * @param string|Source $source The template source code
779
- * @param string $name The template name (deprecated)
780
- *
781
  * @return string The compiled PHP source code
782
  *
783
  * @throws SyntaxError When there was an error during tokenizing, parsing or compiling
784
  */
785
- public function compileSource($source, $name = null)
786
  {
787
- if (!$source instanceof Source) {
788
- @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);
789
- $source = new Source($source, $name);
790
- }
791
-
792
  try {
793
  return $this->compile($this->parse($this->tokenize($source)));
794
  } catch (Error $e) {
@@ -801,10 +602,6 @@ class Environment
801
 
802
  public function setLoader(LoaderInterface $loader)
803
  {
804
- if (!$loader instanceof SourceContextLoaderInterface && 0 !== strpos(\get_class($loader), 'Mock_')) {
805
- @trigger_error(sprintf('Twig loader "%s" should implement Twig\Loader\SourceContextLoaderInterface since version 1.27.', \get_class($loader)), E_USER_DEPRECATED);
806
- }
807
-
808
  $this->loader = $loader;
809
  }
810
 
@@ -815,10 +612,6 @@ class Environment
815
  */
816
  public function getLoader()
817
  {
818
- if (null === $this->loader) {
819
- throw new \LogicException('You must set a loader first.');
820
- }
821
-
822
  return $this->loader;
823
  }
824
 
@@ -829,7 +622,12 @@ class Environment
829
  */
830
  public function setCharset($charset)
831
  {
832
- $this->charset = strtoupper($charset);
 
 
 
 
 
833
  }
834
 
835
  /**
@@ -842,29 +640,6 @@ class Environment
842
  return $this->charset;
843
  }
844
 
845
- /**
846
- * Initializes the runtime environment.
847
- *
848
- * @deprecated since 1.23 (to be removed in 2.0)
849
- */
850
- public function initRuntime()
851
- {
852
- $this->runtimeInitialized = true;
853
-
854
- foreach ($this->getExtensions() as $name => $extension) {
855
- if (!$extension instanceof InitRuntimeInterface) {
856
- $m = new \ReflectionMethod($extension, 'initRuntime');
857
-
858
- $parentClass = $m->getDeclaringClass()->getName();
859
- if ('Twig_Extension' !== $parentClass && 'Twig\Extension\AbstractExtension' !== $parentClass) {
860
- @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);
861
- }
862
- }
863
-
864
- $extension->initRuntime($this);
865
- }
866
- }
867
-
868
  /**
869
  * Returns true if the given extension is registered.
870
  *
@@ -874,22 +649,7 @@ class Environment
874
  */
875
  public function hasExtension($class)
876
  {
877
- $class = ltrim($class, '\\');
878
- if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
879
- // For BC/FC with namespaced aliases
880
- $class = new \ReflectionClass($class);
881
- $class = $class->name;
882
- }
883
-
884
- if (isset($this->extensions[$class])) {
885
- if ($class !== \get_class($this->extensions[$class])) {
886
- @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);
887
- }
888
-
889
- return true;
890
- }
891
-
892
- return isset($this->extensionsByClass[$class]);
893
  }
894
 
895
  /**
@@ -909,26 +669,7 @@ class Environment
909
  */
910
  public function getExtension($class)
911
  {
912
- $class = ltrim($class, '\\');
913
- if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
914
- // For BC/FC with namespaced aliases
915
- $class = new \ReflectionClass($class);
916
- $class = $class->name;
917
- }
918
-
919
- if (isset($this->extensions[$class])) {
920
- if ($class !== \get_class($this->extensions[$class])) {
921
- @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);
922
- }
923
-
924
- return $this->extensions[$class];
925
- }
926
-
927
- if (!isset($this->extensionsByClass[$class])) {
928
- throw new RuntimeError(sprintf('The "%s" extension is not enabled.', $class));
929
- }
930
-
931
- return $this->extensionsByClass[$class];
932
  }
933
 
934
  /**
@@ -957,57 +698,7 @@ class Environment
957
 
958
  public function addExtension(ExtensionInterface $extension)
959
  {
960
- if ($this->extensionInitialized) {
961
- throw new \LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $extension->getName()));
962
- }
963
-
964
- $class = \get_class($extension);
965
- if ($class !== $extension->getName()) {
966
- if (isset($this->extensions[$extension->getName()])) {
967
- unset($this->extensions[$extension->getName()], $this->extensionsByClass[$class]);
968
- @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);
969
- }
970
- }
971
-
972
- $this->lastModifiedExtension = 0;
973
- $this->extensionsByClass[$class] = $extension;
974
- $this->extensions[$extension->getName()] = $extension;
975
- $this->updateOptionsHash();
976
- }
977
-
978
- /**
979
- * Removes an extension by name.
980
- *
981
- * This method is deprecated and you should not use it.
982
- *
983
- * @param string $name The extension name
984
- *
985
- * @deprecated since 1.12 (to be removed in 2.0)
986
- */
987
- public function removeExtension($name)
988
- {
989
- @trigger_error(sprintf('The %s method is deprecated since version 1.12 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
990
-
991
- if ($this->extensionInitialized) {
992
- throw new \LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name));
993
- }
994
-
995
- $class = ltrim($name, '\\');
996
- if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
997
- // For BC/FC with namespaced aliases
998
- $class = new \ReflectionClass($class);
999
- $class = $class->name;
1000
- }
1001
-
1002
- if (isset($this->extensions[$class])) {
1003
- if ($class !== \get_class($this->extensions[$class])) {
1004
- @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);
1005
- }
1006
-
1007
- unset($this->extensions[$class]);
1008
- }
1009
-
1010
- unset($this->extensions[$class]);
1011
  $this->updateOptionsHash();
1012
  }
1013
 
@@ -1018,9 +709,8 @@ class Environment
1018
  */
1019
  public function setExtensions(array $extensions)
1020
  {
1021
- foreach ($extensions as $extension) {
1022
- $this->addExtension($extension);
1023
- }
1024
  }
1025
 
1026
  /**
@@ -1030,39 +720,29 @@ class Environment
1030
  */
1031
  public function getExtensions()
1032
  {
1033
- return $this->extensions;
1034
  }
1035
 
1036
  public function addTokenParser(TokenParserInterface $parser)
1037
  {
1038
- if ($this->extensionInitialized) {
1039
- throw new \LogicException('Unable to add a token parser as extensions have already been initialized.');
1040
- }
1041
-
1042
- $this->staging->addTokenParser($parser);
1043
  }
1044
 
1045
  /**
1046
  * Gets the registered Token Parsers.
1047
  *
1048
- * @return \Twig_TokenParserBrokerInterface
1049
  *
1050
  * @internal
1051
  */
1052
  public function getTokenParsers()
1053
  {
1054
- if (!$this->extensionInitialized) {
1055
- $this->initExtensions();
1056
- }
1057
-
1058
- return $this->parsers;
1059
  }
1060
 
1061
  /**
1062
  * Gets registered tags.
1063
  *
1064
- * Be warned that this method cannot return tags defined by \Twig_TokenParserBrokerInterface classes.
1065
- *
1066
  * @return TokenParserInterface[]
1067
  *
1068
  * @internal
@@ -1070,10 +750,8 @@ class Environment
1070
  public function getTags()
1071
  {
1072
  $tags = [];
1073
- foreach ($this->getTokenParsers()->getParsers() as $parser) {
1074
- if ($parser instanceof TokenParserInterface) {
1075
- $tags[$parser->getTag()] = $parser;
1076
- }
1077
  }
1078
 
1079
  return $tags;
@@ -1081,11 +759,7 @@ class Environment
1081
 
1082
  public function addNodeVisitor(NodeVisitorInterface $visitor)
1083
  {
1084
- if ($this->extensionInitialized) {
1085
- throw new \LogicException('Unable to add a node visitor as extensions have already been initialized.');
1086
- }
1087
-
1088
- $this->staging->addNodeVisitor($visitor);
1089
  }
1090
 
1091
  /**
@@ -1097,37 +771,12 @@ class Environment
1097
  */
1098
  public function getNodeVisitors()
1099
  {
1100
- if (!$this->extensionInitialized) {
1101
- $this->initExtensions();
1102
- }
1103
-
1104
- return $this->visitors;
1105
  }
1106
 
1107
- /**
1108
- * Registers a Filter.
1109
- *
1110
- * @param string|TwigFilter $name The filter name or a \Twig_SimpleFilter instance
1111
- * @param \Twig_FilterInterface|TwigFilter $filter
1112
- */
1113
- public function addFilter($name, $filter = null)
1114
  {
1115
- if (!$name instanceof TwigFilter && !($filter instanceof TwigFilter || $filter instanceof \Twig_FilterInterface)) {
1116
- throw new \LogicException('A filter must be an instance of \Twig_FilterInterface or \Twig_SimpleFilter.');
1117
- }
1118
-
1119
- if ($name instanceof TwigFilter) {
1120
- $filter = $name;
1121
- $name = $filter->getName();
1122
- } else {
1123
- @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);
1124
- }
1125
-
1126
- if ($this->extensionInitialized) {
1127
- throw new \LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name));
1128
- }
1129
-
1130
- $this->staging->addFilter($name, $filter);
1131
  }
1132
 
1133
  /**
@@ -1138,45 +787,18 @@ class Environment
1138
  *
1139
  * @param string $name The filter name
1140
  *
1141
- * @return \Twig_Filter|false
1142
  *
1143
  * @internal
1144
  */
1145
  public function getFilter($name)
1146
  {
1147
- if (!$this->extensionInitialized) {
1148
- $this->initExtensions();
1149
- }
1150
-
1151
- if (isset($this->filters[$name])) {
1152
- return $this->filters[$name];
1153
- }
1154
-
1155
- foreach ($this->filters as $pattern => $filter) {
1156
- $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);
1157
-
1158
- if ($count) {
1159
- if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
1160
- array_shift($matches);
1161
- $filter->setArguments($matches);
1162
-
1163
- return $filter;
1164
- }
1165
- }
1166
- }
1167
-
1168
- foreach ($this->filterCallbacks as $callback) {
1169
- if (false !== $filter = \call_user_func($callback, $name)) {
1170
- return $filter;
1171
- }
1172
- }
1173
-
1174
- return false;
1175
  }
1176
 
1177
- public function registerUndefinedFilterCallback($callable)
1178
  {
1179
- $this->filterCallbacks[] = $callable;
1180
  }
1181
 
1182
  /**
@@ -1184,7 +806,7 @@ class Environment
1184
  *
1185
  * Be warned that this method cannot return filters defined with registerUndefinedFilterCallback.
1186
  *
1187
- * @return \Twig_FilterInterface[]
1188
  *
1189
  * @see registerUndefinedFilterCallback
1190
  *
@@ -1192,53 +814,24 @@ class Environment
1192
  */
1193
  public function getFilters()
1194
  {
1195
- if (!$this->extensionInitialized) {
1196
- $this->initExtensions();
1197
- }
1198
-
1199
- return $this->filters;
1200
  }
1201
 
1202
- /**
1203
- * Registers a Test.
1204
- *
1205
- * @param string|TwigTest $name The test name or a \Twig_SimpleTest instance
1206
- * @param \Twig_TestInterface|TwigTest $test A \Twig_TestInterface instance or a \Twig_SimpleTest instance
1207
- */
1208
- public function addTest($name, $test = null)
1209
  {
1210
- if (!$name instanceof TwigTest && !($test instanceof TwigTest || $test instanceof \Twig_TestInterface)) {
1211
- throw new \LogicException('A test must be an instance of \Twig_TestInterface or \Twig_SimpleTest.');
1212
- }
1213
-
1214
- if ($name instanceof TwigTest) {
1215
- $test = $name;
1216
- $name = $test->getName();
1217
- } else {
1218
- @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);
1219
- }
1220
-
1221
- if ($this->extensionInitialized) {
1222
- throw new \LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $name));
1223
- }
1224
-
1225
- $this->staging->addTest($name, $test);
1226
  }
1227
 
1228
  /**
1229
  * Gets the registered Tests.
1230
  *
1231
- * @return \Twig_TestInterface[]
1232
  *
1233
  * @internal
1234
  */
1235
  public function getTests()
1236
  {
1237
- if (!$this->extensionInitialized) {
1238
- $this->initExtensions();
1239
- }
1240
-
1241
- return $this->tests;
1242
  }
1243
 
1244
  /**
@@ -1246,60 +839,18 @@ class Environment
1246
  *
1247
  * @param string $name The test name
1248
  *
1249
- * @return \Twig_Test|false
1250
  *
1251
  * @internal
1252
  */
1253
  public function getTest($name)
1254
  {
1255
- if (!$this->extensionInitialized) {
1256
- $this->initExtensions();
1257
- }
1258
-
1259
- if (isset($this->tests[$name])) {
1260
- return $this->tests[$name];
1261
- }
1262
-
1263
- foreach ($this->tests as $pattern => $test) {
1264
- $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);
1265
-
1266
- if ($count) {
1267
- if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
1268
- array_shift($matches);
1269
- $test->setArguments($matches);
1270
-
1271
- return $test;
1272
- }
1273
- }
1274
- }
1275
-
1276
- return false;
1277
  }
1278
 
1279
- /**
1280
- * Registers a Function.
1281
- *
1282
- * @param string|TwigFunction $name The function name or a \Twig_SimpleFunction instance
1283
- * @param \Twig_FunctionInterface|TwigFunction $function
1284
- */
1285
- public function addFunction($name, $function = null)
1286
  {
1287
- if (!$name instanceof TwigFunction && !($function instanceof TwigFunction || $function instanceof \Twig_FunctionInterface)) {
1288
- throw new \LogicException('A function must be an instance of \Twig_FunctionInterface or \Twig_SimpleFunction.');
1289
- }
1290
-
1291
- if ($name instanceof TwigFunction) {
1292
- $function = $name;
1293
- $name = $function->getName();
1294
- } else {
1295
- @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);
1296
- }
1297
-
1298
- if ($this->extensionInitialized) {
1299
- throw new \LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $name));
1300
- }
1301
-
1302
- $this->staging->addFunction($name, $function);
1303
  }
1304
 
1305
  /**
@@ -1310,45 +861,18 @@ class Environment
1310
  *
1311
  * @param string $name function name
1312
  *
1313
- * @return \Twig_Function|false
1314
  *
1315
  * @internal
1316
  */
1317
  public function getFunction($name)
1318
  {
1319
- if (!$this->extensionInitialized) {
1320
- $this->initExtensions();
1321
- }
1322
-
1323
- if (isset($this->functions[$name])) {
1324
- return $this->functions[$name];
1325
- }
1326
-
1327
- foreach ($this->functions as $pattern => $function) {
1328
- $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);
1329
-
1330
- if ($count) {
1331
- if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
1332
- array_shift($matches);
1333
- $function->setArguments($matches);
1334
-
1335
- return $function;
1336
- }
1337
- }
1338
- }
1339
-
1340
- foreach ($this->functionCallbacks as $callback) {
1341
- if (false !== $function = \call_user_func($callback, $name)) {
1342
- return $function;
1343
- }
1344
- }
1345
-
1346
- return false;
1347
  }
1348
 
1349
- public function registerUndefinedFunctionCallback($callable)
1350
  {
1351
- $this->functionCallbacks[] = $callable;
1352
  }
1353
 
1354
  /**
@@ -1356,7 +880,7 @@ class Environment
1356
  *
1357
  * Be warned that this method cannot return functions defined with registerUndefinedFunctionCallback.
1358
  *
1359
- * @return \Twig_FunctionInterface[]
1360
  *
1361
  * @see registerUndefinedFunctionCallback
1362
  *
@@ -1364,11 +888,7 @@ class Environment
1364
  */
1365
  public function getFunctions()
1366
  {
1367
- if (!$this->extensionInitialized) {
1368
- $this->initExtensions();
1369
- }
1370
-
1371
- return $this->functions;
1372
  }
1373
 
1374
  /**
@@ -1382,23 +902,14 @@ class Environment
1382
  */
1383
  public function addGlobal($name, $value)
1384
  {
1385
- if ($this->extensionInitialized || $this->runtimeInitialized) {
1386
- if (null === $this->globals) {
1387
- $this->globals = $this->initGlobals();
1388
- }
1389
-
1390
- if (!\array_key_exists($name, $this->globals)) {
1391
- // The deprecation notice must be turned into the following exception in Twig 2.0
1392
- @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);
1393
- //throw new \LogicException(sprintf('Unable to add global "%s" as the runtime or the extensions have already been initialized.', $name));
1394
- }
1395
  }
1396
 
1397
- if ($this->extensionInitialized || $this->runtimeInitialized) {
1398
- // update the value
1399
- $this->globals[$name] = $value;
1400
  } else {
1401
- $this->staging->addGlobal($name, $value);
1402
  }
1403
  }
1404
 
@@ -1411,15 +922,15 @@ class Environment
1411
  */
1412
  public function getGlobals()
1413
  {
1414
- if (!$this->runtimeInitialized && !$this->extensionInitialized) {
1415
- return $this->initGlobals();
1416
- }
 
1417
 
1418
- if (null === $this->globals) {
1419
- $this->globals = $this->initGlobals();
1420
  }
1421
 
1422
- return $this->globals;
1423
  }
1424
 
1425
  /**
@@ -1451,11 +962,7 @@ class Environment
1451
  */
1452
  public function getUnaryOperators()
1453
  {
1454
- if (!$this->extensionInitialized) {
1455
- $this->initExtensions();
1456
- }
1457
-
1458
- return $this->unaryOperators;
1459
  }
1460
 
1461
  /**
@@ -1467,171 +974,20 @@ class Environment
1467
  */
1468
  public function getBinaryOperators()
1469
  {
1470
- if (!$this->extensionInitialized) {
1471
- $this->initExtensions();
1472
- }
1473
-
1474
- return $this->binaryOperators;
1475
- }
1476
-
1477
- /**
1478
- * @deprecated since 1.23 (to be removed in 2.0)
1479
- */
1480
- public function computeAlternatives($name, $items)
1481
- {
1482
- @trigger_error(sprintf('The %s method is deprecated since version 1.23 and will be removed in Twig 2.0.', __METHOD__), E_USER_DEPRECATED);
1483
-
1484
- return SyntaxError::computeAlternatives($name, $items);
1485
- }
1486
-
1487
- /**
1488
- * @internal
1489
- */
1490
- protected function initGlobals()
1491
- {
1492
- $globals = [];
1493
- foreach ($this->extensions as $name => $extension) {
1494
- if (!$extension instanceof GlobalsInterface) {
1495
- $m = new \ReflectionMethod($extension, 'getGlobals');
1496
-
1497
- $parentClass = $m->getDeclaringClass()->getName();
1498
- if ('Twig_Extension' !== $parentClass && 'Twig\Extension\AbstractExtension' !== $parentClass) {
1499
- @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);
1500
- }
1501
- }
1502
-
1503
- $extGlob = $extension->getGlobals();
1504
- if (!\is_array($extGlob)) {
1505
- throw new \UnexpectedValueException(sprintf('"%s::getGlobals()" must return an array of globals.', \get_class($extension)));
1506
- }
1507
-
1508
- $globals[] = $extGlob;
1509
- }
1510
-
1511
- $globals[] = $this->staging->getGlobals();
1512
-
1513
- return \call_user_func_array('array_merge', $globals);
1514
- }
1515
-
1516
- /**
1517
- * @internal
1518
- */
1519
- protected function initExtensions()
1520
- {
1521
- if ($this->extensionInitialized) {
1522
- return;
1523
- }
1524
-
1525
- $this->parsers = new \Twig_TokenParserBroker([], [], false);
1526
- $this->filters = [];
1527
- $this->functions = [];
1528
- $this->tests = [];
1529
- $this->visitors = [];
1530
- $this->unaryOperators = [];
1531
- $this->binaryOperators = [];
1532
-
1533
- foreach ($this->extensions as $extension) {
1534
- $this->initExtension($extension);
1535
- }
1536
- $this->initExtension($this->staging);
1537
- // Done at the end only, so that an exception during initialization does not mark the environment as initialized when catching the exception
1538
- $this->extensionInitialized = true;
1539
- }
1540
-
1541
- /**
1542
- * @internal
1543
- */
1544
- protected function initExtension(ExtensionInterface $extension)
1545
- {
1546
- // filters
1547
- foreach ($extension->getFilters() as $name => $filter) {
1548
- if ($filter instanceof TwigFilter) {
1549
- $name = $filter->getName();
1550
- } else {
1551
- @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);
1552
- }
1553
-
1554
- $this->filters[$name] = $filter;
1555
- }
1556
-
1557
- // functions
1558
- foreach ($extension->getFunctions() as $name => $function) {
1559
- if ($function instanceof TwigFunction) {
1560
- $name = $function->getName();
1561
- } else {
1562
- @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);
1563
- }
1564
-
1565
- $this->functions[$name] = $function;
1566
- }
1567
-
1568
- // tests
1569
- foreach ($extension->getTests() as $name => $test) {
1570
- if ($test instanceof TwigTest) {
1571
- $name = $test->getName();
1572
- } else {
1573
- @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);
1574
- }
1575
-
1576
- $this->tests[$name] = $test;
1577
- }
1578
-
1579
- // token parsers
1580
- foreach ($extension->getTokenParsers() as $parser) {
1581
- if ($parser instanceof TokenParserInterface) {
1582
- $this->parsers->addTokenParser($parser);
1583
- } elseif ($parser instanceof \Twig_TokenParserBrokerInterface) {
1584
- @trigger_error('Registering a \Twig_TokenParserBrokerInterface instance is deprecated since version 1.21.', E_USER_DEPRECATED);
1585
-
1586
- $this->parsers->addTokenParserBroker($parser);
1587
- } else {
1588
- throw new \LogicException('getTokenParsers() must return an array of \Twig_TokenParserInterface or \Twig_TokenParserBrokerInterface instances.');
1589
- }
1590
- }
1591
-
1592
- // node visitors
1593
- foreach ($extension->getNodeVisitors() as $visitor) {
1594
- $this->visitors[] = $visitor;
1595
- }
1596
-
1597
- // operators
1598
- if ($operators = $extension->getOperators()) {
1599
- if (!\is_array($operators)) {
1600
- 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)));
1601
- }
1602
-
1603
- if (2 !== \count($operators)) {
1604
- throw new \InvalidArgumentException(sprintf('"%s::getOperators()" must return an array of 2 elements, got %d.', \get_class($extension), \count($operators)));
1605
- }
1606
-
1607
- $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]);
1608
- $this->binaryOperators = array_merge($this->binaryOperators, $operators[1]);
1609
- }
1610
- }
1611
-
1612
- /**
1613
- * @deprecated since 1.22 (to be removed in 2.0)
1614
- */
1615
- protected function writeCacheFile($file, $content)
1616
- {
1617
- $this->cache->write($file, $content);
1618
  }
1619
 
1620
  private function updateOptionsHash()
1621
  {
1622
- $hashParts = array_merge(
1623
- array_keys($this->extensions),
1624
- [
1625
- (int) \function_exists('twig_template_get_attributes'),
1626
- PHP_MAJOR_VERSION,
1627
- PHP_MINOR_VERSION,
1628
- self::VERSION,
1629
- (int) $this->debug,
1630
- $this->baseTemplateClass,
1631
- (int) $this->strictVariables,
1632
- ]
1633
- );
1634
- $this->optionsHash = implode(':', $hashParts);
1635
  }
1636
  }
1637
 
21
  use Twig\Extension\CoreExtension;
22
  use Twig\Extension\EscaperExtension;
23
  use Twig\Extension\ExtensionInterface;
 
 
24
  use Twig\Extension\OptimizerExtension;
 
25
  use Twig\Loader\ArrayLoader;
26
  use Twig\Loader\ChainLoader;
27
  use Twig\Loader\LoaderInterface;
 
28
  use Twig\Node\ModuleNode;
29
+ use Twig\Node\Node;
30
  use Twig\NodeVisitor\NodeVisitorInterface;
31
  use Twig\RuntimeLoader\RuntimeLoaderInterface;
32
  use Twig\TokenParser\TokenParserInterface;
33
 
34
  /**
35
+ * Stores the Twig configuration and renders templates.
36
  *
37
  * @author Fabien Potencier <fabien@symfony.com>
38
  */
39
  class Environment
40
  {
41
+ public const VERSION = '2.15.3';
42
+ public const VERSION_ID = 21503;
43
+ public const MAJOR_VERSION = 2;
44
+ public const MINOR_VERSION = 15;
45
+ public const RELEASE_VERSION = 3;
46
+ public const EXTRA_VERSION = '';
47
+
48
+ private $charset;
49
+ private $loader;
50
+ private $debug;
51
+ private $autoReload;
52
+ private $cache;
53
+ private $lexer;
54
+ private $parser;
55
+ private $compiler;
56
+ private $baseTemplateClass;
57
+ private $globals = [];
58
+ private $resolvedGlobals;
59
+ private $loadedTemplates;
60
+ private $strictVariables;
61
+ private $templateClassPrefix = '__TwigTemplate_';
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  private $originalCache;
63
+ private $extensionSet;
 
 
 
64
  private $runtimeLoaders = [];
65
  private $runtimes = [];
66
  private $optionsHash;
91
  *
92
  * * autoescape: Whether to enable auto-escaping (default to html):
93
  * * false: disable auto-escaping
 
94
  * * html, js: set the autoescaping to one of the supported strategies
95
  * * name: set the autoescaping strategy based on the template name extension
96
  * * PHP callback: a PHP callback that returns an escaping strategy based on the template "name"
99
  * (default to -1 which means that all optimizations are enabled;
100
  * set it to 0 to disable).
101
  */
102
+ public function __construct(LoaderInterface $loader, $options = [])
103
  {
104
+ $this->setLoader($loader);
 
 
 
 
105
 
106
  $options = array_merge([
107
  'debug' => false,
108
  'charset' => 'UTF-8',
109
+ 'base_template_class' => Template::class,
110
  'strict_variables' => false,
111
  'autoescape' => 'html',
112
  'cache' => false,
115
  ], $options);
116
 
117
  $this->debug = (bool) $options['debug'];
118
+ $this->setCharset($options['charset']);
119
+ $this->baseTemplateClass = '\\'.ltrim($options['base_template_class'], '\\');
120
+ if ('\\'.Template::class !== $this->baseTemplateClass && '\Twig_Template' !== $this->baseTemplateClass) {
121
+ @trigger_error('The "base_template_class" option on '.__CLASS__.' is deprecated since Twig 2.7.0.', \E_USER_DEPRECATED);
122
+ }
123
  $this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload'];
124
  $this->strictVariables = (bool) $options['strict_variables'];
125
  $this->setCache($options['cache']);
126
+ $this->extensionSet = new ExtensionSet();
127
 
128
  $this->addExtension(new CoreExtension());
129
  $this->addExtension(new EscaperExtension($options['autoescape']));
130
  $this->addExtension(new OptimizerExtension($options['optimizations']));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  }
132
 
133
  /**
137
  */
138
  public function getBaseTemplateClass()
139
  {
140
+ if (1 > \func_num_args() || \func_get_arg(0)) {
141
+ @trigger_error('The '.__METHOD__.' is deprecated since Twig 2.7.0.', \E_USER_DEPRECATED);
142
+ }
143
+
144
  return $this->baseTemplateClass;
145
  }
146
 
151
  */
152
  public function setBaseTemplateClass($class)
153
  {
154
+ @trigger_error('The '.__METHOD__.' is deprecated since Twig 2.7.0.', \E_USER_DEPRECATED);
155
+
156
  $this->baseTemplateClass = $class;
157
  $this->updateOptionsHash();
158
  }
264
  {
265
  if (\is_string($cache)) {
266
  $this->originalCache = $cache;
267
+ $this->cache = new FilesystemCache($cache, $this->autoReload ? FilesystemCache::FORCE_BYTECODE_INVALIDATION : 0);
268
  } elseif (false === $cache) {
269
  $this->originalCache = $cache;
270
  $this->cache = new NullCache();
 
 
 
 
271
  } elseif ($cache instanceof CacheInterface) {
272
  $this->originalCache = $this->cache = $cache;
273
  } else {
274
+ throw new \LogicException('Cache can only be a string, false, or a \Twig\Cache\CacheInterface implementation.');
275
  }
276
  }
277
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  /**
279
  * Gets the template class associated with the given string.
280
  *
291
  * @param int|null $index The index if it is an embedded template
292
  *
293
  * @return string The template class name
294
+ *
295
+ * @internal
296
  */
297
  public function getTemplateClass($name, $index = null)
298
  {
299
  $key = $this->getLoader()->getCacheKey($name).$this->optionsHash;
300
 
301
+ return $this->templateClassPrefix.hash(\PHP_VERSION_ID < 80100 ? 'sha256' : 'xxh128', $key).(null === $index ? '' : '___'.$index);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
  }
303
 
304
  /**
336
  /**
337
  * Loads a template.
338
  *
339
+ * @param string|TemplateWrapper $name The template name
340
  *
341
  * @throws LoaderError When the template cannot be found
342
  * @throws RuntimeError When a previously generated cache is corrupted
351
  }
352
 
353
  if ($name instanceof Template) {
354
+ @trigger_error('Passing a \Twig\Template instance to '.__METHOD__.' is deprecated since Twig 2.7.0, use \Twig\TemplateWrapper instead.', \E_USER_DEPRECATED);
355
+
356
  return new TemplateWrapper($this, $name);
357
  }
358
 
368
  * @param string $name The template name
369
  * @param int $index The index if it is an embedded template
370
  *
371
+ * @return Template A template instance representing the given template name
372
  *
373
  * @throws LoaderError When the template cannot be found
374
  * @throws RuntimeError When a previously generated cache is corrupted
396
  }
397
 
398
  if (!class_exists($cls, false)) {
399
+ $key = $this->cache->generateKey($name, $mainCls);
 
 
 
 
400
 
401
  if (!$this->isAutoReload() || $this->isTemplateFresh($name, $this->cache->getTimestamp($key))) {
402
  $this->cache->load($key);
404
 
405
  $source = null;
406
  if (!class_exists($cls, false)) {
407
+ $source = $this->getLoader()->getSourceContext($name);
 
 
 
 
 
 
408
  $content = $this->compileSource($source);
409
+ $this->cache->write($key, $content);
410
+ $this->cache->load($key);
 
 
 
 
 
411
 
412
  if (!class_exists($mainCls, false)) {
413
  /* Last line of defense if either $this->bcWriteCacheFile was used,
417
  */
418
  eval('?>'.$content);
419
  }
 
420
 
421
+ if (!class_exists($cls, false)) {
422
+ throw new RuntimeError(sprintf('Failed to load Twig template "%s", index "%s": cache might be corrupted.', $name, $index), -1, $source);
423
+ }
424
  }
425
  }
426
 
427
+ // to be removed in 3.0
428
+ $this->extensionSet->initRuntime($this);
 
429
 
430
  return $this->loadedTemplates[$cls] = new $cls($this);
431
  }
443
  * @throws LoaderError When the template cannot be found
444
  * @throws SyntaxError When an error occurred during compilation
445
  */
446
+ public function createTemplate($template, string $name = null)
447
  {
448
+ $hash = hash(\PHP_VERSION_ID < 80100 ? 'sha256' : 'xxh128', $template, false);
449
  if (null !== $name) {
450
  $name = sprintf('%s (string template %s)', $name, $hash);
451
  } else {
459
 
460
  $this->setLoader($loader);
461
  try {
462
+ return new TemplateWrapper($this, $this->loadTemplate($name));
463
+ } finally {
464
  $this->setLoader($current);
 
 
 
 
 
 
465
  }
 
 
 
466
  }
467
 
468
  /**
479
  */
480
  public function isTemplateFresh($name, $time)
481
  {
482
+ return $this->extensionSet->getLastModified() <= $time && $this->getLoader()->isFresh($name, $time);
 
 
 
 
 
 
 
 
 
483
  }
484
 
485
  /**
488
  * Similar to load() but it also accepts instances of \Twig\Template and
489
  * \Twig\TemplateWrapper, and an array of templates where each is tried to be loaded.
490
  *
491
+ * @param string|TemplateWrapper|array $names A template or an array of templates to try consecutively
492
  *
493
  * @return TemplateWrapper|Template
494
  *
501
  $names = [$names];
502
  }
503
 
504
+ $count = \count($names);
505
  foreach ($names as $name) {
506
  if ($name instanceof Template) {
507
  return $name;
510
  return $name;
511
  }
512
 
513
+ if (1 !== $count && !$this->getLoader()->exists($name)) {
514
+ continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
515
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
516
 
517
+ return $this->loadTemplate($name);
 
518
  }
519
 
520
+ throw new LoaderError(sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names)));
521
  }
522
 
523
+ public function setLexer(Lexer $lexer)
524
  {
525
  $this->lexer = $lexer;
526
  }
528
  /**
529
  * Tokenizes a source code.
530
  *
 
 
 
531
  * @return TokenStream
532
  *
533
  * @throws SyntaxError When the code is syntactically wrong
534
  */
535
+ public function tokenize(Source $source)
536
  {
 
 
 
 
 
537
  if (null === $this->lexer) {
538
  $this->lexer = new Lexer($this);
539
  }
541
  return $this->lexer->tokenize($source);
542
  }
543
 
544
+ public function setParser(Parser $parser)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
545
  {
546
  $this->parser = $parser;
547
  }
562
  return $this->parser->parse($stream);
563
  }
564
 
565
+ public function setCompiler(Compiler $compiler)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
566
  {
567
  $this->compiler = $compiler;
568
  }
572
  *
573
  * @return string The compiled PHP source code
574
  */
575
+ public function compile(Node $node)
576
  {
577
  if (null === $this->compiler) {
578
  $this->compiler = new Compiler($this);
584
  /**
585
  * Compiles a template source code.
586
  *
 
 
 
587
  * @return string The compiled PHP source code
588
  *
589
  * @throws SyntaxError When there was an error during tokenizing, parsing or compiling
590
  */
591
+ public function compileSource(Source $source)
592
  {
 
 
 
 
 
593
  try {
594
  return $this->compile($this->parse($this->tokenize($source)));
595
  } catch (Error $e) {
602
 
603
  public function setLoader(LoaderInterface $loader)
604
  {
 
 
 
 
605
  $this->loader = $loader;
606
  }
607
 
612
  */
613
  public function getLoader()
614
  {
 
 
 
 
615
  return $this->loader;
616
  }
617
 
622
  */
623
  public function setCharset($charset)
624
  {
625
+ if ('UTF8' === $charset = null === $charset ? null : strtoupper($charset)) {
626
+ // iconv on Windows requires "UTF-8" instead of "UTF8"
627
+ $charset = 'UTF-8';
628
+ }
629
+
630
+ $this->charset = $charset;
631
  }
632
 
633
  /**
640
  return $this->charset;
641
  }
642
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
643
  /**
644
  * Returns true if the given extension is registered.
645
  *
649
  */
650
  public function hasExtension($class)
651
  {
652
+ return $this->extensionSet->hasExtension($class);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
653
  }
654
 
655
  /**
669
  */
670
  public function getExtension($class)
671
  {
672
+ return $this->extensionSet->getExtension($class);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
673
  }
674
 
675
  /**
698
 
699
  public function addExtension(ExtensionInterface $extension)
700
  {
701
+ $this->extensionSet->addExtension($extension);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
702
  $this->updateOptionsHash();
703
  }
704
 
709
  */
710
  public function setExtensions(array $extensions)
711
  {
712
+ $this->extensionSet->setExtensions($extensions);
713
+ $this->updateOptionsHash();
 
714
  }
715
 
716
  /**
720
  */
721
  public function getExtensions()
722
  {
723
+ return $this->extensionSet->getExtensions();
724
  }
725
 
726
  public function addTokenParser(TokenParserInterface $parser)
727
  {
728
+ $this->extensionSet->addTokenParser($parser);
 
 
 
 
729
  }
730
 
731
  /**
732
  * Gets the registered Token Parsers.
733
  *
734
+ * @return TokenParserInterface[]
735
  *
736
  * @internal
737
  */
738
  public function getTokenParsers()
739
  {
740
+ return $this->extensionSet->getTokenParsers();
 
 
 
 
741
  }
742
 
743
  /**
744
  * Gets registered tags.
745
  *
 
 
746
  * @return TokenParserInterface[]
747
  *
748
  * @internal
750
  public function getTags()
751
  {
752
  $tags = [];
753
+ foreach ($this->getTokenParsers() as $parser) {
754
+ $tags[$parser->getTag()] = $parser;
 
 
755
  }
756
 
757
  return $tags;
759
 
760
  public function addNodeVisitor(NodeVisitorInterface $visitor)
761
  {
762
+ $this->extensionSet->addNodeVisitor($visitor);
 
 
 
 
763
  }
764
 
765
  /**
771
  */
772
  public function getNodeVisitors()
773
  {
774
+ return $this->extensionSet->getNodeVisitors();
 
 
 
 
775
  }
776
 
777
+ public function addFilter(TwigFilter $filter)
 
 
 
 
 
 
778
  {
779
+ $this->extensionSet->addFilter($filter);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
780
  }
781
 
782
  /**
787
  *
788
  * @param string $name The filter name
789
  *
790
+ * @return TwigFilter|false
791
  *
792
  * @internal
793
  */
794
  public function getFilter($name)
795
  {
796
+ return $this->extensionSet->getFilter($name);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
797
  }
798
 
799
+ public function registerUndefinedFilterCallback(callable $callable)
800
  {
801
+ $this->extensionSet->registerUndefinedFilterCallback($callable);
802
  }
803
 
804
  /**
806
  *
807
  * Be warned that this method cannot return filters defined with registerUndefinedFilterCallback.
808
  *
809
+ * @return TwigFilter[]
810
  *
811
  * @see registerUndefinedFilterCallback
812
  *
814
  */
815
  public function getFilters()
816
  {
817
+ return $this->extensionSet->getFilters();
 
 
 
 
818
  }
819
 
820
+ public function addTest(TwigTest $test)
 
 
 
 
 
 
821
  {
822
+ $this->extensionSet->addTest($test);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
823
  }
824
 
825
  /**
826
  * Gets the registered Tests.
827
  *
828
+ * @return TwigTest[]
829
  *
830
  * @internal
831
  */
832
  public function getTests()
833
  {
834
+ return $this->extensionSet->getTests();
 
 
 
 
835
  }
836
 
837
  /**
839
  *
840
  * @param string $name The test name
841
  *
842
+ * @return TwigTest|false
843
  *
844
  * @internal
845
  */
846
  public function getTest($name)
847
  {
848
+ return $this->extensionSet->getTest($name);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
849
  }
850
 
851
+ public function addFunction(TwigFunction $function)
 
 
 
 
 
 
852
  {
853
+ $this->extensionSet->addFunction($function);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
854
  }
855
 
856
  /**
861
  *
862
  * @param string $name function name
863
  *
864
+ * @return TwigFunction|false
865
  *
866
  * @internal
867
  */
868
  public function getFunction($name)
869
  {
870
+ return $this->extensionSet->getFunction($name);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
871
  }
872
 
873
+ public function registerUndefinedFunctionCallback(callable $callable)
874
  {
875
+ $this->extensionSet->registerUndefinedFunctionCallback($callable);
876
  }
877
 
878
  /**
880
  *
881
  * Be warned that this method cannot return functions defined with registerUndefinedFunctionCallback.
882
  *
883
+ * @return TwigFunction[]
884
  *
885
  * @see registerUndefinedFunctionCallback
886
  *
888
  */
889
  public function getFunctions()
890
  {
891
+ return $this->extensionSet->getFunctions();
 
 
 
 
892
  }
893
 
894
  /**
902
  */
903
  public function addGlobal($name, $value)
904
  {
905
+ if ($this->extensionSet->isInitialized() && !\array_key_exists($name, $this->getGlobals())) {
906
+ throw new \LogicException(sprintf('Unable to add global "%s" as the runtime or the extensions have already been initialized.', $name));
 
 
 
 
 
 
 
 
907
  }
908
 
909
+ if (null !== $this->resolvedGlobals) {
910
+ $this->resolvedGlobals[$name] = $value;
 
911
  } else {
912
+ $this->globals[$name] = $value;
913
  }
914
  }
915
 
922
  */
923
  public function getGlobals()
924
  {
925
+ if ($this->extensionSet->isInitialized()) {
926
+ if (null === $this->resolvedGlobals) {
927
+ $this->resolvedGlobals = array_merge($this->extensionSet->getGlobals(), $this->globals);
928
+ }
929
 
930
+ return $this->resolvedGlobals;
 
931
  }
932
 
933
+ return array_merge($this->extensionSet->getGlobals(), $this->globals);
934
  }
935
 
936
  /**
962
  */
963
  public function getUnaryOperators()
964
  {
965
+ return $this->extensionSet->getUnaryOperators();
 
 
 
 
966
  }
967
 
968
  /**
974
  */
975
  public function getBinaryOperators()
976
  {
977
+ return $this->extensionSet->getBinaryOperators();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
978
  }
979
 
980
  private function updateOptionsHash()
981
  {
982
+ $this->optionsHash = implode(':', [
983
+ $this->extensionSet->getSignature(),
984
+ \PHP_MAJOR_VERSION,
985
+ \PHP_MINOR_VERSION,
986
+ self::VERSION,
987
+ (int) $this->debug,
988
+ $this->baseTemplateClass,
989
+ (int) $this->strictVariables,
990
+ ]);
 
 
 
 
991
  }
992
  }
993
 
vendor/twig/twig/src/Error/Error.php CHANGED
@@ -38,11 +38,9 @@ use Twig\Template;
38
  */
39
  class Error extends \Exception
40
  {
41
- protected $lineno;
42
- // to be renamed to name in 2.0
43
- protected $filename;
44
- protected $rawMessage;
45
-
46
  private $sourcePath;
47
  private $sourceCode;
48
 
@@ -57,22 +55,23 @@ class Error extends \Exception
57
  * @param Source|string|null $source The source context where the error occurred
58
  * @param \Exception $previous The previous exception
59
  */
60
- public function __construct($message, $lineno = -1, $source = null, \Exception $previous = null)
61
  {
 
 
62
  if (null === $source) {
63
  $name = null;
64
- } elseif (!$source instanceof Source) {
65
- // for compat with the Twig C ext., passing the template name as string is accepted
66
  $name = $source;
67
  } else {
68
  $name = $source->getName();
69
  $this->sourceCode = $source->getCode();
70
  $this->sourcePath = $source->getPath();
71
  }
72
- parent::__construct('', 0, $previous);
73
 
74
  $this->lineno = $lineno;
75
- $this->filename = $name;
76
  $this->rawMessage = $message;
77
  $this->updateRepr();
78
  }
@@ -87,67 +86,6 @@ class Error extends \Exception
87
  return $this->rawMessage;
88
  }
89
 
90
- /**
91
- * Gets the logical name where the error occurred.
92
- *
93
- * @return string The name
94
- *
95
- * @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead.
96
- */
97
- public function getTemplateFile()
98
- {
99
- @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);
100
-
101
- return $this->filename;
102
- }
103
-
104
- /**
105
- * Sets the logical name where the error occurred.
106
- *
107
- * @param string $name The name
108
- *
109
- * @deprecated since 1.27 (to be removed in 2.0). Use setSourceContext() instead.
110
- */
111
- public function setTemplateFile($name)
112
- {
113
- @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);
114
-
115
- $this->filename = $name;
116
-
117
- $this->updateRepr();
118
- }
119
-
120
- /**
121
- * Gets the logical name where the error occurred.
122
- *
123
- * @return string The name
124
- *
125
- * @deprecated since 1.29 (to be removed in 2.0). Use getSourceContext() instead.
126
- */
127
- public function getTemplateName()
128
- {
129
- @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);
130
-
131
- return $this->filename;
132
- }
133
-
134
- /**
135
- * Sets the logical name where the error occurred.
136
- *
137
- * @param string $name The name
138
- *
139
- * @deprecated since 1.29 (to be removed in 2.0). Use setSourceContext() instead.
140
- */
141
- public function setTemplateName($name)
142
- {
143
- @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);
144
-
145
- $this->filename = $name;
146
- $this->sourceCode = $this->sourcePath = null;
147
-
148
- $this->updateRepr();
149
- }
150
-
151
  /**
152
  * Gets the template line where the error occurred.
153
  *
@@ -177,7 +115,7 @@ class Error extends \Exception
177
  */
178
  public function getSourceContext()
179
  {
180
- return $this->filename ? new Source($this->sourceCode, $this->filename, $this->sourcePath) : null;
181
  }
182
 
183
  /**
@@ -186,10 +124,10 @@ class Error extends \Exception
186
  public function setSourceContext(Source $source = null)
187
  {
188
  if (null === $source) {
189
- $this->sourceCode = $this->filename = $this->sourcePath = null;
190
  } else {
191
  $this->sourceCode = $source->getCode();
192
- $this->filename = $source->getName();
193
  $this->sourcePath = $source->getPath();
194
  }
195
 
@@ -208,10 +146,7 @@ class Error extends \Exception
208
  $this->updateRepr();
209
  }
210
 
211
- /**
212
- * @internal
213
- */
214
- protected function updateRepr()
215
  {
216
  $this->message = $this->rawMessage;
217
 
@@ -234,11 +169,11 @@ class Error extends \Exception
234
  $questionMark = true;
235
  }
236
 
237
- if ($this->filename) {
238
- if (\is_string($this->filename) || (\is_object($this->filename) && method_exists($this->filename, '__toString'))) {
239
- $name = sprintf('"%s"', $this->filename);
240
  } else {
241
- $name = json_encode($this->filename);
242
  }
243
  $this->message .= sprintf(' in %s', $name);
244
  }
@@ -256,20 +191,17 @@ class Error extends \Exception
256
  }
257
  }
258
 
259
- /**
260
- * @internal
261
- */
262
- protected function guessTemplateInfo()
263
  {
264
  $template = null;
265
  $templateClass = null;
266
 
267
- $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS | DEBUG_BACKTRACE_PROVIDE_OBJECT);
268
  foreach ($backtrace as $trace) {
269
- if (isset($trace['object']) && $trace['object'] instanceof Template && 'Twig_Template' !== \get_class($trace['object'])) {
270
  $currentClass = \get_class($trace['object']);
271
- $isEmbedContainer = 0 === strpos($templateClass, $currentClass);
272
- if (null === $this->filename || ($this->filename == $trace['object']->getTemplateName() && !$isEmbedContainer)) {
273
  $template = $trace['object'];
274
  $templateClass = \get_class($trace['object']);
275
  }
@@ -277,8 +209,8 @@ class Error extends \Exception
277
  }
278
 
279
  // update template name
280
- if (null !== $template && null === $this->filename) {
281
- $this->filename = $template->getTemplateName();
282
  }
283
 
284
  // update template path if any
@@ -296,7 +228,7 @@ class Error extends \Exception
296
  $file = $r->getFileName();
297
 
298
  $exceptions = [$e = $this];
299
- while ($e instanceof self && $e = $e->getPrevious()) {
300
  $exceptions[] = $e;
301
  }
302
 
38
  */
39
  class Error extends \Exception
40
  {
41
+ private $lineno;
42
+ private $name;
43
+ private $rawMessage;
 
 
44
  private $sourcePath;
45
  private $sourceCode;
46
 
55
  * @param Source|string|null $source The source context where the error occurred
56
  * @param \Exception $previous The previous exception
57
  */
58
+ public function __construct(string $message, int $lineno = -1, $source = null, \Exception $previous = null)
59
  {
60
+ parent::__construct('', 0, $previous);
61
+
62
  if (null === $source) {
63
  $name = null;
64
+ } elseif (!$source instanceof Source && !$source instanceof \Twig_Source) {
65
+ @trigger_error(sprintf('Passing a string as a source to %s is deprecated since Twig 2.6.1; pass a Twig\Source instance instead.', __CLASS__), \E_USER_DEPRECATED);
66
  $name = $source;
67
  } else {
68
  $name = $source->getName();
69
  $this->sourceCode = $source->getCode();
70
  $this->sourcePath = $source->getPath();
71
  }
 
72
 
73
  $this->lineno = $lineno;
74
+ $this->name = $name;
75
  $this->rawMessage = $message;
76
  $this->updateRepr();
77
  }
86
  return $this->rawMessage;
87
  }
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  /**
90
  * Gets the template line where the error occurred.
91
  *
115
  */
116
  public function getSourceContext()
117
  {
118
+ return $this->name ? new Source($this->sourceCode, $this->name, $this->sourcePath) : null;
119
  }
120
 
121
  /**
124
  public function setSourceContext(Source $source = null)
125
  {
126
  if (null === $source) {
127
+ $this->sourceCode = $this->name = $this->sourcePath = null;
128
  } else {
129
  $this->sourceCode = $source->getCode();
130
+ $this->name = $source->getName();
131
  $this->sourcePath = $source->getPath();
132
  }
133
 
146
  $this->updateRepr();
147
  }
148
 
149
+ private function updateRepr()
 
 
 
150
  {
151
  $this->message = $this->rawMessage;
152
 
169
  $questionMark = true;
170
  }
171
 
172
+ if ($this->name) {
173
+ if (\is_string($this->name) || (\is_object($this->name) && method_exists($this->name, '__toString'))) {
174
+ $name = sprintf('"%s"', $this->name);
175
  } else {
176
+ $name = json_encode($this->name);
177
  }
178
  $this->message .= sprintf(' in %s', $name);
179
  }
191
  }
192
  }
193
 
194
+ private function guessTemplateInfo()
 
 
 
195
  {
196
  $template = null;
197
  $templateClass = null;
198
 
199
+ $backtrace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS | \DEBUG_BACKTRACE_PROVIDE_OBJECT);
200
  foreach ($backtrace as $trace) {
201
+ if (isset($trace['object']) && $trace['object'] instanceof Template && 'Twig\Template' !== \get_class($trace['object'])) {
202
  $currentClass = \get_class($trace['object']);
203
+ $isEmbedContainer = null === $templateClass ? false : 0 === strpos($templateClass, $currentClass);
204
+ if (null === $this->name || ($this->name == $trace['object']->getTemplateName() && !$isEmbedContainer)) {
205
  $template = $trace['object'];
206
  $templateClass = \get_class($trace['object']);
207
  }
209
  }
210
 
211
  // update template name
212
+ if (null !== $template && null === $this->name) {
213
+ $this->name = $template->getTemplateName();
214
  }
215
 
216
  // update template path if any
228
  $file = $r->getFileName();
229
 
230
  $exceptions = [$e = $this];
231
+ while ($e = $e->getPrevious()) {
232
  $exceptions[] = $e;
233
  }
234
 
vendor/twig/twig/src/Error/SyntaxError.php CHANGED
@@ -26,20 +26,6 @@ class SyntaxError extends Error
26
  * @param array $items An array of possible items
27
  */
28
  public function addSuggestions($name, array $items)
29
- {
30
- if (!$alternatives = self::computeAlternatives($name, $items)) {
31
- return;
32
- }
33
-
34
- $this->appendMessage(sprintf(' Did you mean "%s"?', implode('", "', $alternatives)));
35
- }
36
-
37
- /**
38
- * @internal
39
- *
40
- * To be merged with the addSuggestions() method in 2.0.
41
- */
42
- public static function computeAlternatives($name, $items)
43
  {
44
  $alternatives = [];
45
  foreach ($items as $item) {
@@ -48,9 +34,14 @@ class SyntaxError extends Error
48
  $alternatives[$item] = $lev;
49
  }
50
  }
 
 
 
 
 
51
  asort($alternatives);
52
 
53
- return array_keys($alternatives);
54
  }
55
  }
56
 
26
  * @param array $items An array of possible items
27
  */
28
  public function addSuggestions($name, array $items)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  {
30
  $alternatives = [];
31
  foreach ($items as $item) {
34
  $alternatives[$item] = $lev;
35
  }
36
  }
37
+
38
+ if (!$alternatives) {
39
+ return;
40
+ }
41
+
42
  asort($alternatives);
43
 
44
+ $this->appendMessage(sprintf(' Did you mean "%s"?', implode('", "', array_keys($alternatives))));
45
  }
46
  }
47
 
vendor/twig/twig/src/ExpressionParser.php CHANGED
@@ -13,6 +13,7 @@
13
  namespace Twig;
14
 
15
  use Twig\Error\SyntaxError;
 
16
  use Twig\Node\Expression\ArrayExpression;
17
  use Twig\Node\Expression\ArrowFunctionExpression;
18
  use Twig\Node\Expression\AssignNameExpression;
@@ -24,6 +25,7 @@ use Twig\Node\Expression\GetAttrExpression;
24
  use Twig\Node\Expression\MethodCallExpression;
25
  use Twig\Node\Expression\NameExpression;
26
  use Twig\Node\Expression\ParentExpression;
 
27
  use Twig\Node\Expression\Unary\NegUnary;
28
  use Twig\Node\Expression\Unary\NotUnary;
29
  use Twig\Node\Expression\Unary\PosUnary;
@@ -43,30 +45,20 @@ use Twig\Node\Node;
43
  */
44
  class ExpressionParser
45
  {
46
- const OPERATOR_LEFT = 1;
47
- const OPERATOR_RIGHT = 2;
48
-
49
- protected $parser;
50
- protected $unaryOperators;
51
- protected $binaryOperators;
52
 
 
53
  private $env;
 
 
54
 
55
- public function __construct(Parser $parser, $env = null)
56
  {
57
  $this->parser = $parser;
58
-
59
- if ($env instanceof Environment) {
60
- $this->env = $env;
61
- $this->unaryOperators = $env->getUnaryOperators();
62
- $this->binaryOperators = $env->getBinaryOperators();
63
- } else {
64
- @trigger_error('Passing the operators as constructor arguments to '.__METHOD__.' is deprecated since version 1.27. Pass the environment instead.', E_USER_DEPRECATED);
65
-
66
- $this->env = $parser->getEnvironment();
67
- $this->unaryOperators = func_get_arg(1);
68
- $this->binaryOperators = func_get_arg(2);
69
- }
70
  }
71
 
72
  public function parseExpression($precedence = 0, $allowArrow = false)
@@ -86,7 +78,7 @@ class ExpressionParser
86
  } elseif ('is' === $token->getValue()) {
87
  $expr = $this->parseTestExpression($expr);
88
  } elseif (isset($op['callable'])) {
89
- $expr = \call_user_func($op['callable'], $this->parser, $expr);
90
  } else {
91
  $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
92
  $class = $op['class'];
@@ -111,57 +103,57 @@ class ExpressionParser
111
  $stream = $this->parser->getStream();
112
 
113
  // short array syntax (one argument, no parentheses)?
114
- if ($stream->look(1)->test(Token::ARROW_TYPE)) {
115
  $line = $stream->getCurrent()->getLine();
116
- $token = $stream->expect(Token::NAME_TYPE);
117
  $names = [new AssignNameExpression($token->getValue(), $token->getLine())];
118
- $stream->expect(Token::ARROW_TYPE);
119
 
120
  return new ArrowFunctionExpression($this->parseExpression(0), new Node($names), $line);
121
  }
122
 
123
  // first, determine if we are parsing an arrow function by finding => (long form)
124
  $i = 0;
125
- if (!$stream->look($i)->test(Token::PUNCTUATION_TYPE, '(')) {
126
  return null;
127
  }
128
  ++$i;
129
  while (true) {
130
  // variable name
131
  ++$i;
132
- if (!$stream->look($i)->test(Token::PUNCTUATION_TYPE, ',')) {
133
  break;
134
  }
135
  ++$i;
136
  }
137
- if (!$stream->look($i)->test(Token::PUNCTUATION_TYPE, ')')) {
138
  return null;
139
  }
140
  ++$i;
141
- if (!$stream->look($i)->test(Token::ARROW_TYPE)) {
142
  return null;
143
  }
144
 
145
  // yes, let's parse it properly
146
- $token = $stream->expect(Token::PUNCTUATION_TYPE, '(');
147
  $line = $token->getLine();
148
 
149
  $names = [];
150
  while (true) {
151
- $token = $stream->expect(Token::NAME_TYPE);
152
  $names[] = new AssignNameExpression($token->getValue(), $token->getLine());
153
 
154
- if (!$stream->nextIf(Token::PUNCTUATION_TYPE, ',')) {
155
  break;
156
  }
157
  }
158
- $stream->expect(Token::PUNCTUATION_TYPE, ')');
159
- $stream->expect(Token::ARROW_TYPE);
160
 
161
  return new ArrowFunctionExpression($this->parseExpression(0), new Node($names), $line);
162
  }
163
 
164
- protected function getPrimary()
165
  {
166
  $token = $this->parser->getCurrentToken();
167
 
@@ -172,10 +164,10 @@ class ExpressionParser
172
  $class = $operator['class'];
173
 
174
  return $this->parsePostfixExpression(new $class($expr, $token->getLine()));
175
- } elseif ($token->test(Token::PUNCTUATION_TYPE, '(')) {
176
  $this->parser->getStream()->next();
177
  $expr = $this->parseExpression();
178
- $this->parser->getStream()->expect(Token::PUNCTUATION_TYPE, ')', 'An opened parenthesis is not properly closed');
179
 
180
  return $this->parsePostfixExpression($expr);
181
  }
@@ -183,12 +175,12 @@ class ExpressionParser
183
  return $this->parsePrimaryExpression();
184
  }
185
 
186
- protected function parseConditionalExpression($expr)
187
  {
188
- while ($this->parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, '?')) {
189
- if (!$this->parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, ':')) {
190
  $expr2 = $this->parseExpression();
191
- if ($this->parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, ':')) {
192
  $expr3 = $this->parseExpression();
193
  } else {
194
  $expr3 = new ConstantExpression('', $this->parser->getCurrentToken()->getLine());
@@ -204,21 +196,21 @@ class ExpressionParser
204
  return $expr;
205
  }
206
 
207
- protected function isUnary(Token $token)
208
  {
209
- return $token->test(Token::OPERATOR_TYPE) && isset($this->unaryOperators[$token->getValue()]);
210
  }
211
 
212
- protected function isBinary(Token $token)
213
  {
214
- return $token->test(Token::OPERATOR_TYPE) && isset($this->binaryOperators[$token->getValue()]);
215
  }
216
 
217
  public function parsePrimaryExpression()
218
  {
219
  $token = $this->parser->getCurrentToken();
220
  switch ($token->getType()) {
221
- case Token::NAME_TYPE:
222
  $this->parser->getStream()->next();
223
  switch ($token->getValue()) {
224
  case 'true':
@@ -247,17 +239,17 @@ class ExpressionParser
247
  }
248
  break;
249
 
250
- case Token::NUMBER_TYPE:
251
  $this->parser->getStream()->next();
252
  $node = new ConstantExpression($token->getValue(), $token->getLine());
253
  break;
254
 
255
- case Token::STRING_TYPE:
256
- case Token::INTERPOLATION_START_TYPE:
257
  $node = $this->parseStringExpression();
258
  break;
259
 
260
- case Token::OPERATOR_TYPE:
261
  if (preg_match(Lexer::REGEX_NAME, $token->getValue(), $matches) && $matches[0] == $token->getValue()) {
262
  // in this context, string operators are variable names
263
  $this->parser->getStream()->next();
@@ -267,10 +259,8 @@ class ExpressionParser
267
  $class = $this->unaryOperators[$token->getValue()]['class'];
268
 
269
  $ref = new \ReflectionClass($class);
270
- $negClass = 'Twig\Node\Expression\Unary\NegUnary';
271
- $posClass = 'Twig\Node\Expression\Unary\PosUnary';
272
- if (!(\in_array($ref->getName(), [$negClass, $posClass, 'Twig_Node_Expression_Unary_Neg', 'Twig_Node_Expression_Unary_Pos'])
273
- || $ref->isSubclassOf($negClass) || $ref->isSubclassOf($posClass)
274
  || $ref->isSubclassOf('Twig_Node_Expression_Unary_Neg') || $ref->isSubclassOf('Twig_Node_Expression_Unary_Pos'))
275
  ) {
276
  throw new SyntaxError(sprintf('Unexpected unary operator "%s".', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
@@ -285,11 +275,11 @@ class ExpressionParser
285
 
286
  // no break
287
  default:
288
- if ($token->test(Token::PUNCTUATION_TYPE, '[')) {
289
  $node = $this->parseArrayExpression();
290
- } elseif ($token->test(Token::PUNCTUATION_TYPE, '{')) {
291
  $node = $this->parseHashExpression();
292
- } elseif ($token->test(Token::OPERATOR_TYPE, '=') && ('==' === $this->parser->getStream()->look(-1)->getValue() || '!=' === $this->parser->getStream()->look(-1)->getValue())) {
293
  throw new 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());
294
  } else {
295
  throw new SyntaxError(sprintf('Unexpected token "%s" of value "%s".', Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
@@ -307,12 +297,12 @@ class ExpressionParser
307
  // a string cannot be followed by another string in a single expression
308
  $nextCanBeString = true;
309
  while (true) {
310
- if ($nextCanBeString && $token = $stream->nextIf(Token::STRING_TYPE)) {
311
  $nodes[] = new ConstantExpression($token->getValue(), $token->getLine());
312
  $nextCanBeString = false;
313
- } elseif ($stream->nextIf(Token::INTERPOLATION_START_TYPE)) {
314
  $nodes[] = $this->parseExpression();
315
- $stream->expect(Token::INTERPOLATION_END_TYPE);
316
  $nextCanBeString = true;
317
  } else {
318
  break;
@@ -330,16 +320,16 @@ class ExpressionParser
330
  public function parseArrayExpression()
331
  {
332
  $stream = $this->parser->getStream();
333
- $stream->expect(Token::PUNCTUATION_TYPE, '[', 'An array element was expected');
334
 
335
  $node = new ArrayExpression([], $stream->getCurrent()->getLine());
336
  $first = true;
337
- while (!$stream->test(Token::PUNCTUATION_TYPE, ']')) {
338
  if (!$first) {
339
- $stream->expect(Token::PUNCTUATION_TYPE, ',', 'An array element must be followed by a comma');
340
 
341
  // trailing ,?
342
- if ($stream->test(Token::PUNCTUATION_TYPE, ']')) {
343
  break;
344
  }
345
  }
@@ -347,7 +337,7 @@ class ExpressionParser
347
 
348
  $node->addElement($this->parseExpression());
349
  }
350
- $stream->expect(Token::PUNCTUATION_TYPE, ']', 'An opened array is not properly closed');
351
 
352
  return $node;
353
  }
@@ -355,16 +345,16 @@ class ExpressionParser
355
  public function parseHashExpression()
356
  {
357
  $stream = $this->parser->getStream();
358
- $stream->expect(Token::PUNCTUATION_TYPE, '{', 'A hash element was expected');
359
 
360
  $node = new ArrayExpression([], $stream->getCurrent()->getLine());
361
  $first = true;
362
- while (!$stream->test(Token::PUNCTUATION_TYPE, '}')) {
363
  if (!$first) {
364
- $stream->expect(Token::PUNCTUATION_TYPE, ',', 'A hash value must be followed by a comma');
365
 
366
  // trailing ,?
367
- if ($stream->test(Token::PUNCTUATION_TYPE, '}')) {
368
  break;
369
  }
370
  }
@@ -376,9 +366,18 @@ class ExpressionParser
376
  // * a string -- 'a'
377
  // * a name, which is equivalent to a string -- a
378
  // * an expression, which must be enclosed in parentheses -- (1 + 2)
379
- if (($token = $stream->nextIf(Token::STRING_TYPE)) || ($token = $stream->nextIf(Token::NAME_TYPE)) || $token = $stream->nextIf(Token::NUMBER_TYPE)) {
380
  $key = new ConstantExpression($token->getValue(), $token->getLine());
381
- } elseif ($stream->test(Token::PUNCTUATION_TYPE, '(')) {
 
 
 
 
 
 
 
 
 
382
  $key = $this->parseExpression();
383
  } else {
384
  $current = $stream->getCurrent();
@@ -386,12 +385,12 @@ class ExpressionParser
386
  throw new 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".', Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $stream->getSourceContext());
387
  }
388
 
389
- $stream->expect(Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
390
  $value = $this->parseExpression();
391
 
392
  $node->addElement($value, $key);
393
  }
394
- $stream->expect(Token::PUNCTUATION_TYPE, '}', 'An opened hash is not properly closed');
395
 
396
  return $node;
397
  }
@@ -400,7 +399,7 @@ class ExpressionParser
400
  {
401
  while (true) {
402
  $token = $this->parser->getCurrentToken();
403
- if (Token::PUNCTUATION_TYPE == $token->getType()) {
404
  if ('.' == $token->getValue() || '[' == $token->getValue()) {
405
  $node = $this->parseSubscriptExpression($node);
406
  } elseif ('|' == $token->getValue()) {
@@ -474,22 +473,22 @@ class ExpressionParser
474
  if ('.' == $token->getValue()) {
475
  $token = $stream->next();
476
  if (
477
- Token::NAME_TYPE == $token->getType()
478
  ||
479
- Token::NUMBER_TYPE == $token->getType()
480
  ||
481
- (Token::OPERATOR_TYPE == $token->getType() && preg_match(Lexer::REGEX_NAME, $token->getValue()))
482
  ) {
483
  $arg = new ConstantExpression($token->getValue(), $lineno);
484
 
485
- if ($stream->test(Token::PUNCTUATION_TYPE, '(')) {
486
  $type = Template::METHOD_CALL;
487
  foreach ($this->parseArguments() as $n) {
488
  $arguments->addElement($n);
489
  }
490
  }
491
  } else {
492
- throw new SyntaxError('Expected name or number.', $lineno, $stream->getSourceContext());
493
  }
494
 
495
  if ($node instanceof NameExpression && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {
@@ -499,11 +498,7 @@ class ExpressionParser
499
 
500
  $name = $arg->getAttribute('value');
501
 
502
- if ($this->parser->isReservedMacroName($name)) {
503
- throw new SyntaxError(sprintf('"%s" cannot be called as macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext());
504
- }
505
-
506
- $node = new MethodCallExpression($node, 'get'.$name, $arguments, $lineno);
507
  $node->setAttribute('safe', true);
508
 
509
  return $node;
@@ -513,19 +508,19 @@ class ExpressionParser
513
 
514
  // slice?
515
  $slice = false;
516
- if ($stream->test(Token::PUNCTUATION_TYPE, ':')) {
517
  $slice = true;
518
  $arg = new ConstantExpression(0, $token->getLine());
519
  } else {
520
  $arg = $this->parseExpression();
521
  }
522
 
523
- if ($stream->nextIf(Token::PUNCTUATION_TYPE, ':')) {
524
  $slice = true;
525
  }
526
 
527
  if ($slice) {
528
- if ($stream->test(Token::PUNCTUATION_TYPE, ']')) {
529
  $length = new ConstantExpression(null, $token->getLine());
530
  } else {
531
  $length = $this->parseExpression();
@@ -535,12 +530,12 @@ class ExpressionParser
535
  $arguments = new Node([$arg, $length]);
536
  $filter = new $class($node, new ConstantExpression('slice', $token->getLine()), $arguments, $token->getLine());
537
 
538
- $stream->expect(Token::PUNCTUATION_TYPE, ']');
539
 
540
  return $filter;
541
  }
542
 
543
- $stream->expect(Token::PUNCTUATION_TYPE, ']');
544
  }
545
 
546
  return new GetAttrExpression($node, $arg, $arguments, $type, $lineno);
@@ -556,10 +551,10 @@ class ExpressionParser
556
  public function parseFilterExpressionRaw($node, $tag = null)
557
  {
558
  while (true) {
559
- $token = $this->parser->getStream()->expect(Token::NAME_TYPE);
560
 
561
  $name = new ConstantExpression($token->getValue(), $token->getLine());
562
- if (!$this->parser->getStream()->test(Token::PUNCTUATION_TYPE, '(')) {
563
  $arguments = new Node();
564
  } else {
565
  $arguments = $this->parseArguments(true, false, true);
@@ -569,7 +564,7 @@ class ExpressionParser
569
 
570
  $node = new $class($node, $name, $arguments, $token->getLine(), $tag);
571
 
572
- if (!$this->parser->getStream()->test(Token::PUNCTUATION_TYPE, '|')) {
573
  break;
574
  }
575
 
@@ -594,21 +589,26 @@ class ExpressionParser
594
  $args = [];
595
  $stream = $this->parser->getStream();
596
 
597
- $stream->expect(Token::PUNCTUATION_TYPE, '(', 'A list of arguments must begin with an opening parenthesis');
598
- while (!$stream->test(Token::PUNCTUATION_TYPE, ')')) {
599
  if (!empty($args)) {
600
- $stream->expect(Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma');
 
 
 
 
 
601
  }
602
 
603
  if ($definition) {
604
- $token = $stream->expect(Token::NAME_TYPE, null, 'An argument must be a name');
605
  $value = new NameExpression($token->getValue(), $this->parser->getCurrentToken()->getLine());
606
  } else {
607
  $value = $this->parseExpression(0, $allowArrow);
608
  }
609
 
610
  $name = null;
611
- if ($namedArguments && $token = $stream->nextIf(Token::OPERATOR_TYPE, '=')) {
612
  if (!$value instanceof NameExpression) {
613
  throw new SyntaxError(sprintf('A parameter name must be a string, "%s" given.', \get_class($value)), $token->getLine(), $stream->getSourceContext());
614
  }
@@ -618,7 +618,7 @@ class ExpressionParser
618
  $value = $this->parsePrimaryExpression();
619
 
620
  if (!$this->checkConstantExpression($value)) {
621
- throw new 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());
622
  }
623
  } else {
624
  $value = $this->parseExpression(0, $allowArrow);
@@ -639,7 +639,7 @@ class ExpressionParser
639
  }
640
  }
641
  }
642
- $stream->expect(Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis');
643
 
644
  return new Node($args);
645
  }
@@ -650,11 +650,11 @@ class ExpressionParser
650
  $targets = [];
651
  while (true) {
652
  $token = $this->parser->getCurrentToken();
653
- if ($stream->test(Token::OPERATOR_TYPE) && preg_match(Lexer::REGEX_NAME, $token->getValue())) {
654
  // in this context, string operators are variable names
655
  $this->parser->getStream()->next();
656
  } else {
657
- $stream->expect(Token::NAME_TYPE, null, 'Only variables can be assigned to');
658
  }
659
  $value = $token->getValue();
660
  if (\in_array(strtr($value, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), ['true', 'false', 'none', 'null'])) {
@@ -662,7 +662,7 @@ class ExpressionParser
662
  }
663
  $targets[] = new AssignNameExpression($value, $token->getLine());
664
 
665
- if (!$stream->nextIf(Token::PUNCTUATION_TYPE, ',')) {
666
  break;
667
  }
668
  }
@@ -675,7 +675,7 @@ class ExpressionParser
675
  $targets = [];
676
  while (true) {
677
  $targets[] = $this->parseExpression();
678
- if (!$this->parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, ',')) {
679
  break;
680
  }
681
  }
@@ -683,35 +683,42 @@ class ExpressionParser
683
  return new Node($targets);
684
  }
685
 
686
- private function parseNotTestExpression(\Twig_NodeInterface $node)
687
  {
688
  return new NotUnary($this->parseTestExpression($node), $this->parser->getCurrentToken()->getLine());
689
  }
690
 
691
- private function parseTestExpression(\Twig_NodeInterface $node)
692
  {
693
  $stream = $this->parser->getStream();
694
  list($name, $test) = $this->getTest($node->getTemplateLine());
695
 
696
  $class = $this->getTestNodeClass($test);
697
  $arguments = null;
698
- if ($stream->test(Token::PUNCTUATION_TYPE, '(')) {
699
  $arguments = $this->parseArguments(true);
 
 
 
 
 
 
 
700
  }
701
 
702
  return new $class($node, $name, $arguments, $this->parser->getCurrentToken()->getLine());
703
  }
704
 
705
- private function getTest($line)
706
  {
707
  $stream = $this->parser->getStream();
708
- $name = $stream->expect(Token::NAME_TYPE)->getValue();
709
 
710
  if ($test = $this->env->getTest($name)) {
711
  return [$name, $test];
712
  }
713
 
714
- if ($stream->test(Token::NAME_TYPE)) {
715
  // try 2-words tests
716
  $name = $name.' '.$this->parser->getCurrentToken()->getValue();
717
 
@@ -728,11 +735,12 @@ class ExpressionParser
728
  throw $e;
729
  }
730
 
731
- private function getTestNodeClass($test)
732
  {
733
- if ($test instanceof TwigTest && $test->isDeprecated()) {
734
  $stream = $this->parser->getStream();
735
  $message = sprintf('Twig Test "%s" is deprecated', $test->getName());
 
736
  if (!\is_bool($test->getDeprecatedVersion())) {
737
  $message .= sprintf(' since version %s', $test->getDeprecatedVersion());
738
  }
@@ -740,19 +748,15 @@ class ExpressionParser
740
  $message .= sprintf('. Use "%s" instead', $test->getAlternative());
741
  }
742
  $src = $stream->getSourceContext();
743
- $message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $stream->getCurrent()->getLine());
744
 
745
- @trigger_error($message, E_USER_DEPRECATED);
746
  }
747
 
748
- if ($test instanceof TwigTest) {
749
- return $test->getNodeClass();
750
- }
751
-
752
- return $test instanceof \Twig_Test_Node ? $test->getClass() : 'Twig\Node\Expression\TestExpression';
753
  }
754
 
755
- protected function getFunctionNodeClass($name, $line)
756
  {
757
  if (false === $function = $this->env->getFunction($name)) {
758
  $e = new SyntaxError(sprintf('Unknown "%s" function.', $name), $line, $this->parser->getStream()->getSourceContext());
@@ -761,7 +765,7 @@ class ExpressionParser
761
  throw $e;
762
  }
763
 
764
- if ($function instanceof TwigFunction && $function->isDeprecated()) {
765
  $message = sprintf('Twig Function "%s" is deprecated', $function->getName());
766
  if (!\is_bool($function->getDeprecatedVersion())) {
767
  $message .= sprintf(' since version %s', $function->getDeprecatedVersion());
@@ -770,19 +774,15 @@ class ExpressionParser
770
  $message .= sprintf('. Use "%s" instead', $function->getAlternative());
771
  }
772
  $src = $this->parser->getStream()->getSourceContext();
773
- $message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $line);
774
-
775
- @trigger_error($message, E_USER_DEPRECATED);
776
- }
777
 
778
- if ($function instanceof TwigFunction) {
779
- return $function->getNodeClass();
780
  }
781
 
782
- return $function instanceof \Twig_Function_Node ? $function->getClass() : 'Twig\Node\Expression\FunctionExpression';
783
  }
784
 
785
- protected function getFilterNodeClass($name, $line)
786
  {
787
  if (false === $filter = $this->env->getFilter($name)) {
788
  $e = new SyntaxError(sprintf('Unknown "%s" filter.', $name), $line, $this->parser->getStream()->getSourceContext());
@@ -791,7 +791,7 @@ class ExpressionParser
791
  throw $e;
792
  }
793
 
794
- if ($filter instanceof TwigFilter && $filter->isDeprecated()) {
795
  $message = sprintf('Twig Filter "%s" is deprecated', $filter->getName());
796
  if (!\is_bool($filter->getDeprecatedVersion())) {
797
  $message .= sprintf(' since version %s', $filter->getDeprecatedVersion());
@@ -800,20 +800,16 @@ class ExpressionParser
800
  $message .= sprintf('. Use "%s" instead', $filter->getAlternative());
801
  }
802
  $src = $this->parser->getStream()->getSourceContext();
803
- $message .= sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $line);
804
-
805
- @trigger_error($message, E_USER_DEPRECATED);
806
- }
807
 
808
- if ($filter instanceof TwigFilter) {
809
- return $filter->getNodeClass();
810
  }
811
 
812
- return $filter instanceof \Twig_Filter_Node ? $filter->getClass() : 'Twig\Node\Expression\FilterExpression';
813
  }
814
 
815
  // checks that the node only contains "constant" elements
816
- protected function checkConstantExpression(\Twig_NodeInterface $node)
817
  {
818
  if (!($node instanceof ConstantExpression || $node instanceof ArrayExpression
819
  || $node instanceof NegUnary || $node instanceof PosUnary
13
  namespace Twig;
14
 
15
  use Twig\Error\SyntaxError;
16
+ use Twig\Node\Expression\AbstractExpression;
17
  use Twig\Node\Expression\ArrayExpression;
18
  use Twig\Node\Expression\ArrowFunctionExpression;
19
  use Twig\Node\Expression\AssignNameExpression;
25
  use Twig\Node\Expression\MethodCallExpression;
26
  use Twig\Node\Expression\NameExpression;
27
  use Twig\Node\Expression\ParentExpression;
28
+ use Twig\Node\Expression\TestExpression;
29
  use Twig\Node\Expression\Unary\NegUnary;
30
  use Twig\Node\Expression\Unary\NotUnary;
31
  use Twig\Node\Expression\Unary\PosUnary;
45
  */
46
  class ExpressionParser
47
  {
48
+ public const OPERATOR_LEFT = 1;
49
+ public const OPERATOR_RIGHT = 2;
 
 
 
 
50
 
51
+ private $parser;
52
  private $env;
53
+ private $unaryOperators;
54
+ private $binaryOperators;
55
 
56
+ public function __construct(Parser $parser, Environment $env)
57
  {
58
  $this->parser = $parser;
59
+ $this->env = $env;
60
+ $this->unaryOperators = $env->getUnaryOperators();
61
+ $this->binaryOperators = $env->getBinaryOperators();
 
 
 
 
 
 
 
 
 
62
  }
63
 
64
  public function parseExpression($precedence = 0, $allowArrow = false)
78
  } elseif ('is' === $token->getValue()) {
79
  $expr = $this->parseTestExpression($expr);
80
  } elseif (isset($op['callable'])) {
81
+ $expr = $op['callable']($this->parser, $expr);
82
  } else {
83
  $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
84
  $class = $op['class'];
103
  $stream = $this->parser->getStream();
104
 
105
  // short array syntax (one argument, no parentheses)?
106
+ if ($stream->look(1)->test(/* Token::ARROW_TYPE */ 12)) {
107
  $line = $stream->getCurrent()->getLine();
108
+ $token = $stream->expect(/* Token::NAME_TYPE */ 5);
109
  $names = [new AssignNameExpression($token->getValue(), $token->getLine())];
110
+ $stream->expect(/* Token::ARROW_TYPE */ 12);
111
 
112
  return new ArrowFunctionExpression($this->parseExpression(0), new Node($names), $line);
113
  }
114
 
115
  // first, determine if we are parsing an arrow function by finding => (long form)
116
  $i = 0;
117
+ if (!$stream->look($i)->test(/* Token::PUNCTUATION_TYPE */ 9, '(')) {
118
  return null;
119
  }
120
  ++$i;
121
  while (true) {
122
  // variable name
123
  ++$i;
124
+ if (!$stream->look($i)->test(/* Token::PUNCTUATION_TYPE */ 9, ',')) {
125
  break;
126
  }
127
  ++$i;
128
  }
129
+ if (!$stream->look($i)->test(/* Token::PUNCTUATION_TYPE */ 9, ')')) {
130
  return null;
131
  }
132
  ++$i;
133
+ if (!$stream->look($i)->test(/* Token::ARROW_TYPE */ 12)) {
134
  return null;
135
  }
136
 
137
  // yes, let's parse it properly
138
+ $token = $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, '(');
139
  $line = $token->getLine();
140
 
141
  $names = [];
142
  while (true) {
143
+ $token = $stream->expect(/* Token::NAME_TYPE */ 5);
144
  $names[] = new AssignNameExpression($token->getValue(), $token->getLine());
145
 
146
+ if (!$stream->nextIf(/* Token::PUNCTUATION_TYPE */ 9, ',')) {
147
  break;
148
  }
149
  }
150
+ $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ')');
151
+ $stream->expect(/* Token::ARROW_TYPE */ 12);
152
 
153
  return new ArrowFunctionExpression($this->parseExpression(0), new Node($names), $line);
154
  }
155
 
156
+ private function getPrimary(): AbstractExpression
157
  {
158
  $token = $this->parser->getCurrentToken();
159
 
164
  $class = $operator['class'];
165
 
166
  return $this->parsePostfixExpression(new $class($expr, $token->getLine()));
167
+ } elseif ($token->test(/* Token::PUNCTUATION_TYPE */ 9, '(')) {
168
  $this->parser->getStream()->next();
169
  $expr = $this->parseExpression();
170
+ $this->parser->getStream()->expect(/* Token::PUNCTUATION_TYPE */ 9, ')', 'An opened parenthesis is not properly closed');
171
 
172
  return $this->parsePostfixExpression($expr);
173
  }
175
  return $this->parsePrimaryExpression();
176
  }
177
 
178
+ private function parseConditionalExpression($expr): AbstractExpression
179
  {
180
+ while ($this->parser->getStream()->nextIf(/* Token::PUNCTUATION_TYPE */ 9, '?')) {
181
+ if (!$this->parser->getStream()->nextIf(/* Token::PUNCTUATION_TYPE */ 9, ':')) {
182
  $expr2 = $this->parseExpression();
183
+ if ($this->parser->getStream()->nextIf(/* Token::PUNCTUATION_TYPE */ 9, ':')) {
184
  $expr3 = $this->parseExpression();
185
  } else {
186
  $expr3 = new ConstantExpression('', $this->parser->getCurrentToken()->getLine());
196
  return $expr;
197
  }
198
 
199
+ private function isUnary(Token $token): bool
200
  {
201
+ return $token->test(/* Token::OPERATOR_TYPE */ 8) && isset($this->unaryOperators[$token->getValue()]);
202
  }
203
 
204
+ private function isBinary(Token $token): bool
205
  {
206
+ return $token->test(/* Token::OPERATOR_TYPE */ 8) && isset($this->binaryOperators[$token->getValue()]);
207
  }
208
 
209
  public function parsePrimaryExpression()
210
  {
211
  $token = $this->parser->getCurrentToken();
212
  switch ($token->getType()) {
213
+ case /* Token::NAME_TYPE */ 5:
214
  $this->parser->getStream()->next();
215
  switch ($token->getValue()) {
216
  case 'true':
239
  }
240
  break;
241
 
242
+ case /* Token::NUMBER_TYPE */ 6:
243
  $this->parser->getStream()->next();
244
  $node = new ConstantExpression($token->getValue(), $token->getLine());
245
  break;
246
 
247
+ case /* Token::STRING_TYPE */ 7:
248
+ case /* Token::INTERPOLATION_START_TYPE */ 10:
249
  $node = $this->parseStringExpression();
250
  break;
251
 
252
+ case /* Token::OPERATOR_TYPE */ 8:
253
  if (preg_match(Lexer::REGEX_NAME, $token->getValue(), $matches) && $matches[0] == $token->getValue()) {
254
  // in this context, string operators are variable names
255
  $this->parser->getStream()->next();
259
  $class = $this->unaryOperators[$token->getValue()]['class'];
260
 
261
  $ref = new \ReflectionClass($class);
262
+ if (!(\in_array($ref->getName(), [NegUnary::class, PosUnary::class, 'Twig_Node_Expression_Unary_Neg', 'Twig_Node_Expression_Unary_Pos'])
263
+ || $ref->isSubclassOf(NegUnary::class) || $ref->isSubclassOf(PosUnary::class)
 
 
264
  || $ref->isSubclassOf('Twig_Node_Expression_Unary_Neg') || $ref->isSubclassOf('Twig_Node_Expression_Unary_Pos'))
265
  ) {
266
  throw new SyntaxError(sprintf('Unexpected unary operator "%s".', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
275
 
276
  // no break
277
  default:
278
+ if ($token->test(/* Token::PUNCTUATION_TYPE */ 9, '[')) {
279
  $node = $this->parseArrayExpression();
280
+ } elseif ($token->test(/* Token::PUNCTUATION_TYPE */ 9, '{')) {
281
  $node = $this->parseHashExpression();
282
+ } elseif ($token->test(/* Token::OPERATOR_TYPE */ 8, '=') && ('==' === $this->parser->getStream()->look(-1)->getValue() || '!=' === $this->parser->getStream()->look(-1)->getValue())) {
283
  throw new 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());
284
  } else {
285
  throw new SyntaxError(sprintf('Unexpected token "%s" of value "%s".', Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
297
  // a string cannot be followed by another string in a single expression
298
  $nextCanBeString = true;
299
  while (true) {
300
+ if ($nextCanBeString && $token = $stream->nextIf(/* Token::STRING_TYPE */ 7)) {
301
  $nodes[] = new ConstantExpression($token->getValue(), $token->getLine());
302
  $nextCanBeString = false;
303
+ } elseif ($stream->nextIf(/* Token::INTERPOLATION_START_TYPE */ 10)) {
304
  $nodes[] = $this->parseExpression();
305
+ $stream->expect(/* Token::INTERPOLATION_END_TYPE */ 11);
306
  $nextCanBeString = true;
307
  } else {
308
  break;
320
  public function parseArrayExpression()
321
  {
322
  $stream = $this->parser->getStream();
323
+ $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, '[', 'An array element was expected');
324
 
325
  $node = new ArrayExpression([], $stream->getCurrent()->getLine());
326
  $first = true;
327
+ while (!$stream->test(/* Token::PUNCTUATION_TYPE */ 9, ']')) {
328
  if (!$first) {
329
+ $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ',', 'An array element must be followed by a comma');
330
 
331
  // trailing ,?
332
+ if ($stream->test(/* Token::PUNCTUATION_TYPE */ 9, ']')) {
333
  break;
334
  }
335
  }
337
 
338
  $node->addElement($this->parseExpression());
339
  }
340
+ $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ']', 'An opened array is not properly closed');
341
 
342
  return $node;
343
  }
345
  public function parseHashExpression()
346
  {
347
  $stream = $this->parser->getStream();
348
+ $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, '{', 'A hash element was expected');
349
 
350
  $node = new ArrayExpression([], $stream->getCurrent()->getLine());
351
  $first = true;
352
+ while (!$stream->test(/* Token::PUNCTUATION_TYPE */ 9, '}')) {
353
  if (!$first) {
354
+ $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ',', 'A hash value must be followed by a comma');
355
 
356
  // trailing ,?
357
+ if ($stream->test(/* Token::PUNCTUATION_TYPE */ 9, '}')) {
358
  break;
359
  }
360
  }
366
  // * a string -- 'a'
367
  // * a name, which is equivalent to a string -- a
368
  // * an expression, which must be enclosed in parentheses -- (1 + 2)
369
+ if ($token = $stream->nextIf(/* Token::NAME_TYPE */ 5)) {
370
  $key = new ConstantExpression($token->getValue(), $token->getLine());
371
+
372
+ // {a} is a shortcut for {a:a}
373
+ if ($stream->test(Token::PUNCTUATION_TYPE, [',', '}'])) {
374
+ $value = new NameExpression($key->getAttribute('value'), $key->getTemplateLine());
375
+ $node->addElement($value, $key);
376
+ continue;
377
+ }
378
+ } elseif (($token = $stream->nextIf(/* Token::STRING_TYPE */ 7)) || $token = $stream->nextIf(/* Token::NUMBER_TYPE */ 6)) {
379
+ $key = new ConstantExpression($token->getValue(), $token->getLine());
380
+ } elseif ($stream->test(/* Token::PUNCTUATION_TYPE */ 9, '(')) {
381
  $key = $this->parseExpression();
382
  } else {
383
  $current = $stream->getCurrent();
385
  throw new 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".', Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $stream->getSourceContext());
386
  }
387
 
388
+ $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ':', 'A hash key must be followed by a colon (:)');
389
  $value = $this->parseExpression();
390
 
391
  $node->addElement($value, $key);
392
  }
393
+ $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, '}', 'An opened hash is not properly closed');
394
 
395
  return $node;
396
  }
399
  {
400
  while (true) {
401
  $token = $this->parser->getCurrentToken();
402
+ if (/* Token::PUNCTUATION_TYPE */ 9 == $token->getType()) {
403
  if ('.' == $token->getValue() || '[' == $token->getValue()) {
404
  $node = $this->parseSubscriptExpression($node);
405
  } elseif ('|' == $token->getValue()) {
473
  if ('.' == $token->getValue()) {
474
  $token = $stream->next();
475
  if (
476
+ /* Token::NAME_TYPE */ 5 == $token->getType()
477
  ||
478
+ /* Token::NUMBER_TYPE */ 6 == $token->getType()
479
  ||
480
+ (/* Token::OPERATOR_TYPE */ 8 == $token->getType() && preg_match(Lexer::REGEX_NAME, $token->getValue()))
481
  ) {
482
  $arg = new ConstantExpression($token->getValue(), $lineno);
483
 
484
+ if ($stream->test(/* Token::PUNCTUATION_TYPE */ 9, '(')) {
485
  $type = Template::METHOD_CALL;
486
  foreach ($this->parseArguments() as $n) {
487
  $arguments->addElement($n);
488
  }
489
  }
490
  } else {
491
+ throw new SyntaxError(sprintf('Expected name or number, got value "%s" of type %s.', $token->getValue(), Token::typeToEnglish($token->getType())), $lineno, $stream->getSourceContext());
492
  }
493
 
494
  if ($node instanceof NameExpression && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {
498
 
499
  $name = $arg->getAttribute('value');
500
 
501
+ $node = new MethodCallExpression($node, 'macro_'.$name, $arguments, $lineno);
 
 
 
 
502
  $node->setAttribute('safe', true);
503
 
504
  return $node;
508
 
509
  // slice?
510
  $slice = false;
511
+ if ($stream->test(/* Token::PUNCTUATION_TYPE */ 9, ':')) {
512
  $slice = true;
513
  $arg = new ConstantExpression(0, $token->getLine());
514
  } else {
515
  $arg = $this->parseExpression();
516
  }
517
 
518
+ if ($stream->nextIf(/* Token::PUNCTUATION_TYPE */ 9, ':')) {
519
  $slice = true;
520
  }
521
 
522
  if ($slice) {
523
+ if ($stream->test(/* Token::PUNCTUATION_TYPE */ 9, ']')) {
524
  $length = new ConstantExpression(null, $token->getLine());
525
  } else {
526
  $length = $this->parseExpression();
530
  $arguments = new Node([$arg, $length]);
531
  $filter = new $class($node, new ConstantExpression('slice', $token->getLine()), $arguments, $token->getLine());
532
 
533
+ $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ']');
534
 
535
  return $filter;
536
  }
537
 
538
+ $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ']');
539
  }
540
 
541
  return new GetAttrExpression($node, $arg, $arguments, $type, $lineno);
551
  public function parseFilterExpressionRaw($node, $tag = null)
552
  {
553
  while (true) {
554
+ $token = $this->parser->getStream()->expect(/* Token::NAME_TYPE */ 5);
555
 
556
  $name = new ConstantExpression($token->getValue(), $token->getLine());
557
+ if (!$this->parser->getStream()->test(/* Token::PUNCTUATION_TYPE */ 9, '(')) {
558
  $arguments = new Node();
559
  } else {
560
  $arguments = $this->parseArguments(true, false, true);
564
 
565
  $node = new $class($node, $name, $arguments, $token->getLine(), $tag);
566
 
567
+ if (!$this->parser->getStream()->test(/* Token::PUNCTUATION_TYPE */ 9, '|')) {
568
  break;
569
  }
570
 
589
  $args = [];
590
  $stream = $this->parser->getStream();
591
 
592
+ $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, '(', 'A list of arguments must begin with an opening parenthesis');
593
+ while (!$stream->test(/* Token::PUNCTUATION_TYPE */ 9, ')')) {
594
  if (!empty($args)) {
595
+ $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ',', 'Arguments must be separated by a comma');
596
+
597
+ // if the comma above was a trailing comma, early exit the argument parse loop
598
+ if ($stream->test(/* Token::PUNCTUATION_TYPE */ 9, ')')) {
599
+ break;
600
+ }
601
  }
602
 
603
  if ($definition) {
604
+ $token = $stream->expect(/* Token::NAME_TYPE */ 5, null, 'An argument must be a name');
605
  $value = new NameExpression($token->getValue(), $this->parser->getCurrentToken()->getLine());
606
  } else {
607
  $value = $this->parseExpression(0, $allowArrow);
608
  }
609
 
610
  $name = null;
611
+ if ($namedArguments && $token = $stream->nextIf(/* Token::OPERATOR_TYPE */ 8, '=')) {
612
  if (!$value instanceof NameExpression) {
613
  throw new SyntaxError(sprintf('A parameter name must be a string, "%s" given.', \get_class($value)), $token->getLine(), $stream->getSourceContext());
614
  }
618
  $value = $this->parsePrimaryExpression();
619
 
620
  if (!$this->checkConstantExpression($value)) {
621
+ throw new SyntaxError('A default value for an argument must be a constant (a boolean, a string, a number, or an array).', $token->getLine(), $stream->getSourceContext());
622
  }
623
  } else {
624
  $value = $this->parseExpression(0, $allowArrow);
639
  }
640
  }
641
  }
642
+ $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ')', 'A list of arguments must be closed by a parenthesis');
643
 
644
  return new Node($args);
645
  }
650
  $targets = [];
651
  while (true) {
652
  $token = $this->parser->getCurrentToken();
653
+ if ($stream->test(/* Token::OPERATOR_TYPE */ 8) && preg_match(Lexer::REGEX_NAME, $token->getValue())) {
654
  // in this context, string operators are variable names
655
  $this->parser->getStream()->next();
656
  } else {
657
+ $stream->expect(/* Token::NAME_TYPE */ 5, null, 'Only variables can be assigned to');
658
  }
659
  $value = $token->getValue();
660
  if (\in_array(strtr($value, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), ['true', 'false', 'none', 'null'])) {
662
  }
663
  $targets[] = new AssignNameExpression($value, $token->getLine());
664
 
665
+ if (!$stream->nextIf(/* Token::PUNCTUATION_TYPE */ 9, ',')) {
666
  break;
667
  }
668
  }
675
  $targets = [];
676
  while (true) {
677
  $targets[] = $this->parseExpression();
678
+ if (!$this->parser->getStream()->nextIf(/* Token::PUNCTUATION_TYPE */ 9, ',')) {
679
  break;
680
  }
681
  }
683
  return new Node($targets);
684
  }
685
 
686
+ private function parseNotTestExpression(Node $node): NotUnary
687
  {
688
  return new NotUnary($this->parseTestExpression($node), $this->parser->getCurrentToken()->getLine());
689
  }
690
 
691
+ private function parseTestExpression(Node $node): TestExpression
692
  {
693
  $stream = $this->parser->getStream();
694
  list($name, $test) = $this->getTest($node->getTemplateLine());
695
 
696
  $class = $this->getTestNodeClass($test);
697
  $arguments = null;
698
+ if ($stream->test(/* Token::PUNCTUATION_TYPE */ 9, '(')) {
699
  $arguments = $this->parseArguments(true);
700
+ } elseif ($test->hasOneMandatoryArgument()) {
701
+ $arguments = new Node([0 => $this->parsePrimaryExpression()]);
702
+ }
703
+
704
+ if ('defined' === $name && $node instanceof NameExpression && null !== $alias = $this->parser->getImportedSymbol('function', $node->getAttribute('name'))) {
705
+ $node = new MethodCallExpression($alias['node'], $alias['name'], new ArrayExpression([], $node->getTemplateLine()), $node->getTemplateLine());
706
+ $node->setAttribute('safe', true);
707
  }
708
 
709
  return new $class($node, $name, $arguments, $this->parser->getCurrentToken()->getLine());
710
  }
711
 
712
+ private function getTest(int $line): array
713
  {
714
  $stream = $this->parser->getStream();
715
+ $name = $stream->expect(/* Token::NAME_TYPE */ 5)->getValue();
716
 
717
  if ($test = $this->env->getTest($name)) {
718
  return [$name, $test];
719
  }
720
 
721
+ if ($stream->test(/* Token::NAME_TYPE */ 5)) {
722
  // try 2-words tests
723
  $name = $name.' '.$this->parser->getCurrentToken()->getValue();
724
 
735
  throw $e;
736
  }
737
 
738
+ private function getTestNodeClass(TwigTest $test): string
739
  {
740
+ if ($test->isDeprecated()) {
741
  $stream = $this->parser->getStream();
742
  $message = sprintf('Twig Test "%s" is deprecated', $test->getName());
743
+
744
  if (!\is_bool($test->getDeprecatedVersion())) {
745
  $message .= sprintf(' since version %s', $test->getDeprecatedVersion());
746
  }
748
  $message .= sprintf('. Use "%s" instead', $test->getAlternative());
749
  }
750
  $src = $stream->getSourceContext();
751
+ $message .= sprintf(' in %s at line %d.', $src->getPath() ?: $src->getName(), $stream->getCurrent()->getLine());
752
 
753
+ @trigger_error($message, \E_USER_DEPRECATED);
754
  }
755
 
756
+ return $test->getNodeClass();
 
 
 
 
757
  }
758
 
759
+ private function getFunctionNodeClass(string $name, int $line): string
760
  {
761
  if (false === $function = $this->env->getFunction($name)) {
762
  $e = new SyntaxError(sprintf('Unknown "%s" function.', $name), $line, $this->parser->getStream()->getSourceContext());
765
  throw $e;
766
  }
767
 
768
+ if ($function->isDeprecated()) {
769
  $message = sprintf('Twig Function "%s" is deprecated', $function->getName());
770
  if (!\is_bool($function->getDeprecatedVersion())) {
771
  $message .= sprintf(' since version %s', $function->getDeprecatedVersion());
774
  $message .= sprintf('. Use "%s" instead', $function->getAlternative());
775
  }
776
  $src = $this->parser->getStream()->getSourceContext();
777
+ $message .= sprintf(' in %s at line %d.', $src->getPath() ?: $src->getName(), $line);
 
 
 
778
 
779
+ @trigger_error($message, \E_USER_DEPRECATED);
 
780
  }
781
 
782
+ return $function->getNodeClass();
783
  }
784
 
785
+ private function getFilterNodeClass(string $name, int $line): string
786
  {
787
  if (false === $filter = $this->env->getFilter($name)) {
788
  $e = new SyntaxError(sprintf('Unknown "%s" filter.', $name), $line, $this->parser->getStream()->getSourceContext());
791
  throw $e;
792
  }
793
 
794
+ if ($filter->isDeprecated()) {
795
  $message = sprintf('Twig Filter "%s" is deprecated', $filter->getName());
796
  if (!\is_bool($filter->getDeprecatedVersion())) {
797
  $message .= sprintf(' since version %s', $filter->getDeprecatedVersion());
800
  $message .= sprintf('. Use "%s" instead', $filter->getAlternative());
801
  }
802
  $src = $this->parser->getStream()->getSourceContext();
803
+ $message .= sprintf(' in %s at line %d.', $src->getPath() ?: $src->getName(), $line);
 
 
 
804
 
805
+ @trigger_error($message, \E_USER_DEPRECATED);
 
806
  }
807
 
808
+ return $filter->getNodeClass();
809
  }
810
 
811
  // checks that the node only contains "constant" elements
812
+ private function checkConstantExpression(Node $node): bool
813
  {
814
  if (!($node instanceof ConstantExpression || $node instanceof ArrayExpression
815
  || $node instanceof NegUnary || $node instanceof PosUnary
vendor/twig/twig/src/Extension/AbstractExtension.php CHANGED
@@ -11,17 +11,8 @@
11
 
12
  namespace Twig\Extension;
13
 
14
- use Twig\Environment;
15
-
16
  abstract class AbstractExtension implements ExtensionInterface
17
  {
18
- /**
19
- * @deprecated since 1.23 (to be removed in 2.0), implement \Twig_Extension_InitRuntimeInterface instead
20
- */
21
- public function initRuntime(Environment $environment)
22
- {
23
- }
24
-
25
  public function getTokenParsers()
26
  {
27
  return [];
@@ -51,22 +42,6 @@ abstract class AbstractExtension implements ExtensionInterface
51
  {
52
  return [];
53
  }
54
-
55
- /**
56
- * @deprecated since 1.23 (to be removed in 2.0), implement \Twig_Extension_GlobalsInterface instead
57
- */
58
- public function getGlobals()
59
- {
60
- return [];
61
- }
62
-
63
- /**
64
- * @deprecated since 1.26 (to be removed in 2.0), not used anymore internally
65
- */
66
- public function getName()
67
- {
68
- return \get_class($this);
69
- }
70
  }
71
 
72
  class_alias('Twig\Extension\AbstractExtension', 'Twig_Extension');
11
 
12
  namespace Twig\Extension;
13
 
 
 
14
  abstract class AbstractExtension implements ExtensionInterface
15
  {
 
 
 
 
 
 
 
16
  public function getTokenParsers()
17
  {
18
  return [];
42
  {
43
  return [];
44
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  }
46
 
47
  class_alias('Twig\Extension\AbstractExtension', 'Twig_Extension');
vendor/twig/twig/src/Extension/CoreExtension.php CHANGED
@@ -11,6 +11,45 @@
11
 
12
  namespace Twig\Extension {
13
  use Twig\ExpressionParser;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  use Twig\TokenParser\ApplyTokenParser;
15
  use Twig\TokenParser\BlockTokenParser;
16
  use Twig\TokenParser\DeprecatedTokenParser;
@@ -33,34 +72,41 @@ use Twig\TwigFilter;
33
  use Twig\TwigFunction;
34
  use Twig\TwigTest;
35
 
36
- /**
37
- * @final
38
- */
39
- class CoreExtension extends AbstractExtension
40
  {
41
- protected $dateFormats = ['F j, Y H:i', '%d days'];
42
- protected $numberFormat = [0, '.', ','];
43
- protected $timezone = null;
44
- protected $escapers = [];
45
 
46
  /**
47
  * Defines a new escaper to be used via the escape filter.
48
  *
49
  * @param string $strategy The strategy name that should be used as a strategy in the escape call
50
  * @param callable $callable A valid PHP callable
 
 
51
  */
52
- public function setEscaper($strategy, $callable)
53
  {
 
 
54
  $this->escapers[$strategy] = $callable;
55
  }
56
 
57
  /**
58
  * Gets all defined escapers.
59
  *
60
- * @return array An array of escapers
 
 
61
  */
62
- public function getEscapers()
63
  {
 
 
 
 
64
  return $this->escapers;
65
  }
66
 
@@ -163,11 +209,11 @@ class CoreExtension extends AbstractExtension
163
 
164
  public function getFilters()
165
  {
166
- $filters = [
167
  // formatting filters
168
  new TwigFilter('date', 'twig_date_format_filter', ['needs_environment' => true]),
169
  new TwigFilter('date_modify', 'twig_date_modify_filter', ['needs_environment' => true]),
170
- new TwigFilter('format', 'sprintf'),
171
  new TwigFilter('replace', 'twig_replace_filter'),
172
  new TwigFilter('number_format', 'twig_number_format_filter', ['needs_environment' => true]),
173
  new TwigFilter('abs', 'abs'),
@@ -175,28 +221,29 @@ class CoreExtension extends AbstractExtension
175
 
176
  // encoding
177
  new TwigFilter('url_encode', 'twig_urlencode_filter'),
178
- new TwigFilter('json_encode', 'twig_jsonencode_filter'),
179
  new TwigFilter('convert_encoding', 'twig_convert_encoding'),
180
 
181
  // string filters
182
  new TwigFilter('title', 'twig_title_string_filter', ['needs_environment' => true]),
183
  new TwigFilter('capitalize', 'twig_capitalize_string_filter', ['needs_environment' => true]),
184
- new TwigFilter('upper', 'strtoupper'),
185
- new TwigFilter('lower', 'strtolower'),
186
- new TwigFilter('striptags', 'strip_tags'),
187
  new TwigFilter('trim', 'twig_trim_filter'),
188
- new TwigFilter('nl2br', 'nl2br', ['pre_escape' => 'html', 'is_safe' => ['html']]),
189
  new TwigFilter('spaceless', 'twig_spaceless', ['is_safe' => ['html']]),
190
 
191
  // array helpers
192
  new TwigFilter('join', 'twig_join_filter'),
193
  new TwigFilter('split', 'twig_split_filter', ['needs_environment' => true]),
194
- new TwigFilter('sort', 'twig_sort_filter'),
195
  new TwigFilter('merge', 'twig_array_merge'),
196
  new TwigFilter('batch', 'twig_array_batch'),
197
- new TwigFilter('filter', 'twig_array_filter'),
198
- new TwigFilter('map', 'twig_array_map'),
199
- new TwigFilter('reduce', 'twig_array_reduce'),
 
200
 
201
  // string/array filters
202
  new TwigFilter('reverse', 'twig_reverse_filter', ['needs_environment' => true]),
@@ -206,20 +253,9 @@ class CoreExtension extends AbstractExtension
206
  new TwigFilter('last', 'twig_last', ['needs_environment' => true]),
207
 
208
  // iteration and runtime
209
- new TwigFilter('default', '_twig_default_filter', ['node_class' => '\Twig\Node\Expression\Filter\DefaultFilter']),
210
  new TwigFilter('keys', 'twig_get_array_keys_filter'),
211
-
212
- // escaping
213
- new TwigFilter('escape', 'twig_escape_filter', ['needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe']),
214
- new TwigFilter('e', 'twig_escape_filter', ['needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe']),
215
  ];
216
-
217
- if (\function_exists('mb_get_info')) {
218
- $filters[] = new TwigFilter('upper', 'twig_upper_filter', ['needs_environment' => true]);
219
- $filters[] = new TwigFilter('lower', 'twig_lower_filter', ['needs_environment' => true]);
220
- }
221
-
222
- return $filters;
223
  }
224
 
225
  public function getFunctions()
@@ -240,79 +276,80 @@ class CoreExtension extends AbstractExtension
240
  public function getTests()
241
  {
242
  return [
243
- new TwigTest('even', null, ['node_class' => '\Twig\Node\Expression\Test\EvenTest']),
244
- new TwigTest('odd', null, ['node_class' => '\Twig\Node\Expression\Test\OddTest']),
245
- new TwigTest('defined', null, ['node_class' => '\Twig\Node\Expression\Test\DefinedTest']),
246
- new TwigTest('sameas', null, ['node_class' => '\Twig\Node\Expression\Test\SameasTest', 'deprecated' => '1.21', 'alternative' => 'same as']),
247
- new TwigTest('same as', null, ['node_class' => '\Twig\Node\Expression\Test\SameasTest']),
248
- new TwigTest('none', null, ['node_class' => '\Twig\Node\Expression\Test\NullTest']),
249
- new TwigTest('null', null, ['node_class' => '\Twig\Node\Expression\Test\NullTest']),
250
- new TwigTest('divisibleby', null, ['node_class' => '\Twig\Node\Expression\Test\DivisiblebyTest', 'deprecated' => '1.21', 'alternative' => 'divisible by']),
251
- new TwigTest('divisible by', null, ['node_class' => '\Twig\Node\Expression\Test\DivisiblebyTest']),
252
- new TwigTest('constant', null, ['node_class' => '\Twig\Node\Expression\Test\ConstantTest']),
253
  new TwigTest('empty', 'twig_test_empty'),
254
  new TwigTest('iterable', 'twig_test_iterable'),
255
  ];
256
  }
257
 
 
 
 
 
 
258
  public function getOperators()
259
  {
260
  return [
261
  [
262
- 'not' => ['precedence' => 50, 'class' => '\Twig\Node\Expression\Unary\NotUnary'],
263
- '-' => ['precedence' => 500, 'class' => '\Twig\Node\Expression\Unary\NegUnary'],
264
- '+' => ['precedence' => 500, 'class' => '\Twig\Node\Expression\Unary\PosUnary'],
265
  ],
266
  [
267
- 'or' => ['precedence' => 10, 'class' => '\Twig\Node\Expression\Binary\OrBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
268
- 'and' => ['precedence' => 15, 'class' => '\Twig\Node\Expression\Binary\AndBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
269
- 'b-or' => ['precedence' => 16, 'class' => '\Twig\Node\Expression\Binary\BitwiseOrBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
270
- 'b-xor' => ['precedence' => 17, 'class' => '\Twig\Node\Expression\Binary\BitwiseXorBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
271
- 'b-and' => ['precedence' => 18, 'class' => '\Twig\Node\Expression\Binary\BitwiseAndBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
272
- '==' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\EqualBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
273
- '!=' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\NotEqualBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
274
- '<' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\LessBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
275
- '>' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\GreaterBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
276
- '>=' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\GreaterEqualBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
277
- '<=' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\LessEqualBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
278
- 'not in' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\NotInBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
279
- 'in' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\InBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
280
- 'matches' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\MatchesBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
281
- 'starts with' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\StartsWithBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
282
- 'ends with' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\EndsWithBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
283
- '..' => ['precedence' => 25, 'class' => '\Twig\Node\Expression\Binary\RangeBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
284
- '+' => ['precedence' => 30, 'class' => '\Twig\Node\Expression\Binary\AddBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
285
- '-' => ['precedence' => 30, 'class' => '\Twig\Node\Expression\Binary\SubBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
286
- '~' => ['precedence' => 40, 'class' => '\Twig\Node\Expression\Binary\ConcatBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
287
- '*' => ['precedence' => 60, 'class' => '\Twig\Node\Expression\Binary\MulBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
288
- '/' => ['precedence' => 60, 'class' => '\Twig\Node\Expression\Binary\DivBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
289
- '//' => ['precedence' => 60, 'class' => '\Twig\Node\Expression\Binary\FloorDivBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
290
- '%' => ['precedence' => 60, 'class' => '\Twig\Node\Expression\Binary\ModBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
 
291
  'is' => ['precedence' => 100, 'associativity' => ExpressionParser::OPERATOR_LEFT],
292
  'is not' => ['precedence' => 100, 'associativity' => ExpressionParser::OPERATOR_LEFT],
293
- '**' => ['precedence' => 200, 'class' => '\Twig\Node\Expression\Binary\PowerBinary', 'associativity' => ExpressionParser::OPERATOR_RIGHT],
294
- '??' => ['precedence' => 300, 'class' => '\Twig\Node\Expression\NullCoalesceExpression', 'associativity' => ExpressionParser::OPERATOR_RIGHT],
295
  ],
296
  ];
297
  }
298
-
299
- public function getName()
300
- {
301
- return 'core';
302
- }
303
  }
304
 
305
  class_alias('Twig\Extension\CoreExtension', 'Twig_Extension_Core');
306
  }
307
 
308
  namespace {
309
- use Twig\Environment;
310
- use Twig\Error\LoaderError;
311
- use Twig\Error\RuntimeError;
312
- use Twig\Loader\SourceContextLoaderInterface;
313
- use Twig\Markup;
314
- use Twig\Node\Expression\ConstantExpression;
315
- use Twig\Node\Node;
 
 
316
 
317
  /**
318
  * Cycles over a value.
@@ -347,7 +384,7 @@ function twig_cycle($values, $position)
347
  function twig_random(Environment $env, $values = null, $max = null)
348
  {
349
  if (null === $values) {
350
- return null === $max ? mt_rand() : mt_rand(0, $max);
351
  }
352
 
353
  if (\is_int($values) || \is_float($values)) {
@@ -364,29 +401,28 @@ function twig_random(Environment $env, $values = null, $max = null)
364
  $max = $max;
365
  }
366
 
367
- return mt_rand($min, $max);
368
  }
369
 
370
  if (\is_string($values)) {
371
  if ('' === $values) {
372
  return '';
373
  }
374
- if (null !== $charset = $env->getCharset()) {
375
- if ('UTF-8' !== $charset) {
376
- $values = twig_convert_encoding($values, 'UTF-8', $charset);
377
- }
378
 
379
- // unicode version of str_split()
380
- // split at all positions, but not after the start and not before the end
381
- $values = preg_split('/(?<!^)(?!$)/u', $values);
382
 
383
- if ('UTF-8' !== $charset) {
384
- foreach ($values as $i => $value) {
385
- $values[$i] = twig_convert_encoding($value, $charset, 'UTF-8');
386
- }
 
 
 
 
 
 
 
387
  }
388
- } else {
389
- return $values[mt_rand(0, \strlen($values) - 1)];
390
  }
391
  }
392
 
@@ -408,16 +444,16 @@ function twig_random(Environment $env, $values = null, $max = null)
408
  *
409
  * {{ post.published_at|date("m/d/Y") }}
410
  *
411
- * @param \DateTime|\DateTimeInterface|\DateInterval|string $date A date
412
- * @param string|null $format The target format, null to use the default
413
- * @param \DateTimeZone|string|false|null $timezone The target timezone, null to use the default, false to leave unchanged
414
  *
415
  * @return string The formatted date
416
  */
417
  function twig_date_format_filter(Environment $env, $date, $format = null, $timezone = null)
418
  {
419
  if (null === $format) {
420
- $formats = $env->getExtension('\Twig\Extension\CoreExtension')->getDateFormat();
421
  $format = $date instanceof \DateInterval ? $formats[1] : $formats[0];
422
  }
423
 
@@ -433,20 +469,29 @@ function twig_date_format_filter(Environment $env, $date, $format = null, $timez
433
  *
434
  * {{ post.published_at|date_modify("-1day")|date("m/d/Y") }}
435
  *
436
- * @param \DateTime|string $date A date
437
- * @param string $modifier A modifier string
438
  *
439
- * @return \DateTime
440
  */
441
  function twig_date_modify_filter(Environment $env, $date, $modifier)
442
  {
443
  $date = twig_date_converter($env, $date, false);
444
- $resultDate = $date->modify($modifier);
445
 
446
- // This is a hack to ensure PHP 5.2 support and support for \DateTimeImmutable
447
- // \DateTime::modify does not return the modified \DateTime object < 5.3.0
448
- // and \DateTimeImmutable does not modify $date.
449
- return null === $resultDate ? $date : $resultDate;
 
 
 
 
 
 
 
 
 
 
450
  }
451
 
452
  /**
@@ -456,8 +501,8 @@ function twig_date_modify_filter(Environment $env, $date, $modifier)
456
  * {# do something #}
457
  * {% endif %}
458
  *
459
- * @param \DateTime|\DateTimeInterface|string|null $date A date
460
- * @param \DateTimeZone|string|false|null $timezone The target timezone, null to use the default, false to leave unchanged
461
  *
462
  * @return \DateTimeInterface
463
  */
@@ -466,7 +511,7 @@ function twig_date_converter(Environment $env, $date = null, $timezone = null)
466
  // determine the timezone
467
  if (false !== $timezone) {
468
  if (null === $timezone) {
469
- $timezone = $env->getExtension('\Twig\Extension\CoreExtension')->getTimezone();
470
  } elseif (!$timezone instanceof \DateTimeZone) {
471
  $timezone = new \DateTimeZone($timezone);
472
  }
@@ -477,7 +522,7 @@ function twig_date_converter(Environment $env, $date = null, $timezone = null)
477
  return false !== $timezone ? $date->setTimezone($timezone) : $date;
478
  }
479
 
480
- if ($date instanceof \DateTime || $date instanceof \DateTimeInterface) {
481
  $date = clone $date;
482
  if (false !== $timezone) {
483
  $date->setTimezone($timezone);
@@ -487,14 +532,18 @@ function twig_date_converter(Environment $env, $date = null, $timezone = null)
487
  }
488
 
489
  if (null === $date || 'now' === $date) {
490
- return new \DateTime($date, false !== $timezone ? $timezone : $env->getExtension('\Twig\Extension\CoreExtension')->getTimezone());
 
 
 
 
491
  }
492
 
493
  $asString = (string) $date;
494
  if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) {
495
  $date = new \DateTime('@'.$date);
496
  } else {
497
- $date = new \DateTime($date, $env->getExtension('\Twig\Extension\CoreExtension')->getTimezone());
498
  }
499
 
500
  if (false !== $timezone) {
@@ -507,54 +556,49 @@ function twig_date_converter(Environment $env, $date = null, $timezone = null)
507
  /**
508
  * Replaces strings within a string.
509
  *
510
- * @param string $str String to replace in
511
  * @param array|\Traversable $from Replace values
512
- * @param string|null $to Replace to, deprecated (@see https://secure.php.net/manual/en/function.strtr.php)
513
  *
514
  * @return string
515
  */
516
- function twig_replace_filter($str, $from, $to = null)
517
  {
518
- if (\is_string($from) && \is_string($to)) {
519
- @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);
520
-
521
- return strtr($str, $from, $to);
522
- }
523
-
524
  if (!twig_test_iterable($from)) {
525
  throw new RuntimeError(sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".', \is_object($from) ? \get_class($from) : \gettype($from)));
526
  }
527
 
528
- return strtr($str, twig_to_array($from));
529
  }
530
 
531
  /**
532
  * Rounds a number.
533
  *
534
- * @param int|float $value The value to round
535
- * @param int|float $precision The rounding precision
536
- * @param string $method The method to use for rounding
537
  *
538
  * @return int|float The rounded number
539
  */
540
  function twig_round($value, $precision = 0, $method = 'common')
541
  {
542
- if ('common' == $method) {
 
 
543
  return round($value, $precision);
544
  }
545
 
546
- if ('ceil' != $method && 'floor' != $method) {
547
  throw new RuntimeError('The round filter only supports the "common", "ceil", and "floor" methods.');
548
  }
549
 
550
- return $method($value * pow(10, $precision)) / pow(10, $precision);
551
  }
552
 
553
  /**
554
  * Number format filter.
555
  *
556
  * All of the formatting options can be left null, in that case the defaults will
557
- * be used. Supplying any of the parameters will override the defaults set in the
558
  * environment object.
559
  *
560
  * @param mixed $number A float/int/string of the number to format
@@ -566,7 +610,7 @@ function twig_round($value, $precision = 0, $method = 'common')
566
  */
567
  function twig_number_format_filter(Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null)
568
  {
569
- $defaults = $env->getExtension('\Twig\Extension\CoreExtension')->getNumberFormat();
570
  if (null === $decimal) {
571
  $decimal = $defaults[0];
572
  }
@@ -585,47 +629,17 @@ function twig_number_format_filter(Environment $env, $number, $decimal = null, $
585
  /**
586
  * URL encodes (RFC 3986) a string as a path segment or an array as a query string.
587
  *
588
- * @param string|array $url A URL or an array of query parameters
589
  *
590
  * @return string The URL encoded value
591
  */
592
  function twig_urlencode_filter($url)
593
  {
594
  if (\is_array($url)) {
595
- if (\defined('PHP_QUERY_RFC3986')) {
596
- return http_build_query($url, '', '&', PHP_QUERY_RFC3986);
597
- }
598
-
599
- return http_build_query($url, '', '&');
600
  }
601
 
602
- return rawurlencode($url);
603
- }
604
-
605
- /**
606
- * JSON encodes a variable.
607
- *
608
- * @param mixed $value the value to encode
609
- * @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
610
- *
611
- * @return mixed The JSON encoded value
612
- */
613
- function twig_jsonencode_filter($value, $options = 0)
614
- {
615
- if ($value instanceof Markup) {
616
- $value = (string) $value;
617
- } elseif (\is_array($value)) {
618
- array_walk_recursive($value, '_twig_markup2string');
619
- }
620
-
621
- return json_encode($value, $options);
622
- }
623
-
624
- function _twig_markup2string(&$value)
625
- {
626
- if ($value instanceof Markup) {
627
- $value = (string) $value;
628
- }
629
  }
630
 
631
  /**
@@ -687,13 +701,7 @@ function twig_slice(Environment $env, $item, $start, $length = null, $preserveKe
687
  return \array_slice($item, $start, $length, $preserveKeys);
688
  }
689
 
690
- $item = (string) $item;
691
-
692
- if (\function_exists('mb_get_info') && null !== $charset = $env->getCharset()) {
693
- return (string) mb_substr($item, $start, null === $length ? mb_strlen($item, $charset) - $start : $length, $charset);
694
- }
695
-
696
- return (string) (null === $length ? substr($item, $start) : substr($item, $start, $length));
697
  }
698
 
699
  /**
@@ -782,34 +790,32 @@ function twig_join_filter($value, $glue = '', $and = null)
782
  * {{ "aabbcc"|split('', 2) }}
783
  * {# returns [aa, bb, cc] #}
784
  *
785
- * @param string $value A string
786
- * @param string $delimiter The delimiter
787
- * @param int $limit The limit
788
  *
789
  * @return array The split string as an array
790
  */
791
  function twig_split_filter(Environment $env, $value, $delimiter, $limit = null)
792
  {
 
 
793
  if (\strlen($delimiter) > 0) {
794
  return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit);
795
  }
796
 
797
- if (!\function_exists('mb_get_info') || null === $charset = $env->getCharset()) {
798
- return str_split($value, null === $limit ? 1 : $limit);
799
- }
800
-
801
  if ($limit <= 1) {
802
  return preg_split('/(?<!^)(?!$)/u', $value);
803
  }
804
 
805
- $length = mb_strlen($value, $charset);
806
  if ($length < $limit) {
807
  return [$value];
808
  }
809
 
810
  $r = [];
811
  for ($i = 0; $i < $length; $i += $limit) {
812
- $r[] = mb_substr($value, $i, $limit, $charset);
813
  }
814
 
815
  return $r;
@@ -879,8 +885,8 @@ function twig_get_array_keys_filter($array)
879
  /**
880
  * Reverses a variable.
881
  *
882
- * @param array|\Traversable|string $item An array, a \Traversable instance, or a string
883
- * @param bool $preserveKeys Whether to preserve key or not
884
  *
885
  * @return mixed The reversed input
886
  */
@@ -894,25 +900,23 @@ function twig_reverse_filter(Environment $env, $item, $preserveKeys = false)
894
  return array_reverse($item, $preserveKeys);
895
  }
896
 
897
- if (null !== $charset = $env->getCharset()) {
898
- $string = (string) $item;
899
 
900
- if ('UTF-8' !== $charset) {
901
- $item = twig_convert_encoding($string, 'UTF-8', $charset);
902
- }
903
 
904
- preg_match_all('/./us', $item, $matches);
 
 
905
 
906
- $string = implode('', array_reverse($matches[0]));
907
 
908
- if ('UTF-8' !== $charset) {
909
- $string = twig_convert_encoding($string, $charset, 'UTF-8');
910
- }
911
 
912
- return $string;
 
913
  }
914
 
915
- return strrev((string) $item);
916
  }
917
 
918
  /**
@@ -922,7 +926,7 @@ function twig_reverse_filter(Environment $env, $item, $preserveKeys = false)
922
  *
923
  * @return array
924
  */
925
- function twig_sort_filter($array)
926
  {
927
  if ($array instanceof \Traversable) {
928
  $array = iterator_to_array($array);
@@ -930,7 +934,13 @@ function twig_sort_filter($array)
930
  throw new RuntimeError(sprintf('The sort filter only works with arrays or "Traversable", got "%s".', \gettype($array)));
931
  }
932
 
933
- asort($array);
 
 
 
 
 
 
934
 
935
  return $array;
936
  }
@@ -975,6 +985,10 @@ function twig_in_filter($value, $compare)
975
  /**
976
  * Returns a trimmed string.
977
  *
 
 
 
 
978
  * @return string
979
  *
980
  * @throws RuntimeError When an invalid trimming side is used (not a string or not 'left', 'right', or 'both')
@@ -987,478 +1001,172 @@ function twig_trim_filter($string, $characterMask = null, $side = 'both')
987
 
988
  switch ($side) {
989
  case 'both':
990
- return trim($string, $characterMask);
991
  case 'left':
992
- return ltrim($string, $characterMask);
993
  case 'right':
994
- return rtrim($string, $characterMask);
995
  default:
996
  throw new RuntimeError('Trimming side must be "left", "right" or "both".');
997
  }
998
  }
999
 
1000
  /**
1001
- * Removes whitespaces between HTML tags.
 
 
1002
  *
1003
  * @return string
1004
  */
1005
- function twig_spaceless($content)
1006
  {
1007
- return trim(preg_replace('/>\s+</', '><', $content));
1008
  }
1009
 
1010
  /**
1011
- * Escapes a string.
1012
  *
1013
- * @param mixed $string The value to be escaped
1014
- * @param string $strategy The escaping strategy
1015
- * @param string $charset The charset
1016
- * @param bool $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false)
1017
  *
1018
  * @return string
1019
  */
1020
- function twig_escape_filter(Environment $env, $string, $strategy = 'html', $charset = null, $autoescape = false)
1021
  {
1022
- if ($autoescape && $string instanceof Markup) {
1023
- return $string;
1024
- }
1025
-
1026
- if (!\is_string($string)) {
1027
- if (\is_object($string) && method_exists($string, '__toString')) {
1028
- $string = (string) $string;
1029
- } elseif (\in_array($strategy, ['html', 'js', 'css', 'html_attr', 'url'])) {
1030
- return $string;
1031
- }
1032
- }
1033
-
1034
- if ('' === $string) {
1035
- return '';
1036
- }
1037
-
1038
- if (null === $charset) {
1039
- $charset = $env->getCharset();
1040
- }
1041
-
1042
- switch ($strategy) {
1043
- case 'html':
1044
- // see https://secure.php.net/htmlspecialchars
1045
-
1046
- // Using a static variable to avoid initializing the array
1047
- // each time the function is called. Moving the declaration on the
1048
- // top of the function slow downs other escaping strategies.
1049
- static $htmlspecialcharsCharsets = [
1050
- 'ISO-8859-1' => true, 'ISO8859-1' => true,
1051
- 'ISO-8859-15' => true, 'ISO8859-15' => true,
1052
- 'utf-8' => true, 'UTF-8' => true,
1053
- 'CP866' => true, 'IBM866' => true, '866' => true,
1054
- 'CP1251' => true, 'WINDOWS-1251' => true, 'WIN-1251' => true,
1055
- '1251' => true,
1056
- 'CP1252' => true, 'WINDOWS-1252' => true, '1252' => true,
1057
- 'KOI8-R' => true, 'KOI8-RU' => true, 'KOI8R' => true,
1058
- 'BIG5' => true, '950' => true,
1059
- 'GB2312' => true, '936' => true,
1060
- 'BIG5-HKSCS' => true,
1061
- 'SHIFT_JIS' => true, 'SJIS' => true, '932' => true,
1062
- 'EUC-JP' => true, 'EUCJP' => true,
1063
- 'ISO8859-5' => true, 'ISO-8859-5' => true, 'MACROMAN' => true,
1064
- ];
1065
-
1066
- if (isset($htmlspecialcharsCharsets[$charset])) {
1067
- return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset);
1068
- }
1069
-
1070
- if (isset($htmlspecialcharsCharsets[strtoupper($charset)])) {
1071
- // cache the lowercase variant for future iterations
1072
- $htmlspecialcharsCharsets[$charset] = true;
1073
-
1074
- return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset);
1075
- }
1076
-
1077
- $string = twig_convert_encoding($string, 'UTF-8', $charset);
1078
- $string = htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
1079
-
1080
- return twig_convert_encoding($string, $charset, 'UTF-8');
1081
-
1082
- case 'js':
1083
- // escape all non-alphanumeric characters
1084
- // into their \x or \uHHHH representations
1085
- if ('UTF-8' !== $charset) {
1086
- $string = twig_convert_encoding($string, 'UTF-8', $charset);
1087
- }
1088
-
1089
- if (!preg_match('//u', $string)) {
1090
- throw new RuntimeError('The string to escape is not a valid UTF-8 string.');
1091
- }
1092
-
1093
- $string = preg_replace_callback('#[^a-zA-Z0-9,\._]#Su', '_twig_escape_js_callback', $string);
1094
-
1095
- if ('UTF-8' !== $charset) {
1096
- $string = twig_convert_encoding($string, $charset, 'UTF-8');
1097
- }
1098
-
1099
- return $string;
1100
-
1101
- case 'css':
1102
- if ('UTF-8' !== $charset) {
1103
- $string = twig_convert_encoding($string, 'UTF-8', $charset);
1104
- }
1105
-
1106
- if (!preg_match('//u', $string)) {
1107
- throw new RuntimeError('The string to escape is not a valid UTF-8 string.');
1108
- }
1109
-
1110
- $string = preg_replace_callback('#[^a-zA-Z0-9]#Su', '_twig_escape_css_callback', $string);
1111
-
1112
- if ('UTF-8' !== $charset) {
1113
- $string = twig_convert_encoding($string, $charset, 'UTF-8');
1114
- }
1115
-
1116
- return $string;
1117
-
1118
- case 'html_attr':
1119
- if ('UTF-8' !== $charset) {
1120
- $string = twig_convert_encoding($string, 'UTF-8', $charset);
1121
- }
1122
-
1123
- if (!preg_match('//u', $string)) {
1124
- throw new RuntimeError('The string to escape is not a valid UTF-8 string.');
1125
- }
1126
-
1127
- $string = preg_replace_callback('#[^a-zA-Z0-9,\.\-_]#Su', '_twig_escape_html_attr_callback', $string);
1128
-
1129
- if ('UTF-8' !== $charset) {
1130
- $string = twig_convert_encoding($string, $charset, 'UTF-8');
1131
- }
1132
-
1133
- return $string;
1134
-
1135
- case 'url':
1136
- return rawurlencode($string);
1137
-
1138
- default:
1139
- static $escapers;
1140
-
1141
- if (null === $escapers) {
1142
- $escapers = $env->getExtension('\Twig\Extension\CoreExtension')->getEscapers();
1143
- }
1144
-
1145
- if (isset($escapers[$strategy])) {
1146
- return \call_user_func($escapers[$strategy], $env, $string, $charset);
1147
- }
1148
-
1149
- $validStrategies = implode(', ', array_merge(['html', 'js', 'url', 'css', 'html_attr'], array_keys($escapers)));
1150
-
1151
- throw new RuntimeError(sprintf('Invalid escaping strategy "%s" (valid ones: %s).', $strategy, $validStrategies));
1152
- }
1153
  }
1154
 
1155
  /**
1156
- * @internal
 
 
 
 
1157
  */
1158
- function twig_escape_filter_is_safe(Node $filterArgs)
1159
  {
1160
- foreach ($filterArgs as $arg) {
1161
- if ($arg instanceof ConstantExpression) {
1162
- return [$arg->getAttribute('value')];
1163
- }
1164
-
1165
- return [];
1166
  }
1167
 
1168
- return ['html'];
1169
  }
1170
 
1171
- if (\function_exists('mb_convert_encoding')) {
1172
- function twig_convert_encoding($string, $to, $from)
1173
- {
1174
- return mb_convert_encoding($string, $to, $from);
1175
- }
1176
- } elseif (\function_exists('iconv')) {
1177
- function twig_convert_encoding($string, $to, $from)
1178
- {
1179
- return iconv($from, $to, $string);
1180
- }
1181
- } else {
1182
- function twig_convert_encoding($string, $to, $from)
1183
- {
1184
- throw new RuntimeError('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).');
1185
  }
1186
- }
1187
 
1188
- if (\function_exists('mb_ord')) {
1189
- function twig_ord($string)
1190
- {
1191
- return mb_ord($string, 'UTF-8');
1192
  }
1193
- } else {
1194
- function twig_ord($string)
1195
- {
1196
- $code = ($string = unpack('C*', substr($string, 0, 4))) ? $string[1] : 0;
1197
- if (0xF0 <= $code) {
1198
- return (($code - 0xF0) << 18) + (($string[2] - 0x80) << 12) + (($string[3] - 0x80) << 6) + $string[4] - 0x80;
1199
- }
1200
- if (0xE0 <= $code) {
1201
- return (($code - 0xE0) << 12) + (($string[2] - 0x80) << 6) + $string[3] - 0x80;
1202
- }
1203
- if (0xC0 <= $code) {
1204
- return (($code - 0xC0) << 6) + $string[2] - 0x80;
1205
- }
1206
 
1207
- return $code;
 
1208
  }
1209
- }
1210
-
1211
- function _twig_escape_js_callback($matches)
1212
- {
1213
- $char = $matches[0];
1214
 
1215
- /*
1216
- * A few characters have short escape sequences in JSON and JavaScript.
1217
- * Escape sequences supported only by JavaScript, not JSON, are ommitted.
1218
- * \" is also supported but omitted, because the resulting string is not HTML safe.
1219
- */
1220
- static $shortMap = [
1221
- '\\' => '\\\\',
1222
- '/' => '\\/',
1223
- "\x08" => '\b',
1224
- "\x0C" => '\f',
1225
- "\x0A" => '\n',
1226
- "\x0D" => '\r',
1227
- "\x09" => '\t',
1228
- ];
1229
-
1230
- if (isset($shortMap[$char])) {
1231
- return $shortMap[$char];
1232
  }
1233
 
1234
- // \uHHHH
1235
- $char = twig_convert_encoding($char, 'UTF-16BE', 'UTF-8');
1236
- $char = strtoupper(bin2hex($char));
1237
-
1238
- if (4 >= \strlen($char)) {
1239
- return sprintf('\u%04s', $char);
1240
  }
1241
 
1242
- return sprintf('\u%04s\u%04s', substr($char, 0, -4), substr($char, -4));
1243
  }
1244
 
1245
- function _twig_escape_css_callback($matches)
 
 
 
 
 
 
 
1246
  {
1247
- $char = $matches[0];
1248
-
1249
- return sprintf('\\%X ', 1 === \strlen($char) ? \ord($char) : twig_ord($char));
1250
  }
1251
 
1252
  /**
1253
- * This function is adapted from code coming from Zend Framework.
 
 
1254
  *
1255
- * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (https://www.zend.com)
1256
- * @license https://framework.zend.com/license/new-bsd New BSD License
1257
  */
1258
- function _twig_escape_html_attr_callback($matches)
1259
  {
1260
- $chr = $matches[0];
1261
- $ord = \ord($chr);
1262
-
1263
- /*
1264
- * The following replaces characters undefined in HTML with the
1265
- * hex entity for the Unicode replacement character.
1266
- */
1267
- if (($ord <= 0x1f && "\t" != $chr && "\n" != $chr && "\r" != $chr) || ($ord >= 0x7f && $ord <= 0x9f)) {
1268
- return '&#xFFFD;';
1269
- }
1270
-
1271
- /*
1272
- * Check if the current character to escape has a name entity we should
1273
- * replace it with while grabbing the hex value of the character.
1274
- */
1275
- if (1 == \strlen($chr)) {
1276
- /*
1277
- * While HTML supports far more named entities, the lowest common denominator
1278
- * has become HTML5's XML Serialisation which is restricted to the those named
1279
- * entities that XML supports. Using HTML entities would result in this error:
1280
- * XML Parsing Error: undefined entity
1281
- */
1282
- static $entityMap = [
1283
- 34 => '&quot;', /* quotation mark */
1284
- 38 => '&amp;', /* ampersand */
1285
- 60 => '&lt;', /* less-than sign */
1286
- 62 => '&gt;', /* greater-than sign */
1287
- ];
1288
-
1289
- if (isset($entityMap[$ord])) {
1290
- return $entityMap[$ord];
1291
- }
1292
-
1293
- return sprintf('&#x%02X;', $ord);
1294
- }
1295
-
1296
- /*
1297
- * Per OWASP recommendations, we'll use hex entities for any other
1298
- * characters where a named entity does not exist.
1299
- */
1300
- return sprintf('&#x%04X;', twig_ord($chr));
1301
  }
1302
 
1303
- // add multibyte extensions if possible
1304
- if (\function_exists('mb_get_info')) {
1305
- /**
1306
- * Returns the length of a variable.
1307
- *
1308
- * @param mixed $thing A variable
1309
- *
1310
- * @return int The length of the value
1311
- */
1312
- function twig_length_filter(Environment $env, $thing)
1313
- {
1314
- if (null === $thing) {
1315
- return 0;
1316
- }
1317
-
1318
- if (is_scalar($thing)) {
1319
- return mb_strlen($thing, $env->getCharset());
1320
- }
1321
-
1322
- if ($thing instanceof \Countable || \is_array($thing) || $thing instanceof \SimpleXMLElement) {
1323
- return \count($thing);
1324
- }
1325
-
1326
- if ($thing instanceof \Traversable) {
1327
- return iterator_count($thing);
1328
- }
1329
-
1330
- if (\is_object($thing) && method_exists($thing, '__toString')) {
1331
- return mb_strlen((string) $thing, $env->getCharset());
1332
- }
1333
-
1334
- return 1;
1335
- }
1336
-
1337
- /**
1338
- * Converts a string to uppercase.
1339
- *
1340
- * @param string $string A string
1341
- *
1342
- * @return string The uppercased string
1343
- */
1344
- function twig_upper_filter(Environment $env, $string)
1345
- {
1346
- if (null !== $charset = $env->getCharset()) {
1347
- return mb_strtoupper($string, $charset);
1348
- }
1349
-
1350
- r
11
 
12
  namespace Twig\Extension {
13
  use Twig\ExpressionParser;
14
+ use Twig\Node\Expression\Binary\AddBinary;
15
+ use Twig\Node\Expression\Binary\AndBinary;
16
+ use Twig\Node\Expression\Binary\BitwiseAndBinary;
17
+ use Twig\Node\Expression\Binary\BitwiseOrBinary;
18
+ use Twig\Node\Expression\Binary\BitwiseXorBinary;
19
+ use Twig\Node\Expression\Binary\ConcatBinary;
20
+ use Twig\Node\Expression\Binary\DivBinary;
21
+ use Twig\Node\Expression\Binary\EndsWithBinary;
22
+ use Twig\Node\Expression\Binary\EqualBinary;
23
+ use Twig\Node\Expression\Binary\FloorDivBinary;
24
+ use Twig\Node\Expression\Binary\GreaterBinary;
25
+ use Twig\Node\Expression\Binary\GreaterEqualBinary;
26
+ use Twig\Node\Expression\Binary\InBinary;
27
+ use Twig\Node\Expression\Binary\LessBinary;
28
+ use Twig\Node\Expression\Binary\LessEqualBinary;
29
+ use Twig\Node\Expression\Binary\MatchesBinary;
30
+ use Twig\Node\Expression\Binary\ModBinary;
31
+ use Twig\Node\Expression\Binary\MulBinary;
32
+ use Twig\Node\Expression\Binary\NotEqualBinary;
33
+ use Twig\Node\Expression\Binary\NotInBinary;
34
+ use Twig\Node\Expression\Binary\OrBinary;
35
+ use Twig\Node\Expression\Binary\PowerBinary;
36
+ use Twig\Node\Expression\Binary\RangeBinary;
37
+ use Twig\Node\Expression\Binary\SpaceshipBinary;
38
+ use Twig\Node\Expression\Binary\StartsWithBinary;
39
+ use Twig\Node\Expression\Binary\SubBinary;
40
+ use Twig\Node\Expression\Filter\DefaultFilter;
41
+ use Twig\Node\Expression\NullCoalesceExpression;
42
+ use Twig\Node\Expression\Test\ConstantTest;
43
+ use Twig\Node\Expression\Test\DefinedTest;
44
+ use Twig\Node\Expression\Test\DivisiblebyTest;
45
+ use Twig\Node\Expression\Test\EvenTest;
46
+ use Twig\Node\Expression\Test\NullTest;
47
+ use Twig\Node\Expression\Test\OddTest;
48
+ use Twig\Node\Expression\Test\SameasTest;
49
+ use Twig\Node\Expression\Unary\NegUnary;
50
+ use Twig\Node\Expression\Unary\NotUnary;
51
+ use Twig\Node\Expression\Unary\PosUnary;
52
+ use Twig\NodeVisitor\MacroAutoImportNodeVisitor;
53
  use Twig\TokenParser\ApplyTokenParser;
54
  use Twig\TokenParser\BlockTokenParser;
55
  use Twig\TokenParser\DeprecatedTokenParser;
72
  use Twig\TwigFunction;
73
  use Twig\TwigTest;
74
 
75
+ final class CoreExtension extends AbstractExtension
 
 
 
76
  {
77
+ private $dateFormats = ['F j, Y H:i', '%d days'];
78
+ private $numberFormat = [0, '.', ','];
79
+ private $timezone = null;
80
+ private $escapers = [];
81
 
82
  /**
83
  * Defines a new escaper to be used via the escape filter.
84
  *
85
  * @param string $strategy The strategy name that should be used as a strategy in the escape call
86
  * @param callable $callable A valid PHP callable
87
+ *
88
+ * @deprecated since Twig 2.11, to be removed in 3.0; use the same method on EscaperExtension instead
89
  */
90
+ public function setEscaper($strategy, callable $callable)
91
  {
92
+ @trigger_error(sprintf('The "%s" method is deprecated since Twig 2.11; use "%s::setEscaper" instead.', __METHOD__, EscaperExtension::class), \E_USER_DEPRECATED);
93
+
94
  $this->escapers[$strategy] = $callable;
95
  }
96
 
97
  /**
98
  * Gets all defined escapers.
99
  *
100
+ * @return callable[] An array of escapers
101
+ *
102
+ * @deprecated since Twig 2.11, to be removed in 3.0; use the same method on EscaperExtension instead
103
  */
104
+ public function getEscapers(/* $triggerDeprecation = true */)
105
  {
106
+ if (0 === \func_num_args() || \func_get_arg(0)) {
107
+ @trigger_error(sprintf('The "%s" method is deprecated since Twig 2.11; use "%s::getEscapers" instead.', __METHOD__, EscaperExtension::class), \E_USER_DEPRECATED);
108
+ }
109
+
110
  return $this->escapers;
111
  }
112
 
209
 
210
  public function getFilters()
211
  {
212
+ return [
213
  // formatting filters
214
  new TwigFilter('date', 'twig_date_format_filter', ['needs_environment' => true]),
215
  new TwigFilter('date_modify', 'twig_date_modify_filter', ['needs_environment' => true]),
216
+ new TwigFilter('format', 'twig_sprintf'),
217
  new TwigFilter('replace', 'twig_replace_filter'),
218
  new TwigFilter('number_format', 'twig_number_format_filter', ['needs_environment' => true]),
219
  new TwigFilter('abs', 'abs'),
221
 
222
  // encoding
223
  new TwigFilter('url_encode', 'twig_urlencode_filter'),
224
+ new TwigFilter('json_encode', 'json_encode'),
225
  new TwigFilter('convert_encoding', 'twig_convert_encoding'),
226
 
227
  // string filters
228
  new TwigFilter('title', 'twig_title_string_filter', ['needs_environment' => true]),
229
  new TwigFilter('capitalize', 'twig_capitalize_string_filter', ['needs_environment' => true]),
230
+ new TwigFilter('upper', 'twig_upper_filter', ['needs_environment' => true]),
231
+ new TwigFilter('lower', 'twig_lower_filter', ['needs_environment' => true]),
232
+ new TwigFilter('striptags', 'twig_striptags'),
233
  new TwigFilter('trim', 'twig_trim_filter'),
234
+ new TwigFilter('nl2br', 'twig_nl2br', ['pre_escape' => 'html', 'is_safe' => ['html']]),
235
  new TwigFilter('spaceless', 'twig_spaceless', ['is_safe' => ['html']]),
236
 
237
  // array helpers
238
  new TwigFilter('join', 'twig_join_filter'),
239
  new TwigFilter('split', 'twig_split_filter', ['needs_environment' => true]),
240
+ new TwigFilter('sort', 'twig_sort_filter', ['needs_environment' => true]),
241
  new TwigFilter('merge', 'twig_array_merge'),
242
  new TwigFilter('batch', 'twig_array_batch'),
243
+ new TwigFilter('column', 'twig_array_column'),
244
+ new TwigFilter('filter', 'twig_array_filter', ['needs_environment' => true]),
245
+ new TwigFilter('map', 'twig_array_map', ['needs_environment' => true]),
246
+ new TwigFilter('reduce', 'twig_array_reduce', ['needs_environment' => true]),
247
 
248
  // string/array filters
249
  new TwigFilter('reverse', 'twig_reverse_filter', ['needs_environment' => true]),
253
  new TwigFilter('last', 'twig_last', ['needs_environment' => true]),
254
 
255
  // iteration and runtime
256
+ new TwigFilter('default', '_twig_default_filter', ['node_class' => DefaultFilter::class]),
257
  new TwigFilter('keys', 'twig_get_array_keys_filter'),
 
 
 
 
258
  ];
 
 
 
 
 
 
 
259
  }
260
 
261
  public function getFunctions()
276
  public function getTests()
277
  {
278
  return [
279
+ new TwigTest('even', null, ['node_class' => EvenTest::class]),
280
+ new TwigTest('odd', null, ['node_class' => OddTest::class]),
281
+ new TwigTest('defined', null, ['node_class' => DefinedTest::class]),
282
+ new TwigTest('same as', null, ['node_class' => SameasTest::class, 'one_mandatory_argument' => true]),
283
+ new TwigTest('none', null, ['node_class' => NullTest::class]),
284
+ new TwigTest('null', null, ['node_class' => NullTest::class]),
285
+ new TwigTest('divisible by', null, ['node_class' => DivisiblebyTest::class, 'one_mandatory_argument' => true]),
286
+ new TwigTest('constant', null, ['node_class' => ConstantTest::class]),
 
 
287
  new TwigTest('empty', 'twig_test_empty'),
288
  new TwigTest('iterable', 'twig_test_iterable'),
289
  ];
290
  }
291
 
292
+ public function getNodeVisitors()
293
+ {
294
+ return [new MacroAutoImportNodeVisitor()];
295
+ }
296
+
297
  public function getOperators()
298
  {
299
  return [
300
  [
301
+ 'not' => ['precedence' => 50, 'class' => NotUnary::class],
302
+ '-' => ['precedence' => 500, 'class' => NegUnary::class],
303
+ '+' => ['precedence' => 500, 'class' => PosUnary::class],
304
  ],
305
  [
306
+ 'or' => ['precedence' => 10, 'class' => OrBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
307
+ 'and' => ['precedence' => 15, 'class' => AndBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
308
+ 'b-or' => ['precedence' => 16, 'class' => BitwiseOrBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
309
+ 'b-xor' => ['precedence' => 17, 'class' => BitwiseXorBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
310
+ 'b-and' => ['precedence' => 18, 'class' => BitwiseAndBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
311
+ '==' => ['precedence' => 20, 'class' => EqualBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
312
+ '!=' => ['precedence' => 20, 'class' => NotEqualBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
313
+ '<=>' => ['precedence' => 20, 'class' => SpaceshipBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
314
+ '<' => ['precedence' => 20, 'class' => LessBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
315
+ '>' => ['precedence' => 20, 'class' => GreaterBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
316
+ '>=' => ['precedence' => 20, 'class' => GreaterEqualBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
317
+ '<=' => ['precedence' => 20, 'class' => LessEqualBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
318
+ 'not in' => ['precedence' => 20, 'class' => NotInBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
319
+ 'in' => ['precedence' => 20, 'class' => InBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
320
+ 'matches' => ['precedence' => 20, 'class' => MatchesBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
321
+ 'starts with' => ['precedence' => 20, 'class' => StartsWithBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
322
+ 'ends with' => ['precedence' => 20, 'class' => EndsWithBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
323
+ '..' => ['precedence' => 25, 'class' => RangeBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
324
+ '+' => ['precedence' => 30, 'class' => AddBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
325
+ '-' => ['precedence' => 30, 'class' => SubBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
326
+ '~' => ['precedence' => 40, 'class' => ConcatBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
327
+ '*' => ['precedence' => 60, 'class' => MulBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
328
+ '/' => ['precedence' => 60, 'class' => DivBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
329
+ '//' => ['precedence' => 60, 'class' => FloorDivBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
330
+ '%' => ['precedence' => 60, 'class' => ModBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
331
  'is' => ['precedence' => 100, 'associativity' => ExpressionParser::OPERATOR_LEFT],
332
  'is not' => ['precedence' => 100, 'associativity' => ExpressionParser::OPERATOR_LEFT],
333
+ '**' => ['precedence' => 200, 'class' => PowerBinary::class, 'associativity' => ExpressionParser::OPERATOR_RIGHT],
334
+ '??' => ['precedence' => 300, 'class' => NullCoalesceExpression::class, 'associativity' => ExpressionParser::OPERATOR_RIGHT],
335
  ],
336
  ];
337
  }
 
 
 
 
 
338
  }
339
 
340
  class_alias('Twig\Extension\CoreExtension', 'Twig_Extension_Core');
341
  }
342
 
343
  namespace {
344
+ use Twig\Environment;
345
+ use Twig\Error\LoaderError;
346
+ use Twig\Error\RuntimeError;
347
+ use Twig\Extension\CoreExtension;
348
+ use Twig\Extension\SandboxExtension;
349
+ use Twig\Markup;
350
+ use Twig\Source;
351
+ use Twig\Template;
352
+ use Twig\TemplateWrapper;
353
 
354
  /**
355
  * Cycles over a value.
384
  function twig_random(Environment $env, $values = null, $max = null)
385
  {
386
  if (null === $values) {
387
+ return null === $max ? mt_rand() : mt_rand(0, (int) $max);
388
  }
389
 
390
  if (\is_int($values) || \is_float($values)) {
401
  $max = $max;
402
  }
403
 
404
+ return mt_rand((int) $min, (int) $max);
405
  }
406
 
407
  if (\is_string($values)) {
408
  if ('' === $values) {
409
  return '';
410
  }
 
 
 
 
411
 
412
+ $charset = $env->getCharset();
 
 
413
 
414
+ if ('UTF-8' !== $charset) {
415
+ $values = twig_convert_encoding($values, 'UTF-8', $charset);
416
+ }
417
+
418
+ // unicode version of str_split()
419
+ // split at all positions, but not after the start and not before the end
420
+ $values = preg_split('/(?<!^)(?!$)/u', $values);
421
+
422
+ if ('UTF-8' !== $charset) {
423
+ foreach ($values as $i => $value) {
424
+ $values[$i] = twig_convert_encoding($value, $charset, 'UTF-8');
425
  }
 
 
426
  }
427
  }
428
 
444
  *
445
  * {{ post.published_at|date("m/d/Y") }}
446
  *
447
+ * @param \DateTimeInterface|\DateInterval|string $date A date
448
+ * @param string|null $format The target format, null to use the default
449
+ * @param \DateTimeZone|string|false|null $timezone The target timezone, null to use the default, false to leave unchanged
450
  *
451
  * @return string The formatted date
452
  */
453
  function twig_date_format_filter(Environment $env, $date, $format = null, $timezone = null)
454
  {
455
  if (null === $format) {
456
+ $formats = $env->getExtension(CoreExtension::class)->getDateFormat();
457
  $format = $date instanceof \DateInterval ? $formats[1] : $formats[0];
458
  }
459
 
469
  *
470
  * {{ post.published_at|date_modify("-1day")|date("m/d/Y") }}
471
  *
472
+ * @param \DateTimeInterface|string $date A date
473
+ * @param string $modifier A modifier string
474
  *
475
+ * @return \DateTimeInterface
476
  */
477
  function twig_date_modify_filter(Environment $env, $date, $modifier)
478
  {
479
  $date = twig_date_converter($env, $date, false);
 
480
 
481
+ return $date->modify($modifier);
482
+ }
483
+
484
+ /**
485
+ * Returns a formatted string.
486
+ *
487
+ * @param string|null $format
488
+ * @param ...$values
489
+ *
490
+ * @return string
491
+ */
492
+ function twig_sprintf($format, ...$values)
493
+ {
494
+ return sprintf($format ?? '', ...$values);
495
  }
496
 
497
  /**
501
  * {# do something #}
502
  * {% endif %}
503
  *
504
+ * @param \DateTimeInterface|string|null $date A date or null to use the current time
505
+ * @param \DateTimeZone|string|false|null $timezone The target timezone, null to use the default, false to leave unchanged
506
  *
507
  * @return \DateTimeInterface
508
  */
511
  // determine the timezone
512
  if (false !== $timezone) {
513
  if (null === $timezone) {
514
+ $timezone = $env->getExtension(CoreExtension::class)->getTimezone();
515
  } elseif (!$timezone instanceof \DateTimeZone) {
516
  $timezone = new \DateTimeZone($timezone);
517
  }
522
  return false !== $timezone ? $date->setTimezone($timezone) : $date;
523
  }
524
 
525
+ if ($date instanceof \DateTimeInterface) {
526
  $date = clone $date;
527
  if (false !== $timezone) {
528
  $date->setTimezone($timezone);
532
  }
533
 
534
  if (null === $date || 'now' === $date) {
535
+ if (null === $date) {
536
+ $date = 'now';
537
+ }
538
+
539
+ return new \DateTime($date, false !== $timezone ? $timezone : $env->getExtension(CoreExtension::class)->getTimezone());
540
  }
541
 
542
  $asString = (string) $date;
543
  if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) {
544
  $date = new \DateTime('@'.$date);
545
  } else {
546
+ $date = new \DateTime($date, $env->getExtension(CoreExtension::class)->getTimezone());
547
  }
548
 
549
  if (false !== $timezone) {
556
  /**
557
  * Replaces strings within a string.
558
  *
559
+ * @param string|null $str String to replace in
560
  * @param array|\Traversable $from Replace values
 
561
  *
562
  * @return string
563
  */
564
+ function twig_replace_filter($str, $from)
565
  {
 
 
 
 
 
 
566
  if (!twig_test_iterable($from)) {
567
  throw new RuntimeError(sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".', \is_object($from) ? \get_class($from) : \gettype($from)));
568
  }
569
 
570
+ return strtr($str ?? '', twig_to_array($from));
571
  }
572
 
573
  /**
574
  * Rounds a number.
575
  *
576
+ * @param int|float|string|null $value The value to round
577
+ * @param int|float $precision The rounding precision
578
+ * @param string $method The method to use for rounding
579
  *
580
  * @return int|float The rounded number
581
  */
582
  function twig_round($value, $precision = 0, $method = 'common')
583
  {
584
+ $value = (float) $value;
585
+
586
+ if ('common' === $method) {
587
  return round($value, $precision);
588
  }
589
 
590
+ if ('ceil' !== $method && 'floor' !== $method) {
591
  throw new RuntimeError('The round filter only supports the "common", "ceil", and "floor" methods.');
592
  }
593
 
594
+ return $method($value * 10 ** $precision) / 10 ** $precision;
595
  }
596
 
597
  /**
598
  * Number format filter.
599
  *
600
  * All of the formatting options can be left null, in that case the defaults will
601
+ * be used. Supplying any of the parameters will override the defaults set in the
602
  * environment object.
603
  *
604
  * @param mixed $number A float/int/string of the number to format
610
  */
611
  function twig_number_format_filter(Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null)
612
  {
613
+ $defaults = $env->getExtension(CoreExtension::class)->getNumberFormat();
614
  if (null === $decimal) {
615
  $decimal = $defaults[0];
616
  }
629
  /**
630
  * URL encodes (RFC 3986) a string as a path segment or an array as a query string.
631
  *
632
+ * @param string|array|null $url A URL or an array of query parameters
633
  *
634
  * @return string The URL encoded value
635
  */
636
  function twig_urlencode_filter($url)
637
  {
638
  if (\is_array($url)) {
639
+ return http_build_query($url, '', '&', \PHP_QUERY_RFC3986);
 
 
 
 
640
  }
641
 
642
+ return rawurlencode($url ?? '');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
643
  }
644
 
645
  /**
701
  return \array_slice($item, $start, $length, $preserveKeys);
702
  }
703
 
704
+ return (string) mb_substr((string) $item, $start, $length, $env->getCharset());
 
 
 
 
 
 
705
  }
706
 
707
  /**
790
  * {{ "aabbcc"|split('', 2) }}
791
  * {# returns [aa, bb, cc] #}
792
  *
793
+ * @param string|null $value A string
794
+ * @param string $delimiter The delimiter
795
+ * @param int $limit The limit
796
  *
797
  * @return array The split string as an array
798
  */
799
  function twig_split_filter(Environment $env, $value, $delimiter, $limit = null)
800
  {
801
+ $value = $value ?? '';
802
+
803
  if (\strlen($delimiter) > 0) {
804
  return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit);
805
  }
806
 
 
 
 
 
807
  if ($limit <= 1) {
808
  return preg_split('/(?<!^)(?!$)/u', $value);
809
  }
810
 
811
+ $length = mb_strlen($value, $env->getCharset());
812
  if ($length < $limit) {
813
  return [$value];
814
  }
815
 
816
  $r = [];
817
  for ($i = 0; $i < $length; $i += $limit) {
818
+ $r[] = mb_substr($value, $i, $limit, $env->getCharset());
819
  }
820
 
821
  return $r;
885
  /**
886
  * Reverses a variable.
887
  *
888
+ * @param array|\Traversable|string|null $item An array, a \Traversable instance, or a string
889
+ * @param bool $preserveKeys Whether to preserve key or not
890
  *
891
  * @return mixed The reversed input
892
  */
900
  return array_reverse($item, $preserveKeys);
901
  }
902
 
903
+ $string = (string) $item;
 
904
 
905
+ $charset = $env->getCharset();
 
 
906
 
907
+ if ('UTF-8' !== $charset) {
908
+ $string = twig_convert_encoding($string, 'UTF-8', $charset);
909
+ }
910
 
911
+ preg_match_all('/./us', $string, $matches);
912
 
913
+ $string = implode('', array_reverse($matches[0]));
 
 
914
 
915
+ if ('UTF-8' !== $charset) {
916
+ $string = twig_convert_encoding($string, $charset, 'UTF-8');
917
  }
918
 
919
+ return $string;
920
  }
921
 
922
  /**
926
  *
927
  * @return array
928
  */
929
+ function twig_sort_filter(Environment $env, $array, $arrow = null)
930
  {
931
  if ($array instanceof \Traversable) {
932
  $array = iterator_to_array($array);
934
  throw new RuntimeError(sprintf('The sort filter only works with arrays or "Traversable", got "%s".', \gettype($array)));
935
  }
936
 
937
+ if (null !== $arrow) {
938
+ twig_check_arrow_in_sandbox($env, $arrow, 'sort', 'filter');
939
+
940
+ uasort($array, $arrow);
941
+ } else {
942
+ asort($array);
943
+ }
944
 
945
  return $array;
946
  }
985
  /**
986
  * Returns a trimmed string.
987
  *
988
+ * @param string|null $string
989
+ * @param string|null $characterMask
990
+ * @param string $side
991
+ *
992
  * @return string
993
  *
994
  * @throws RuntimeError When an invalid trimming side is used (not a string or not 'left', 'right', or 'both')
1001
 
1002
  switch ($side) {
1003
  case 'both':
1004
+ return trim($string ?? '', $characterMask);
1005
  case 'left':
1006
+ return ltrim($string ?? '', $characterMask);
1007
  case 'right':
1008
+ return rtrim($string ?? '', $characterMask);
1009
  default:
1010
  throw new RuntimeError('Trimming side must be "left", "right" or "both".');
1011
  }
1012
  }
1013
 
1014
  /**
1015
+ * Inserts HTML line breaks before all newlines in a string.
1016
+ *
1017
+ * @param string|null $string
1018
  *
1019
  * @return string
1020
  */
1021
+ function twig_nl2br($string)
1022
  {
1023
+ return nl2br($string ?? '');
1024
  }
1025
 
1026
  /**
1027
+ * Removes whitespaces between HTML tags.
1028
  *
1029
+ * @param string|null $string
 
 
 
1030
  *
1031
  * @return string
1032
  */
1033
+ function twig_spaceless($content)
1034
  {
1035
+ return trim(preg_replace('/>\s+</', '><', $content ?? ''));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1036
  }
1037
 
1038
  /**
1039
+ * @param string|null $string
1040
+ * @param string $to
1041
+ * @param string $from
1042
+ *
1043
+ * @return string
1044
  */
1045
+ function twig_convert_encoding($string, $to, $from)
1046
  {
1047
+ if (!\function_exists('iconv')) {
1048
+ throw new RuntimeError('Unable to convert encoding: required function iconv() does not exist. You should install ext-iconv or symfony/polyfill-iconv.');
 
 
 
 
1049
  }
1050
 
1051
+ return iconv($from, $to, $string ?? '');
1052
  }
1053
 
1054
+ /**
1055
+ * Returns the length of a variable.
1056
+ *
1057
+ * @param mixed $thing A variable
1058
+ *
1059
+ * @return int The length of the value
1060
+ */
1061
+ function twig_length_filter(Environment $env, $thing)
1062
+ {
1063
+ if (null === $thing) {
1064
+ return 0;
 
 
 
1065
  }
 
1066
 
1067
+ if (is_scalar($thing)) {
1068
+ return mb_strlen($thing, $env->getCharset());
 
 
1069
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
1070
 
1071
+ if ($thing instanceof \Countable || \is_array($thing) || $thing instanceof \SimpleXMLElement) {
1072
+ return \count($thing);
1073
  }
 
 
 
 
 
1074
 
1075
+ if ($thing instanceof \Traversable) {
1076
+ return iterator_count($thing);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1077
  }
1078
 
1079
+ if (method_exists($thing, '__toString') && !$thing instanceof \Countable) {
1080
+ return mb_strlen((string) $thing, $env->getCharset());
 
 
 
 
1081
  }
1082
 
1083
+ return 1;
1084
  }
1085
 
1086
+ /**
1087
+ * Converts a string to uppercase.
1088
+ *
1089
+ * @param string|null $string A string
1090
+ *
1091
+ * @return string The uppercased string
1092
+ */
1093
+ function twig_upper_filter(Environment $env, $string)
1094
  {
1095
+ return mb_strtoupper($string ?? '', $env->getCharset());
 
 
1096
  }
1097
 
1098
  /**
1099
+ * Converts a string to lowercase.
1100
+ *
1101
+ * @param string|null $string A string
1102
  *
1103
+ * @return string The lowercased string
 
1104
  */
1105
+ function twig_lower_filter(Environment $env, $string)
1106
  {
1107
+ return mb_strtolower($string ?? '', $env->getCharset());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1108
  }
1109