@vituum/vite-plugin-latte 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. package/README.md +39 -0
  2. package/handler.js +9 -0
  3. package/index.js +138 -0
  4. package/index.php +173 -0
  5. package/latte/AssetFilter.php +11 -0
  6. package/latte/FetchFunction.php +28 -0
  7. package/latte/IconFilter.php +14 -0
  8. package/latte/JsonTag.php +64 -0
  9. package/latte/PlaceholderFunction.php +11 -0
  10. package/latte/RandomColorFunction.php +14 -0
  11. package/latte/TelFilter.php +22 -0
  12. package/package.json +35 -0
  13. package/vendor/autoload.php +7 -0
  14. package/vendor/bin/latte-lint +107 -0
  15. package/vendor/composer/ClassLoader.php +572 -0
  16. package/vendor/composer/InstalledVersions.php +350 -0
  17. package/vendor/composer/LICENSE +21 -0
  18. package/vendor/composer/autoload_classmap.php +183 -0
  19. package/vendor/composer/autoload_namespaces.php +9 -0
  20. package/vendor/composer/autoload_psr4.php +9 -0
  21. package/vendor/composer/autoload_real.php +57 -0
  22. package/vendor/composer/autoload_static.php +193 -0
  23. package/vendor/composer/installed.json +93 -0
  24. package/vendor/composer/installed.php +32 -0
  25. package/vendor/composer/platform_check.php +26 -0
  26. package/vendor/latte/latte/bin/latte-lint +29 -0
  27. package/vendor/latte/latte/composer.json +53 -0
  28. package/vendor/latte/latte/license.md +60 -0
  29. package/vendor/latte/latte/ncs.php +14 -0
  30. package/vendor/latte/latte/ncs.xml +9 -0
  31. package/vendor/latte/latte/readme.md +21 -0
  32. package/vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php +114 -0
  33. package/vendor/latte/latte/src/Bridges/Tracy/LattePanel.php +99 -0
  34. package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.panel.phtml +98 -0
  35. package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.tab.phtml +15 -0
  36. package/vendor/latte/latte/src/Latte/Compiler/Block.php +44 -0
  37. package/vendor/latte/latte/src/Latte/Compiler/Escaper.php +244 -0
  38. package/vendor/latte/latte/src/Latte/Compiler/ExpressionBuilder.php +128 -0
  39. package/vendor/latte/latte/src/Latte/Compiler/Node.php +28 -0
  40. package/vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php +132 -0
  41. package/vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php +77 -0
  42. package/vendor/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php +17 -0
  43. package/vendor/latte/latte/src/Latte/Compiler/Nodes/AuxiliaryNode.php +27 -0
  44. package/vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php +59 -0
  45. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php +48 -0
  46. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php +46 -0
  47. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php +39 -0
  48. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php +129 -0
  49. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/QuotedValue.php +53 -0
  50. package/vendor/latte/latte/src/Latte/Compiler/Nodes/NopNode.php +21 -0
  51. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArgumentNode.php +45 -0
  52. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php +17 -0
  53. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayAccessNode.php +41 -0
  54. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayItemNode.php +52 -0
  55. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php +94 -0
  56. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php +39 -0
  57. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php +45 -0
  58. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php +65 -0
  59. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php +43 -0
  60. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php +42 -0
  61. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php +36 -0
  62. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php +73 -0
  63. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureUseNode.php +37 -0
  64. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php +37 -0
  65. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php +36 -0
  66. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ErrorSuppressNode.php +36 -0
  67. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php +39 -0
  68. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php +45 -0
  69. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallableNode.php +39 -0
  70. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InRangeNode.php +42 -0
  71. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php +40 -0
  72. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php +40 -0
  73. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php +49 -0
  74. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php +50 -0
  75. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallableNode.php +42 -0
  76. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php +45 -0
  77. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NotNode.php +36 -0
  78. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php +43 -0
  79. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php +43 -0
  80. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php +42 -0
  81. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticCallNode.php +55 -0
  82. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticCallableNode.php +47 -0
  83. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php +42 -0
  84. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TernaryNode.php +50 -0
  85. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php +45 -0
  86. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php +40 -0
  87. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php +17 -0
  88. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php +67 -0
  89. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php +36 -0
  90. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IntersectionTypeNode.php +39 -0
  91. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php +45 -0
  92. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php +107 -0
  93. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php +89 -0
  94. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php +35 -0
  95. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ParameterNode.php +54 -0
  96. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php +30 -0
  97. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/EncapsedStringNode.php +80 -0
  98. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/EncapsedStringPartNode.php +30 -0
  99. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php +63 -0
  100. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php +70 -0
  101. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php +29 -0
  102. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/StringNode.php +40 -0
  103. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php +15 -0
  104. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/SuperiorTypeNode.php +29 -0
  105. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/UnionTypeNode.php +39 -0
  106. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php +21 -0
  107. package/vendor/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php +15 -0
  108. package/vendor/latte/latte/src/Latte/Compiler/Nodes/TemplateNode.php +34 -0
  109. package/vendor/latte/latte/src/Latte/Compiler/Nodes/TextNode.php +37 -0
  110. package/vendor/latte/latte/src/Latte/Compiler/PhpHelpers.php +227 -0
  111. package/vendor/latte/latte/src/Latte/Compiler/Position.php +43 -0
  112. package/vendor/latte/latte/src/Latte/Compiler/PrintContext.php +334 -0
  113. package/vendor/latte/latte/src/Latte/Compiler/Tag.php +117 -0
  114. package/vendor/latte/latte/src/Latte/Compiler/TagLexer.php +399 -0
  115. package/vendor/latte/latte/src/Latte/Compiler/TagParser.php +388 -0
  116. package/vendor/latte/latte/src/Latte/Compiler/TagParserData.php +580 -0
  117. package/vendor/latte/latte/src/Latte/Compiler/TemplateGenerator.php +206 -0
  118. package/vendor/latte/latte/src/Latte/Compiler/TemplateLexer.php +391 -0
  119. package/vendor/latte/latte/src/Latte/Compiler/TemplateParser.php +448 -0
  120. package/vendor/latte/latte/src/Latte/Compiler/TemplateParserHtml.php +506 -0
  121. package/vendor/latte/latte/src/Latte/Compiler/Token.php +259 -0
  122. package/vendor/latte/latte/src/Latte/Compiler/TokenStream.php +151 -0
  123. package/vendor/latte/latte/src/Latte/ContentType.php +22 -0
  124. package/vendor/latte/latte/src/Latte/Engine.php +591 -0
  125. package/vendor/latte/latte/src/Latte/Essential/Blueprint.php +160 -0
  126. package/vendor/latte/latte/src/Latte/Essential/CachingIterator.php +232 -0
  127. package/vendor/latte/latte/src/Latte/Essential/CoreExtension.php +232 -0
  128. package/vendor/latte/latte/src/Latte/Essential/Filters.php +591 -0
  129. package/vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php +161 -0
  130. package/vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php +98 -0
  131. package/vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php +74 -0
  132. package/vendor/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php +53 -0
  133. package/vendor/latte/latte/src/Latte/Essential/Nodes/DefineNode.php +134 -0
  134. package/vendor/latte/latte/src/Latte/Essential/Nodes/DoNode.php +49 -0
  135. package/vendor/latte/latte/src/Latte/Essential/Nodes/DumpNode.php +58 -0
  136. package/vendor/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php +125 -0
  137. package/vendor/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php +60 -0
  138. package/vendor/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php +81 -0
  139. package/vendor/latte/latte/src/Latte/Essential/Nodes/ForNode.php +91 -0
  140. package/vendor/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php +155 -0
  141. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php +141 -0
  142. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php +82 -0
  143. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfNode.php +180 -0
  144. package/vendor/latte/latte/src/Latte/Essential/Nodes/ImportNode.php +49 -0
  145. package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php +140 -0
  146. package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php +81 -0
  147. package/vendor/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php +94 -0
  148. package/vendor/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php +105 -0
  149. package/vendor/latte/latte/src/Latte/Essential/Nodes/NClassNode.php +54 -0
  150. package/vendor/latte/latte/src/Latte/Essential/Nodes/NTagNode.php +79 -0
  151. package/vendor/latte/latte/src/Latte/Essential/Nodes/ParametersNode.php +84 -0
  152. package/vendor/latte/latte/src/Latte/Essential/Nodes/PrintNode.php +70 -0
  153. package/vendor/latte/latte/src/Latte/Essential/Nodes/RawPhpNode.php +46 -0
  154. package/vendor/latte/latte/src/Latte/Essential/Nodes/RollbackNode.php +37 -0
  155. package/vendor/latte/latte/src/Latte/Essential/Nodes/SkipNode.php +71 -0
  156. package/vendor/latte/latte/src/Latte/Essential/Nodes/SpacelessNode.php +62 -0
  157. package/vendor/latte/latte/src/Latte/Essential/Nodes/SwitchNode.php +118 -0
  158. package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplatePrintNode.php +39 -0
  159. package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplateTypeNode.php +38 -0
  160. package/vendor/latte/latte/src/Latte/Essential/Nodes/TraceNode.php +35 -0
  161. package/vendor/latte/latte/src/Latte/Essential/Nodes/TranslateNode.php +104 -0
  162. package/vendor/latte/latte/src/Latte/Essential/Nodes/TryNode.php +75 -0
  163. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarNode.php +106 -0
  164. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarPrintNode.php +40 -0
  165. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarTypeNode.php +36 -0
  166. package/vendor/latte/latte/src/Latte/Essential/Nodes/WhileNode.php +81 -0
  167. package/vendor/latte/latte/src/Latte/Essential/Passes.php +115 -0
  168. package/vendor/latte/latte/src/Latte/Essential/RawPhpExtension.php +28 -0
  169. package/vendor/latte/latte/src/Latte/Essential/RollbackException.php +16 -0
  170. package/vendor/latte/latte/src/Latte/Essential/Tracer.php +117 -0
  171. package/vendor/latte/latte/src/Latte/Essential/TranslatorExtension.php +101 -0
  172. package/vendor/latte/latte/src/Latte/Extension.php +97 -0
  173. package/vendor/latte/latte/src/Latte/Helpers.php +96 -0
  174. package/vendor/latte/latte/src/Latte/Loader.php +37 -0
  175. package/vendor/latte/latte/src/Latte/Loaders/FileLoader.php +95 -0
  176. package/vendor/latte/latte/src/Latte/Loaders/StringLoader.php +76 -0
  177. package/vendor/latte/latte/src/Latte/Policy.php +24 -0
  178. package/vendor/latte/latte/src/Latte/PositionAwareException.php +50 -0
  179. package/vendor/latte/latte/src/Latte/Runtime/Block.php +24 -0
  180. package/vendor/latte/latte/src/Latte/Runtime/FilterExecutor.php +151 -0
  181. package/vendor/latte/latte/src/Latte/Runtime/FilterInfo.php +39 -0
  182. package/vendor/latte/latte/src/Latte/Runtime/Filters.php +234 -0
  183. package/vendor/latte/latte/src/Latte/Runtime/Html.php +35 -0
  184. package/vendor/latte/latte/src/Latte/Runtime/HtmlStringable.php +17 -0
  185. package/vendor/latte/latte/src/Latte/Runtime/Template.php +381 -0
  186. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallNode.php +30 -0
  187. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallableNode.php +29 -0
  188. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallNode.php +32 -0
  189. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallableNode.php +30 -0
  190. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/PropertyFetchNode.php +32 -0
  191. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/SandboxNode.php +73 -0
  192. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticCallNode.php +31 -0
  193. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticCallableNode.php +30 -0
  194. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticPropertyFetchNode.php +32 -0
  195. package/vendor/latte/latte/src/Latte/Sandbox/RuntimeChecker.php +116 -0
  196. package/vendor/latte/latte/src/Latte/Sandbox/SandboxExtension.php +132 -0
  197. package/vendor/latte/latte/src/Latte/Sandbox/SecurityPolicy.php +185 -0
  198. package/vendor/latte/latte/src/Latte/Strict.php +101 -0
  199. package/vendor/latte/latte/src/Latte/attributes.php +24 -0
  200. package/vendor/latte/latte/src/Latte/exceptions.php +69 -0
  201. package/vendor/latte/latte/src/Tools/Linter.php +175 -0
@@ -0,0 +1,115 @@
1
+ <?php
2
+
3
+ /**
4
+ * This file is part of the Latte (https://latte.nette.org)
5
+ * Copyright (c) 2008 David Grudl (https://davidgrudl.com)
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace Latte\Essential;
11
+
12
+ use Latte;
13
+ use Latte\CompileException;
14
+ use Latte\Compiler\ExpressionBuilder;
15
+ use Latte\Compiler\Node;
16
+ use Latte\Compiler\Nodes\AuxiliaryNode;
17
+ use Latte\Compiler\Nodes\Php\Expression\FunctionCallNode;
18
+ use Latte\Compiler\Nodes\Php\Expression\VariableNode;
19
+ use Latte\Compiler\Nodes\Php\NameNode;
20
+ use Latte\Compiler\Nodes\TemplateNode;
21
+ use Latte\Compiler\NodeTraverser;
22
+ use Latte\Compiler\PrintContext;
23
+ use Latte\Essential\Nodes\ForeachNode;
24
+
25
+
26
+ final class Passes
27
+ {
28
+ use Latte\Strict;
29
+
30
+ /**
31
+ * Checks if foreach overrides template variables.
32
+ */
33
+ public static function overwrittenVariablesPass(TemplateNode $node): void
34
+ {
35
+ $vars = [];
36
+ (new NodeTraverser)->traverse($node, function (Node $node) use (&$vars) {
37
+ if ($node instanceof ForeachNode && $node->checkArgs) {
38
+ foreach ([$node->key, $node->value] as $var) {
39
+ if ($var instanceof VariableNode) {
40
+ $vars[$var->name][] = $node->position->line;
41
+ }
42
+ }
43
+ }
44
+ });
45
+ if ($vars) {
46
+ array_unshift($node->head->children, new AuxiliaryNode(fn(PrintContext $context) => $context->format(
47
+ <<<'XX'
48
+ if (!$this->getReferringTemplate() || $this->getReferenceType() === 'extends') {
49
+ foreach (array_intersect_key(%dump, $this->params) as $ʟ_v => $ʟ_l) {
50
+ trigger_error("Variable \$$ʟ_v overwritten in foreach on line $ʟ_l");
51
+ }
52
+ }
53
+
54
+ XX,
55
+ array_map(fn($l) => implode(', ', $l), $vars),
56
+ )));
57
+ }
58
+ }
59
+
60
+
61
+ /**
62
+ * Move TemplatePrintNode to head.
63
+ */
64
+ public static function moveTemplatePrintToHeadPass(TemplateNode $templateNode): void
65
+ {
66
+ (new NodeTraverser)->traverse($templateNode->main, function (Node $node) use ($templateNode) {
67
+ if ($node instanceof Latte\Essential\Nodes\TemplatePrintNode) {
68
+ array_unshift($templateNode->head->children, $node);
69
+ return new Latte\Compiler\Nodes\NopNode;
70
+ }
71
+ });
72
+ }
73
+
74
+
75
+ /**
76
+ * Enable custom functions.
77
+ */
78
+ public static function customFunctionsPass(TemplateNode $node, array $functions): void
79
+ {
80
+ $names = array_keys($functions);
81
+ $names = array_combine(array_map('strtolower', $names), $names);
82
+
83
+ (new NodeTraverser)->traverse($node, function (Node $node) use ($names) {
84
+ if (($node instanceof FunctionCallNode || $node instanceof FunctionCallableNode)
85
+ && $node->name instanceof NameNode
86
+ && ($orig = $names[strtolower((string) $node->name)] ?? null)
87
+ ) {
88
+ if ((string) $node->name !== $orig) {
89
+ trigger_error("Case mismatch on function name '{$node->name}', correct name is '$orig'.", E_USER_WARNING);
90
+ }
91
+
92
+ return ExpressionBuilder::function(
93
+ ExpressionBuilder::variable('$this')->property('global')->property('fn')->property($orig),
94
+ $node->args,
95
+ )->build();
96
+ }
97
+ });
98
+ }
99
+
100
+
101
+ /**
102
+ * $ʟ_xxx variables are forbidden
103
+ */
104
+ public static function internalVariablesPass(TemplateNode $node): void
105
+ {
106
+ (new NodeTraverser)->traverse($node, function (Node $node) {
107
+ if ($node instanceof VariableNode
108
+ && is_string($node->name)
109
+ && (str_starts_with($node->name, 'ʟ_'))
110
+ ) {
111
+ throw new CompileException("Forbidden variable \$$node->name.", $node->position);
112
+ }
113
+ });
114
+ }
115
+ }
@@ -0,0 +1,28 @@
1
+ <?php
2
+
3
+ /**
4
+ * This file is part of the Latte (https://latte.nette.org)
5
+ * Copyright (c) 2008 David Grudl (https://davidgrudl.com)
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace Latte\Essential;
11
+
12
+ use Latte;
13
+
14
+
15
+ /**
16
+ * Raw PHP in {php ...}
17
+ */
18
+ final class RawPhpExtension extends Latte\Extension
19
+ {
20
+ use Latte\Strict;
21
+
22
+ public function getTags(): array
23
+ {
24
+ return [
25
+ 'php' => [Nodes\RawPhpNode::class, 'create'],
26
+ ];
27
+ }
28
+ }
@@ -0,0 +1,16 @@
1
+ <?php
2
+
3
+ /**
4
+ * This file is part of the Latte (https://latte.nette.org)
5
+ * Copyright (c) 2008 David Grudl (https://davidgrudl.com)
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace Latte\Essential;
11
+
12
+
13
+ /** @internal */
14
+ class RollbackException extends \Exception
15
+ {
16
+ }
@@ -0,0 +1,117 @@
1
+ <?php
2
+
3
+ /**
4
+ * This file is part of the Latte (https://latte.nette.org)
5
+ * Copyright (c) 2008 David Grudl (https://davidgrudl.com)
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace Latte\Essential;
11
+
12
+ use Latte;
13
+ use Latte\Engine;
14
+ use Latte\Runtime\Template;
15
+
16
+
17
+ /**
18
+ * @internal
19
+ */
20
+ final class Tracer
21
+ {
22
+ public static function throw(): void
23
+ {
24
+ $e = new Latte\RuntimeException('Your location in Latte templates');
25
+ $trace = debug_backtrace();
26
+ $props = [
27
+ 'file' => $trace[1]['object']->getName(),
28
+ 'line' => self::getSourceLine($trace[0]['file'], $trace[0]['line']),
29
+ 'trace' => self::generateTrace($trace),
30
+ ];
31
+ foreach ($props as $name => $value) {
32
+ $ref = new \ReflectionProperty('Exception', $name);
33
+ $ref->setAccessible(true);
34
+ $ref->setValue($e, $value);
35
+ }
36
+
37
+ throw $e;
38
+ }
39
+
40
+
41
+ private static function generateTrace(array $trace): array
42
+ {
43
+ $res = [];
44
+ foreach ($trace as $i => $item) {
45
+ $object = $item['object'] ?? null;
46
+ if ($object instanceof Template) {
47
+ $method = $item['function'] ?? '';
48
+
49
+ if (str_starts_with($method, 'block')) {
50
+ // begin of block
51
+ $comment = (new \ReflectionMethod($object, $method))->getDocComment();
52
+ $res[] = [
53
+ 'function' => preg_match('~(\{.+\})~', $comment, $m) ? $m[1] : '?',
54
+ 'file' => $object->getName(),
55
+ 'line' => preg_match('~ on line (\d+)~', $comment, $m) ? (int) $m[1] : 0,
56
+ 'args' => [], // $L_args is not true, will be added in next step
57
+ ];
58
+
59
+ } elseif ($method === 'render' && $object->getReferenceType()) {
60
+ // begin of included/extended/... file
61
+ $res[] = [
62
+ 'function' => '{' . $object->getReferenceType() . ' ' . basename($object->getName()) . '}',
63
+ 'file' => $object->getReferringTemplate()->getName(),
64
+ 'line' => 0, // will be added in next step
65
+ 'args' => self::filterParams($object->getParameters()),
66
+ ];
67
+
68
+ } elseif ($method === 'renderToContentType') {
69
+ // {include file}, extends, embed, sandbox, ...
70
+ $res[count($res) - 1]['line'] = self::getSourceLine($item['file'], $item['line']);
71
+
72
+ } elseif ($method === 'renderBlock' || $method === 'renderBlockParent') {
73
+ // {include block}
74
+ $res[count($res) - 1]['args'] = self::filterParams($item['args'][1] + $object->getParameters());
75
+
76
+ if ($method !== 'renderBlock' || isset($item['args'][2])) { // is not {block}
77
+ $res[] = [
78
+ 'function' => '{include ' . ($method === 'renderBlockParent' ? 'parent' : $item['args'][0]) . '}',
79
+ 'file' => $object->getName(),
80
+ 'line' => self::getSourceLine($item['file'], $item['line']),
81
+ 'args' => self::filterParams($item['args'][1]),
82
+ ];
83
+ }
84
+ }
85
+ } elseif ($object instanceof Engine) {
86
+ break;
87
+ }
88
+ }
89
+
90
+ return $res;
91
+ }
92
+
93
+
94
+ private static function getSourceLine(string $compiledFile, int $line): int
95
+ {
96
+ if (!is_file($compiledFile)) {
97
+ return 0;
98
+ }
99
+
100
+ $line = file($compiledFile)[$line - 1];
101
+ return preg_match('~/\* line (\d+) \*/~', $line, $m)
102
+ ? (int) $m[1]
103
+ : 0;
104
+ }
105
+
106
+
107
+ private static function filterParams(array $params): array
108
+ {
109
+ foreach ($params as $key => $foo) {
110
+ if (is_string($key) && str_starts_with($key, 'ʟ_')) {
111
+ unset($params[$key]);
112
+ }
113
+ }
114
+
115
+ return $params;
116
+ }
117
+ }
@@ -0,0 +1,101 @@
1
+ <?php
2
+
3
+ /**
4
+ * This file is part of the Latte (https://latte.nette.org)
5
+ * Copyright (c) 2008 David Grudl (https://davidgrudl.com)
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace Latte\Essential;
11
+
12
+ use Latte;
13
+ use Latte\Compiler\NodeHelpers;
14
+ use Latte\Compiler\Nodes\Php;
15
+ use Latte\Compiler\Tag;
16
+ use Latte\Engine;
17
+ use Latte\Essential\Nodes\PrintNode;
18
+ use Nette\Localization\Translator;
19
+
20
+
21
+ /**
22
+ * Extension for translations.
23
+ */
24
+ final class TranslatorExtension extends Latte\Extension
25
+ {
26
+ public function __construct(
27
+ private /*?callable|Translator*/ $translator,
28
+ private ?string $key = null,
29
+ ) {
30
+ if ($translator instanceof Translator) {
31
+ $this->translator = [$translator, 'translate'];
32
+ }
33
+ }
34
+
35
+
36
+ public function getTags(): array
37
+ {
38
+ return [
39
+ '_' => [$this, 'parseTranslate'],
40
+ 'translate' => fn(Tag $tag) => yield from Nodes\TranslateNode::create($tag, $this->key ? $this->translator : null),
41
+ ];
42
+ }
43
+
44
+
45
+ public function getFilters(): array
46
+ {
47
+ return [
48
+ 'translate' => fn(Latte\Runtime\FilterInfo $fi, ...$args): string => $this->translator
49
+ ? ($this->translator)(...$args)
50
+ : $args[0],
51
+ ];
52
+ }
53
+
54
+
55
+ public function getCacheKey(Engine $engine): mixed
56
+ {
57
+ return $this->key;
58
+ }
59
+
60
+
61
+ /**
62
+ * {_ ...}
63
+ */
64
+ public function parseTranslate(Tag $tag): PrintNode
65
+ {
66
+ $tag->outputMode = $tag::OutputKeepIndentation;
67
+ $tag->expectArguments();
68
+ $node = new PrintNode;
69
+ $node->expression = $tag->parser->parseUnquotedStringOrExpression();
70
+ $args = new Php\Expression\ArrayNode;
71
+ if ($tag->parser->stream->tryConsume(',')) {
72
+ $args = $tag->parser->parseArguments();
73
+ }
74
+
75
+ $node->modifier = $tag->parser->parseModifier();
76
+ $node->modifier->escape = true;
77
+
78
+ if ($this->translator
79
+ && $this->key
80
+ && ($expr = self::toValue($node->expression))
81
+ && is_array($values = self::toValue($args))
82
+ && is_string($translation = ($this->translator)($expr, ...$values))
83
+ ) {
84
+ $node->expression = new Php\Scalar\StringNode($translation);
85
+ return $node;
86
+ }
87
+
88
+ array_unshift($node->modifier->filters, new Php\FilterNode(new Php\IdentifierNode('translate'), $args->toArguments()));
89
+ return $node;
90
+ }
91
+
92
+
93
+ public static function toValue($args): mixed
94
+ {
95
+ try {
96
+ return NodeHelpers::toValue($args, constants: true);
97
+ } catch (\InvalidArgumentException) {
98
+ return null;
99
+ }
100
+ }
101
+ }
@@ -0,0 +1,97 @@
1
+ <?php
2
+
3
+ /**
4
+ * This file is part of the Latte (https://latte.nette.org)
5
+ * Copyright (c) 2008 David Grudl (https://davidgrudl.com)
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace Latte;
11
+
12
+
13
+ /**
14
+ * Latte extension.
15
+ */
16
+ abstract class Extension
17
+ {
18
+ /**
19
+ * Initializes before template is compiler.
20
+ */
21
+ public function beforeCompile(Engine $engine): void
22
+ {
23
+ }
24
+
25
+
26
+ /**
27
+ * Returns a list of parsers for Latte tags.
28
+ * @return array<string, callable(Compiler\Tag, Compiler\TemplateParser): (Compiler\Node|\Generator|void)|\stdClass>
29
+ */
30
+ public function getTags(): array
31
+ {
32
+ return [];
33
+ }
34
+
35
+
36
+ /**
37
+ * Returns a list of parsers for Latte tags.
38
+ * @return array<string, callable(Compiler\Nodes\TemplateNode): void|\stdClass>
39
+ */
40
+ public function getPasses(): array
41
+ {
42
+ return [];
43
+ }
44
+
45
+
46
+ /**
47
+ * Returns a list of |filters.
48
+ * @return array<string, callable>
49
+ */
50
+ public function getFilters(): array
51
+ {
52
+ return [];
53
+ }
54
+
55
+
56
+ /**
57
+ * Returns a list of functions used in templates.
58
+ * @return array<string, callable>
59
+ */
60
+ public function getFunctions(): array
61
+ {
62
+ return [];
63
+ }
64
+
65
+
66
+ /**
67
+ * Returns a list of providers.
68
+ * @return array<mixed>
69
+ */
70
+ public function getProviders(): array
71
+ {
72
+ return [];
73
+ }
74
+
75
+
76
+ /**
77
+ * Returns a value to distinguish multiple versions of the template.
78
+ */
79
+ public function getCacheKey(Engine $engine): mixed
80
+ {
81
+ return null;
82
+ }
83
+
84
+
85
+ /**
86
+ * Initializes before template is rendered.
87
+ */
88
+ public function beforeRender(Engine $engine): void
89
+ {
90
+ }
91
+
92
+
93
+ public static function order(callable $subject, array|string $before = [], array|string $after = []): \stdClass
94
+ {
95
+ return (object) get_defined_vars();
96
+ }
97
+ }
@@ -0,0 +1,96 @@
1
+ <?php
2
+
3
+ /**
4
+ * This file is part of the Latte (https://latte.nette.org)
5
+ * Copyright (c) 2008 David Grudl (https://davidgrudl.com)
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace Latte;
11
+
12
+
13
+ /**
14
+ * Latte helpers.
15
+ * @internal
16
+ */
17
+ class Helpers
18
+ {
19
+ /** @var array<string, int> empty (void) HTML elements */
20
+ public static array $emptyElements = [
21
+ 'img' => 1, 'hr' => 1, 'br' => 1, 'input' => 1, 'meta' => 1, 'area' => 1, 'embed' => 1, 'keygen' => 1, 'source' => 1, 'base' => 1,
22
+ 'col' => 1, 'link' => 1, 'param' => 1, 'basefont' => 1, 'frame' => 1, 'isindex' => 1, 'wbr' => 1, 'command' => 1, 'track' => 1,
23
+ ];
24
+
25
+
26
+ /**
27
+ * Finds the best suggestion.
28
+ * @param string[] $items
29
+ */
30
+ public static function getSuggestion(array $items, string $value): ?string
31
+ {
32
+ $best = null;
33
+ $min = (strlen($value) / 4 + 1) * 10 + .1;
34
+ foreach (array_unique($items) as $item) {
35
+ if (($len = levenshtein($item, $value, 10, 11, 10)) > 0 && $len < $min) {
36
+ $min = $len;
37
+ $best = $item;
38
+ }
39
+ }
40
+
41
+ return $best;
42
+ }
43
+
44
+
45
+ /** intentionally without callable typehint, because it generates bad error messages */
46
+ public static function toReflection($callable): \ReflectionFunctionAbstract
47
+ {
48
+ if (is_string($callable) && strpos($callable, '::')) {
49
+ return new \ReflectionMethod($callable);
50
+ } elseif (is_array($callable)) {
51
+ return new \ReflectionMethod($callable[0], $callable[1]);
52
+ } elseif (is_object($callable) && !$callable instanceof \Closure) {
53
+ return new \ReflectionMethod($callable, '__invoke');
54
+ } else {
55
+ return new \ReflectionFunction($callable);
56
+ }
57
+ }
58
+
59
+
60
+ public static function sortBeforeAfter(array $list): array
61
+ {
62
+ foreach ($list as $name => $info) {
63
+ if (!$info instanceof \stdClass || !($info->before ?? $info->after ?? null)) {
64
+ continue;
65
+ }
66
+
67
+ unset($list[$name]);
68
+ $names = array_keys($list);
69
+ $best = null;
70
+
71
+ foreach ((array) $info->before as $target) {
72
+ if ($target === '*') {
73
+ $best = 0;
74
+ } elseif (isset($list[$target])) {
75
+ $pos = array_search($target, $names, true);
76
+ $best = min($pos, $best ?? $pos);
77
+ }
78
+ }
79
+
80
+ foreach ((array) ($info->after ?? null) as $target) {
81
+ if ($target === '*') {
82
+ $best = count($names);
83
+ } elseif (isset($list[$target])) {
84
+ $pos = array_search($target, $names, true);
85
+ $best = max($pos + 1, $best);
86
+ }
87
+ }
88
+
89
+ $list = array_slice($list, 0, $best, true)
90
+ + [$name => $info]
91
+ + array_slice($list, $best, null, true);
92
+ }
93
+
94
+ return $list;
95
+ }
96
+ }
@@ -0,0 +1,37 @@
1
+ <?php
2
+
3
+ /**
4
+ * This file is part of the Latte (https://latte.nette.org)
5
+ * Copyright (c) 2008 David Grudl (https://davidgrudl.com)
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace Latte;
11
+
12
+
13
+ /**
14
+ * Template loader.
15
+ */
16
+ interface Loader
17
+ {
18
+ /**
19
+ * Returns template source code.
20
+ */
21
+ function getContent(string $name): string;
22
+
23
+ /**
24
+ * Checks whether template is expired.
25
+ */
26
+ function isExpired(string $name, int $time): bool;
27
+
28
+ /**
29
+ * Returns referred template name.
30
+ */
31
+ function getReferredName(string $name, string $referringName): string;
32
+
33
+ /**
34
+ * Returns unique identifier for caching.
35
+ */
36
+ function getUniqueId(string $name): string;
37
+ }
@@ -0,0 +1,95 @@
1
+ <?php
2
+
3
+ /**
4
+ * This file is part of the Latte (https://latte.nette.org)
5
+ * Copyright (c) 2008 David Grudl (https://davidgrudl.com)
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace Latte\Loaders;
11
+
12
+ use Latte;
13
+
14
+
15
+ /**
16
+ * Template loader.
17
+ */
18
+ class FileLoader implements Latte\Loader
19
+ {
20
+ use Latte\Strict;
21
+
22
+ protected ?string $baseDir = null;
23
+
24
+
25
+ public function __construct(?string $baseDir = null)
26
+ {
27
+ $this->baseDir = $baseDir ? $this->normalizePath("$baseDir/") : null;
28
+ }
29
+
30
+
31
+ /**
32
+ * Returns template source code.
33
+ */
34
+ public function getContent(string $fileName): string
35
+ {
36
+ $file = $this->baseDir . $fileName;
37
+ if ($this->baseDir && !str_starts_with($this->normalizePath($file), $this->baseDir)) {
38
+ throw new Latte\RuntimeException("Template '$file' is not within the allowed path '{$this->baseDir}'.");
39
+
40
+ } elseif (!is_file($file)) {
41
+ throw new Latte\RuntimeException("Missing template file '$file'.");
42
+
43
+ } elseif ($this->isExpired($fileName, time())) {
44
+ if (@touch($file) === false) {
45
+ trigger_error("File's modification time is in the future. Cannot update it: " . error_get_last()['message'], E_USER_WARNING);
46
+ }
47
+ }
48
+
49
+ return file_get_contents($file);
50
+ }
51
+
52
+
53
+ public function isExpired(string $file, int $time): bool
54
+ {
55
+ $mtime = @filemtime($this->baseDir . $file); // @ - stat may fail
56
+ return !$mtime || $mtime > $time;
57
+ }
58
+
59
+
60
+ /**
61
+ * Returns referred template name.
62
+ */
63
+ public function getReferredName(string $file, string $referringFile): string
64
+ {
65
+ if ($this->baseDir || !preg_match('#/|\\\\|[a-z][a-z0-9+.-]*:#iA', $file)) {
66
+ $file = $this->normalizePath($referringFile . '/../' . $file);
67
+ }
68
+
69
+ return $file;
70
+ }
71
+
72
+
73
+ /**
74
+ * Returns unique identifier for caching.
75
+ */
76
+ public function getUniqueId(string $file): string
77
+ {
78
+ return $this->baseDir . strtr($file, '/', DIRECTORY_SEPARATOR);
79
+ }
80
+
81
+
82
+ protected static function normalizePath(string $path): string
83
+ {
84
+ $res = [];
85
+ foreach (explode('/', strtr($path, '\\', '/')) as $part) {
86
+ if ($part === '..' && $res && end($res) !== '..') {
87
+ array_pop($res);
88
+ } elseif ($part !== '.') {
89
+ $res[] = $part;
90
+ }
91
+ }
92
+
93
+ return implode(DIRECTORY_SEPARATOR, $res);
94
+ }
95
+ }