@vituum/vite-plugin-latte 2.0.0-next.4 → 2.0.0
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.
- package/README.md +1 -1
- package/index.js +4 -2
- package/package.json +11 -9
- package/types/index.d.ts +1 -1
- package/vendor/autoload.php +1 -4
- package/vendor/composer/InstalledVersions.php +36 -2
- package/vendor/composer/autoload_classmap.php +14 -15
- package/vendor/composer/autoload_psr4.php +2 -0
- package/vendor/composer/autoload_static.php +38 -15
- package/vendor/composer/installed.json +32 -22
- package/vendor/composer/installed.php +12 -12
- package/vendor/composer/platform_check.php +4 -5
- package/vendor/latte/latte/bin/latte-lint +10 -3
- package/vendor/latte/latte/composer.json +16 -6
- package/vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php +13 -38
- package/vendor/latte/latte/src/Bridges/Tracy/LattePanel.php +9 -7
- package/vendor/latte/latte/src/Bridges/Tracy/TracyExtension.php +2 -4
- package/vendor/latte/latte/src/Bridges/Tracy/dist/panel.phtml +94 -0
- package/vendor/latte/latte/src/Bridges/Tracy/dist/tab.phtml +10 -0
- package/vendor/latte/latte/src/Latte/Compiler/Block.php +4 -6
- package/vendor/latte/latte/src/Latte/Compiler/Escaper.php +67 -86
- package/vendor/latte/latte/src/Latte/Compiler/Node.php +6 -3
- package/vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php +16 -6
- package/vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php +25 -12
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php +7 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/AuxiliaryNode.php +5 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php +8 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php +7 -15
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php +4 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php +37 -67
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ExpressionAttributeNode.php +60 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/TagNode.php +70 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/NopNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArgumentNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArrayItemNode.php +4 -15
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ClosureUseNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayAccessNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php +6 -22
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php +18 -5
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php +18 -7
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AuxiliaryNode.php +5 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php +38 -9
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php +14 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php +12 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php +10 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php +7 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php +10 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php +14 -5
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php +14 -5
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php +6 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php +6 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php +18 -5
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php +14 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php +14 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php +14 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallNode.php +14 -15
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TemporaryNode.php +7 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TernaryNode.php +16 -11
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php +19 -9
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php +33 -8
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/InterpolatedStringPartNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IntersectionTypeNode.php +6 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListItemNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php +6 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php +29 -41
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php +9 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/OperatorNode.php +27 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ParameterNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php +9 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php +8 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/InterpolatedStringNode.php +9 -5
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/StringNode.php +6 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/SuperiorTypeNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/UnionTypeNode.php +6 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/{Expression/NotNode.php → VariadicPlaceholderNode.php} +9 -9
- package/vendor/latte/latte/src/Latte/{Essential → Compiler}/Nodes/PrintNode.php +9 -15
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php +7 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/TemplateNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/TextNode.php +6 -4
- package/vendor/latte/latte/src/Latte/Compiler/PhpHelpers.php +32 -18
- package/vendor/latte/latte/src/Latte/Compiler/Position.php +7 -7
- package/vendor/latte/latte/src/Latte/Compiler/PrintContext.php +72 -104
- package/vendor/latte/latte/src/Latte/Compiler/Tag.php +17 -16
- package/vendor/latte/latte/src/Latte/Compiler/TagLexer.php +11 -8
- package/vendor/latte/latte/src/Latte/Compiler/TagParser.php +28 -23
- package/vendor/latte/latte/src/Latte/Compiler/TagParserData.php +360 -336
- package/vendor/latte/latte/src/Latte/Compiler/TemplateGenerator.php +49 -38
- package/vendor/latte/latte/src/Latte/Compiler/TemplateLexer.php +37 -12
- package/vendor/latte/latte/src/Latte/Compiler/TemplateParser.php +35 -21
- package/vendor/latte/latte/src/Latte/Compiler/TemplateParserHtml.php +121 -71
- package/vendor/latte/latte/src/Latte/Compiler/Token.php +79 -70
- package/vendor/latte/latte/src/Latte/Compiler/TokenStream.php +21 -14
- package/vendor/latte/latte/src/Latte/ContentType.php +4 -3
- package/vendor/latte/latte/src/Latte/Engine.php +147 -188
- package/vendor/latte/latte/src/Latte/Essential/AuxiliaryIterator.php +5 -7
- package/vendor/latte/latte/src/Latte/Essential/Blueprint.php +5 -5
- package/vendor/latte/latte/src/Latte/Essential/CachingIterator.php +5 -4
- package/vendor/latte/latte/src/Latte/Essential/CoreExtension.php +155 -127
- package/vendor/latte/latte/src/Latte/Essential/Filters.php +99 -44
- package/vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php +14 -13
- package/vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php +5 -6
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php +3 -4
- package/vendor/latte/latte/src/Latte/Essential/Nodes/CustomFunctionCallNode.php +46 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php +2 -3
- package/vendor/latte/latte/src/Latte/Essential/Nodes/DefineNode.php +10 -7
- package/vendor/latte/latte/src/Latte/Essential/Nodes/DoNode.php +3 -4
- package/vendor/latte/latte/src/Latte/Essential/Nodes/DumpNode.php +2 -3
- package/vendor/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php +8 -9
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php +3 -5
- package/vendor/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php +4 -7
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ForNode.php +6 -5
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php +7 -7
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php +4 -5
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php +7 -6
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IfNode.php +11 -11
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ImportNode.php +5 -6
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php +26 -27
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php +7 -10
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php +6 -6
- package/vendor/latte/latte/src/Latte/Essential/Nodes/JumpNode.php +4 -8
- package/vendor/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php +35 -47
- package/vendor/latte/latte/src/Latte/Essential/Nodes/NClassNode.php +4 -5
- package/vendor/latte/latte/src/Latte/Essential/Nodes/NElseNode.php +69 -34
- package/vendor/latte/latte/src/Latte/Essential/Nodes/NTagNode.php +9 -33
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ParametersNode.php +7 -4
- package/vendor/latte/latte/src/Latte/Essential/Nodes/RawPhpNode.php +3 -4
- package/vendor/latte/latte/src/Latte/Essential/Nodes/RollbackNode.php +2 -3
- package/vendor/latte/latte/src/Latte/Essential/Nodes/SpacelessNode.php +4 -5
- package/vendor/latte/latte/src/Latte/Essential/Nodes/SwitchNode.php +9 -7
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplatePrintNode.php +4 -4
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplateTypeNode.php +3 -4
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TraceNode.php +2 -3
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TranslateNode.php +5 -5
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TryNode.php +4 -5
- package/vendor/latte/latte/src/Latte/Essential/Nodes/VarNode.php +10 -6
- package/vendor/latte/latte/src/Latte/Essential/Nodes/VarPrintNode.php +2 -3
- package/vendor/latte/latte/src/Latte/Essential/Nodes/VarTypeNode.php +3 -4
- package/vendor/latte/latte/src/Latte/Essential/Nodes/WhileNode.php +5 -5
- package/vendor/latte/latte/src/Latte/Essential/Passes.php +82 -21
- package/vendor/latte/latte/src/Latte/Essential/RawPhpExtension.php +2 -4
- package/vendor/latte/latte/src/Latte/Essential/RollbackException.php +1 -3
- package/vendor/latte/latte/src/Latte/Essential/Tracer.php +24 -28
- package/vendor/latte/latte/src/Latte/Essential/TranslatorExtension.php +14 -14
- package/vendor/latte/latte/src/Latte/Extension.php +12 -6
- package/vendor/latte/latte/src/Latte/Feature.php +24 -0
- package/vendor/latte/latte/src/Latte/Helpers.php +65 -15
- package/vendor/latte/latte/src/Latte/Loader.php +1 -9
- package/vendor/latte/latte/src/Latte/Loaders/FileLoader.php +11 -17
- package/vendor/latte/latte/src/Latte/Loaders/StringLoader.php +7 -21
- package/vendor/latte/latte/src/Latte/Policy.php +4 -3
- package/vendor/latte/latte/src/Latte/Runtime/Block.php +2 -4
- package/vendor/latte/latte/src/Latte/Runtime/Cache.php +143 -0
- package/vendor/latte/latte/src/Latte/Runtime/FilterExecutor.php +5 -6
- package/vendor/latte/latte/src/Latte/Runtime/FilterInfo.php +11 -11
- package/vendor/latte/latte/src/Latte/Runtime/FunctionExecutor.php +5 -6
- package/vendor/latte/latte/src/Latte/Runtime/Helpers.php +91 -0
- package/vendor/latte/latte/src/Latte/Runtime/Html.php +3 -5
- package/vendor/latte/latte/src/Latte/Runtime/HtmlHelpers.php +374 -0
- package/vendor/latte/latte/src/Latte/Runtime/HtmlStringable.php +1 -3
- package/vendor/latte/latte/src/Latte/Runtime/Template.php +162 -182
- package/vendor/latte/latte/src/Latte/Runtime/XmlHelpers.php +108 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallNode.php +12 -4
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallNode.php +15 -5
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/PropertyFetchNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/SandboxNode.php +5 -6
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticMethodCallNode.php +14 -4
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticPropertyFetchNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Sandbox/RuntimeChecker.php +8 -6
- package/vendor/latte/latte/src/Latte/Sandbox/SandboxExtension.php +16 -12
- package/vendor/latte/latte/src/Latte/Sandbox/SecurityPolicy.php +18 -16
- package/vendor/latte/latte/src/Latte/attributes.php +7 -3
- package/vendor/latte/latte/src/Latte/exceptions.php +52 -6
- package/vendor/latte/latte/src/Tools/Linter.php +74 -28
- package/vendor/latte/latte/src/Tools/LinterExtension.php +176 -0
- package/vendor/nette/utils/composer.json +15 -5
- package/vendor/nette/utils/readme.md +1 -1
- package/vendor/nette/utils/src/HtmlStringable.php +4 -1
- package/vendor/nette/utils/src/Iterators/CachingIterator.php +10 -25
- package/vendor/nette/utils/src/Iterators/Mapper.php +2 -3
- package/vendor/nette/utils/src/SmartObject.php +3 -0
- package/vendor/nette/utils/src/StaticClass.php +1 -11
- package/vendor/nette/utils/src/Translator.php +1 -1
- package/vendor/nette/utils/src/Utils/ArrayHash.php +6 -10
- package/vendor/nette/utils/src/Utils/ArrayList.php +8 -12
- package/vendor/nette/utils/src/Utils/Arrays.php +38 -18
- package/vendor/nette/utils/src/Utils/Callback.php +13 -8
- package/vendor/nette/utils/src/Utils/DateTime.php +95 -26
- package/vendor/nette/utils/src/Utils/FileInfo.php +6 -7
- package/vendor/nette/utils/src/Utils/FileSystem.php +10 -5
- package/vendor/nette/utils/src/Utils/Finder.php +31 -12
- package/vendor/nette/utils/src/Utils/Floats.php +1 -0
- package/vendor/nette/utils/src/Utils/Helpers.php +22 -2
- package/vendor/nette/utils/src/Utils/Html.php +130 -127
- package/vendor/nette/utils/src/Utils/Image.php +80 -60
- package/vendor/nette/utils/src/Utils/ImageColor.php +5 -0
- package/vendor/nette/utils/src/Utils/ImageType.php +2 -0
- package/vendor/nette/utils/src/Utils/Iterables.php +41 -7
- package/vendor/nette/utils/src/Utils/Json.php +2 -0
- package/vendor/nette/utils/src/Utils/ObjectHelpers.php +2 -0
- package/vendor/nette/utils/src/Utils/Paginator.php +10 -43
- package/vendor/nette/utils/src/Utils/Random.php +2 -0
- package/vendor/nette/utils/src/Utils/Reflection.php +22 -15
- package/vendor/nette/utils/src/Utils/ReflectionMethod.php +6 -1
- package/vendor/nette/utils/src/Utils/Strings.php +62 -57
- package/vendor/nette/utils/src/Utils/Type.php +91 -42
- package/vendor/nette/utils/src/Utils/Validators.php +9 -7
- package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.panel.phtml +0 -101
- package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.tab.phtml +0 -15
- package/vendor/latte/latte/src/Latte/Compiler/ExpressionBuilder.php +0 -129
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ErrorSuppressNode.php +0 -36
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallableNode.php +0 -39
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallableNode.php +0 -42
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallableNode.php +0 -57
- package/vendor/latte/latte/src/Latte/PositionAwareException.php +0 -47
- package/vendor/latte/latte/src/Latte/Runtime/Filters.php +0 -283
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallableNode.php +0 -29
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallableNode.php +0 -30
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticMethodCallableNode.php +0 -30
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
<?php
|
|
1
|
+
<?php declare(strict_types=1);
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is part of the Latte (https://latte.nette.org)
|
|
5
5
|
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
declare(strict_types=1);
|
|
9
|
-
|
|
10
8
|
namespace Latte\Essential;
|
|
11
9
|
|
|
12
10
|
use Latte;
|
|
13
11
|
use Latte\Compiler\NodeHelpers;
|
|
14
12
|
use Latte\Compiler\Nodes\Php;
|
|
13
|
+
use Latte\Compiler\Nodes\Php\ExpressionNode;
|
|
14
|
+
use Latte\Compiler\Nodes\PrintNode;
|
|
15
15
|
use Latte\Compiler\Tag;
|
|
16
16
|
use Latte\Engine;
|
|
17
|
-
use Latte\Essential\Nodes\PrintNode;
|
|
18
17
|
use Nette\Localization\Translator;
|
|
18
|
+
use function array_unshift, is_array, is_string;
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
/**
|
|
@@ -23,25 +23,25 @@ use Nette\Localization\Translator;
|
|
|
23
23
|
*/
|
|
24
24
|
final class TranslatorExtension extends Latte\Extension
|
|
25
25
|
{
|
|
26
|
-
|
|
27
|
-
private $translator;
|
|
26
|
+
private ?\Closure $translator;
|
|
28
27
|
|
|
29
28
|
|
|
30
29
|
public function __construct(
|
|
31
30
|
callable|Translator|null $translator,
|
|
32
31
|
private ?string $key = null,
|
|
33
32
|
) {
|
|
34
|
-
$this->translator =
|
|
35
|
-
|
|
36
|
-
$
|
|
37
|
-
|
|
33
|
+
$this->translator = match (true) {
|
|
34
|
+
$translator === null => null,
|
|
35
|
+
$translator instanceof Translator => $translator->translate(...),
|
|
36
|
+
default => $translator(...),
|
|
37
|
+
};
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
public function getTags(): array
|
|
42
42
|
{
|
|
43
43
|
return [
|
|
44
|
-
'_' =>
|
|
44
|
+
'_' => $this->parseTranslate(...),
|
|
45
45
|
'translate' => fn(Tag $tag) => yield from Nodes\TranslateNode::create($tag, $this->key ? $this->translator : null),
|
|
46
46
|
];
|
|
47
47
|
}
|
|
@@ -66,7 +66,7 @@ final class TranslatorExtension extends Latte\Extension
|
|
|
66
66
|
/**
|
|
67
67
|
* {_ ...}
|
|
68
68
|
*/
|
|
69
|
-
|
|
69
|
+
private function parseTranslate(Tag $tag): PrintNode
|
|
70
70
|
{
|
|
71
71
|
$tag->outputMode = $tag::OutputKeepIndentation;
|
|
72
72
|
$tag->expectArguments();
|
|
@@ -78,7 +78,7 @@ final class TranslatorExtension extends Latte\Extension
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
$node->modifier = $tag->parser->parseModifier();
|
|
81
|
-
$node->modifier->escape =
|
|
81
|
+
$node->modifier->escape = !$node->modifier->removeFilter('noescape');
|
|
82
82
|
|
|
83
83
|
if ($this->translator
|
|
84
84
|
&& $this->key
|
|
@@ -95,7 +95,7 @@ final class TranslatorExtension extends Latte\Extension
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
|
|
98
|
-
public static function toValue($args): mixed
|
|
98
|
+
public static function toValue(ExpressionNode $args): mixed
|
|
99
99
|
{
|
|
100
100
|
try {
|
|
101
101
|
return NodeHelpers::toValue($args, constants: true);
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
<?php
|
|
1
|
+
<?php declare(strict_types=1);
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is part of the Latte (https://latte.nette.org)
|
|
5
5
|
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
declare(strict_types=1);
|
|
9
|
-
|
|
10
8
|
namespace Latte;
|
|
11
9
|
|
|
10
|
+
use function get_defined_vars;
|
|
11
|
+
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Latte extension.
|
|
@@ -16,7 +16,7 @@ namespace Latte;
|
|
|
16
16
|
abstract class Extension
|
|
17
17
|
{
|
|
18
18
|
/**
|
|
19
|
-
* Initializes before template is
|
|
19
|
+
* Initializes before template is compiled.
|
|
20
20
|
*/
|
|
21
21
|
public function beforeCompile(Engine $engine): void
|
|
22
22
|
{
|
|
@@ -34,7 +34,7 @@ abstract class Extension
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
|
-
* Returns a list of
|
|
37
|
+
* Returns a list of compiler passes.
|
|
38
38
|
* @return array<string, callable(Compiler\Nodes\TemplateNode): void|\stdClass>
|
|
39
39
|
*/
|
|
40
40
|
public function getPasses(): array
|
|
@@ -65,7 +65,7 @@ abstract class Extension
|
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
67
|
* Returns a list of providers.
|
|
68
|
-
* @return array<mixed>
|
|
68
|
+
* @return array<string, mixed>
|
|
69
69
|
*/
|
|
70
70
|
public function getProviders(): array
|
|
71
71
|
{
|
|
@@ -90,8 +90,14 @@ abstract class Extension
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Wraps callable with ordering metadata for tags and passes.
|
|
95
|
+
* @param array<string>|string $before
|
|
96
|
+
* @param array<string>|string $after
|
|
97
|
+
*/
|
|
93
98
|
public static function order(callable $subject, array|string $before = [], array|string $after = []): \stdClass
|
|
94
99
|
{
|
|
100
|
+
$subject = $subject(...);
|
|
95
101
|
return (object) get_defined_vars();
|
|
96
102
|
}
|
|
97
103
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<?php declare(strict_types=1);
|
|
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
|
+
namespace Latte;
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Latte engine feature flags.
|
|
13
|
+
*/
|
|
14
|
+
enum Feature
|
|
15
|
+
{
|
|
16
|
+
/** Adds declare(strict_types=1) to compiled templates (enabled by default) */
|
|
17
|
+
case StrictTypes;
|
|
18
|
+
|
|
19
|
+
/** Enforces strict HTML parsing */
|
|
20
|
+
case StrictParsing;
|
|
21
|
+
|
|
22
|
+
/** Shows warnings for deprecated Latte 3.0 syntax */
|
|
23
|
+
case MigrationWarnings;
|
|
24
|
+
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
<?php
|
|
1
|
+
<?php declare(strict_types=1);
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is part of the Latte (https://latte.nette.org)
|
|
5
5
|
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
declare(strict_types=1);
|
|
9
|
-
|
|
10
8
|
namespace Latte;
|
|
11
9
|
|
|
10
|
+
use function array_filter, array_keys, array_search, array_slice, array_unique, count, is_array, is_object, is_string, levenshtein, max, min, strlen, strpos;
|
|
11
|
+
use const PHP_VERSION_ID;
|
|
12
|
+
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Latte helpers.
|
|
@@ -16,13 +17,6 @@ namespace Latte;
|
|
|
16
17
|
*/
|
|
17
18
|
class Helpers
|
|
18
19
|
{
|
|
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
20
|
/**
|
|
27
21
|
* Finds the best suggestion.
|
|
28
22
|
* @param string[] $items
|
|
@@ -43,7 +37,7 @@ class Helpers
|
|
|
43
37
|
|
|
44
38
|
|
|
45
39
|
/** intentionally without callable typehint, because it generates bad error messages */
|
|
46
|
-
public static function toReflection($callable): \ReflectionFunctionAbstract
|
|
40
|
+
public static function toReflection(mixed $callable): \ReflectionFunctionAbstract
|
|
47
41
|
{
|
|
48
42
|
if (is_string($callable) && strpos($callable, '::')) {
|
|
49
43
|
return PHP_VERSION_ID < 80300
|
|
@@ -59,6 +53,10 @@ class Helpers
|
|
|
59
53
|
}
|
|
60
54
|
|
|
61
55
|
|
|
56
|
+
/**
|
|
57
|
+
* @param array<string, mixed|\stdClass> $list
|
|
58
|
+
* @return array<string, mixed|\stdClass>
|
|
59
|
+
*/
|
|
62
60
|
public static function sortBeforeAfter(array $list): array
|
|
63
61
|
{
|
|
64
62
|
foreach ($list as $name => $info) {
|
|
@@ -74,7 +72,7 @@ class Helpers
|
|
|
74
72
|
if ($target === '*') {
|
|
75
73
|
$best = 0;
|
|
76
74
|
} elseif (isset($list[$target])) {
|
|
77
|
-
$pos = array_search($target, $names, true);
|
|
75
|
+
$pos = (int) array_search($target, $names, strict: true);
|
|
78
76
|
$best = min($pos, $best ?? $pos);
|
|
79
77
|
}
|
|
80
78
|
}
|
|
@@ -83,16 +81,68 @@ class Helpers
|
|
|
83
81
|
if ($target === '*') {
|
|
84
82
|
$best = count($names);
|
|
85
83
|
} elseif (isset($list[$target])) {
|
|
86
|
-
$pos = array_search($target, $names, true);
|
|
84
|
+
$pos = (int) array_search($target, $names, strict: true);
|
|
87
85
|
$best = max($pos + 1, $best);
|
|
88
86
|
}
|
|
89
87
|
}
|
|
90
88
|
|
|
91
|
-
$
|
|
89
|
+
$best ??= count($names);
|
|
90
|
+
$list = array_slice($list, 0, $best, preserve_keys: true)
|
|
92
91
|
+ [$name => $info]
|
|
93
|
-
+ array_slice($list, $best, null, true);
|
|
92
|
+
+ array_slice($list, $best, null, preserve_keys: true);
|
|
94
93
|
}
|
|
95
94
|
|
|
96
95
|
return $list;
|
|
97
96
|
}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
/** @param mixed[] $items */
|
|
100
|
+
public static function removeNulls(array &$items): void
|
|
101
|
+
{
|
|
102
|
+
$items = array_values(array_filter($items, fn($item) => $item !== null));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Attempts to map the compiled template to the source.
|
|
108
|
+
* @return array{name: ?string, line: ?int, column: ?int}|null
|
|
109
|
+
*/
|
|
110
|
+
public static function mapCompiledToSource(string $compiledFile, ?int $compiledLine = null): ?array
|
|
111
|
+
{
|
|
112
|
+
if (!Runtime\Cache::isCacheFile($compiledFile)) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
$content = file_get_contents($compiledFile);
|
|
117
|
+
if ($content === false) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
$name = preg_match('#^/\*\* source: (\S.+) \*/#m', $content, $m) ? $m[1] : null;
|
|
121
|
+
$compiledLine && preg_match('~/\* pos (\d+)(?::(\d+))? \*/~', explode("\n", $content)[$compiledLine - 1], $pos);
|
|
122
|
+
$line = isset($pos[1]) ? (int) $pos[1] : null;
|
|
123
|
+
$column = isset($pos[2]) ? (int) $pos[2] : null;
|
|
124
|
+
return $name || $line ? compact('name', 'line', 'column') : null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Tries to guess the position in the template from the backtrace
|
|
130
|
+
*/
|
|
131
|
+
public static function guessTemplatePosition(): ?string
|
|
132
|
+
{
|
|
133
|
+
$trace = debug_backtrace();
|
|
134
|
+
foreach ($trace as $item) {
|
|
135
|
+
if (isset($item['file']) && ($source = self::mapCompiledToSource($item['file'], $item['line'] ?? null))) {
|
|
136
|
+
$res = [];
|
|
137
|
+
if ($source['name'] && is_file($source['name'])) {
|
|
138
|
+
$res[] = "in '" . str_replace(dirname($source['name'], 2), '...', $source['name']) . "'";
|
|
139
|
+
}
|
|
140
|
+
if ($source['line']) {
|
|
141
|
+
$res[] = 'on line ' . $source['line'] . ($source['column'] ? ' at column ' . $source['column'] : '');
|
|
142
|
+
}
|
|
143
|
+
return implode(' ', $res);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
98
148
|
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
<?php
|
|
1
|
+
<?php declare(strict_types=1);
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is part of the Latte (https://latte.nette.org)
|
|
5
5
|
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
declare(strict_types=1);
|
|
9
|
-
|
|
10
8
|
namespace Latte;
|
|
11
9
|
|
|
12
10
|
|
|
@@ -20,12 +18,6 @@ interface Loader
|
|
|
20
18
|
*/
|
|
21
19
|
function getContent(string $name): string;
|
|
22
20
|
|
|
23
|
-
/**
|
|
24
|
-
* Checks whether template is expired.
|
|
25
|
-
* @deprecated
|
|
26
|
-
*/
|
|
27
|
-
function isExpired(string $name, int $time): bool;
|
|
28
|
-
|
|
29
21
|
/**
|
|
30
22
|
* Returns referred template name.
|
|
31
23
|
*/
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
<?php
|
|
1
|
+
<?php declare(strict_types=1);
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is part of the Latte (https://latte.nette.org)
|
|
5
5
|
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
declare(strict_types=1);
|
|
9
|
-
|
|
10
8
|
namespace Latte\Loaders;
|
|
11
9
|
|
|
12
10
|
use Latte;
|
|
11
|
+
use function array_pop, end, explode, file_get_contents, implode, is_file, preg_match, str_starts_with, strtr;
|
|
12
|
+
use const DIRECTORY_SEPARATOR;
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
16
|
+
* Loads templates from filesystem.
|
|
17
17
|
*/
|
|
18
18
|
class FileLoader implements Latte\Loader
|
|
19
19
|
{
|
|
@@ -36,21 +36,15 @@ class FileLoader implements Latte\Loader
|
|
|
36
36
|
throw new Latte\RuntimeException("Template '$file' is not within the allowed path '{$this->baseDir}'.");
|
|
37
37
|
|
|
38
38
|
} elseif (!is_file($file)) {
|
|
39
|
-
throw new Latte\
|
|
40
|
-
|
|
41
|
-
} elseif ($this->isExpired($fileName, time())) {
|
|
42
|
-
if (@touch($file) === false) {
|
|
43
|
-
trigger_error("File's modification time is in the future. Cannot update it: " . error_get_last()['message'], E_USER_WARNING);
|
|
44
|
-
}
|
|
39
|
+
throw new Latte\TemplateNotFoundException("Missing template file '$file'.");
|
|
45
40
|
}
|
|
46
41
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
$content = file_get_contents($file);
|
|
43
|
+
if ($content === false) {
|
|
44
|
+
throw new Latte\RuntimeException("Unable to read file '$file'.");
|
|
45
|
+
}
|
|
50
46
|
|
|
51
|
-
|
|
52
|
-
{
|
|
53
|
-
return false;
|
|
47
|
+
return $content;
|
|
54
48
|
}
|
|
55
49
|
|
|
56
50
|
|
|
@@ -59,7 +53,7 @@ class FileLoader implements Latte\Loader
|
|
|
59
53
|
*/
|
|
60
54
|
public function getReferredName(string $file, string $referringFile): string
|
|
61
55
|
{
|
|
62
|
-
if ($this->baseDir || !preg_match('
|
|
56
|
+
if ($this->baseDir || !preg_match('#/|\\\|[a-z]:|phar:#iA', $file)) {
|
|
63
57
|
$file = $this->normalizePath($referringFile . '/../' . $file);
|
|
64
58
|
}
|
|
65
59
|
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
<?php
|
|
1
|
+
<?php declare(strict_types=1);
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is part of the Latte (https://latte.nette.org)
|
|
5
5
|
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
declare(strict_types=1);
|
|
9
|
-
|
|
10
8
|
namespace Latte\Loaders;
|
|
11
9
|
|
|
12
10
|
use Latte;
|
|
@@ -17,16 +15,10 @@ use Latte;
|
|
|
17
15
|
*/
|
|
18
16
|
class StringLoader implements Latte\Loader
|
|
19
17
|
{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @param string[] $templates
|
|
26
|
-
*/
|
|
27
|
-
public function __construct(?array $templates = null)
|
|
28
|
-
{
|
|
29
|
-
$this->templates = $templates;
|
|
18
|
+
public function __construct(
|
|
19
|
+
/** @var array<string, string>|null */
|
|
20
|
+
private ?array $templates = null,
|
|
21
|
+
) {
|
|
30
22
|
}
|
|
31
23
|
|
|
32
24
|
|
|
@@ -40,24 +32,18 @@ class StringLoader implements Latte\Loader
|
|
|
40
32
|
} elseif (isset($this->templates[$name])) {
|
|
41
33
|
return $this->templates[$name];
|
|
42
34
|
} else {
|
|
43
|
-
throw new Latte\
|
|
35
|
+
throw new Latte\TemplateNotFoundException("Missing template '$name'.");
|
|
44
36
|
}
|
|
45
37
|
}
|
|
46
38
|
|
|
47
39
|
|
|
48
|
-
public function isExpired(string $name, int $time): bool
|
|
49
|
-
{
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
40
|
/**
|
|
55
41
|
* Returns referred template name.
|
|
56
42
|
*/
|
|
57
43
|
public function getReferredName(string $name, string $referringName): string
|
|
58
44
|
{
|
|
59
45
|
if ($this->templates === null) {
|
|
60
|
-
throw new \
|
|
46
|
+
throw new Latte\TemplateNotFoundException("Missing template '$name'.");
|
|
61
47
|
}
|
|
62
48
|
|
|
63
49
|
return $name;
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
<?php
|
|
1
|
+
<?php declare(strict_types=1);
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is part of the Latte (https://latte.nette.org)
|
|
5
5
|
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
declare(strict_types=1);
|
|
9
|
-
|
|
10
8
|
namespace Latte;
|
|
11
9
|
|
|
12
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Security policy for sandbox mode.
|
|
13
|
+
*/
|
|
13
14
|
interface Policy
|
|
14
15
|
{
|
|
15
16
|
function isTagAllowed(string $tag): bool;
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
<?php
|
|
1
|
+
<?php declare(strict_types=1);
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is part of the Latte (https://latte.nette.org)
|
|
5
5
|
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
declare(strict_types=1);
|
|
9
|
-
|
|
10
8
|
namespace Latte\Runtime;
|
|
11
9
|
|
|
12
10
|
|
|
@@ -15,6 +13,6 @@ final class Block
|
|
|
15
13
|
{
|
|
16
14
|
public ?string $contentType = null;
|
|
17
15
|
|
|
18
|
-
/** @var
|
|
16
|
+
/** @var \Closure[] */
|
|
19
17
|
public array $functions = [];
|
|
20
18
|
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
<?php declare(strict_types=1);
|
|
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
|
+
namespace Latte\Runtime;
|
|
9
|
+
|
|
10
|
+
use Latte\Engine;
|
|
11
|
+
use Latte\RuntimeException;
|
|
12
|
+
use function array_map, defined, dirname, file_put_contents, filemtime, flock, fopen, fseek, ftell, ftruncate, function_exists, fwrite, is_dir, is_file, mkdir, preg_match, preg_replace, rename, serialize, stream_get_contents, strlen, substr, unlink;
|
|
13
|
+
use const LOCK_EX, LOCK_SH, LOCK_UN;
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Caching of compiled templates.
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
final class Cache
|
|
21
|
+
{
|
|
22
|
+
public ?string $directory = null;
|
|
23
|
+
public bool $autoRefresh = true;
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Loads existing cache or compiles template if needed.
|
|
28
|
+
* Uses file locking to ensure atomic operations and prevent race conditions.
|
|
29
|
+
*/
|
|
30
|
+
public function loadOrCreate(Engine $engine, string $name): void
|
|
31
|
+
{
|
|
32
|
+
// Solving atomicity to work everywhere is really pain in the ass.
|
|
33
|
+
// 1) We want to do as little as possible IO calls on production and also directory and file can be not writable
|
|
34
|
+
// so on Linux we include the file directly without shared lock, therefore, the file must be created atomically by renaming.
|
|
35
|
+
// 2) On Windows file cannot be renamed-to while is open (ie by include), so we have to acquire a lock.
|
|
36
|
+
$file = $this->generateFilePath($engine, $name);
|
|
37
|
+
$signature = $this->autoRefresh
|
|
38
|
+
? hash('xxh128', serialize($this->generateRefreshSignature($engine, $name)))
|
|
39
|
+
: null;
|
|
40
|
+
$lock = defined('PHP_WINDOWS_VERSION_BUILD') || $signature
|
|
41
|
+
? $this->acquireLock("$file.lock", LOCK_SH)
|
|
42
|
+
: null;
|
|
43
|
+
|
|
44
|
+
if (
|
|
45
|
+
!($signature && $lock && $signature !== stream_get_contents($lock))
|
|
46
|
+
&& (@include $file) !== false // @ - file may not exist
|
|
47
|
+
) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if ($lock) {
|
|
52
|
+
flock($lock, LOCK_UN); // release shared lock so we can get exclusive
|
|
53
|
+
fseek($lock, 0);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
$lock = $this->acquireLock("$file.lock", LOCK_EX);
|
|
57
|
+
|
|
58
|
+
// while waiting for exclusive lock, someone might have already created the cache
|
|
59
|
+
if (!is_file($file) || ($signature && $signature !== stream_get_contents($lock))) {
|
|
60
|
+
$compiled = $engine->compile($name);
|
|
61
|
+
if (
|
|
62
|
+
file_put_contents("$file.tmp", $compiled) !== strlen($compiled)
|
|
63
|
+
|| !rename("$file.tmp", $file)
|
|
64
|
+
) {
|
|
65
|
+
@unlink("$file.tmp"); // @ - file may not exist
|
|
66
|
+
throw new RuntimeException("Unable to create '$file'.");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
fseek($lock, 0);
|
|
70
|
+
fwrite($lock, $signature ?? hash('xxh128', serialize($this->generateRefreshSignature($engine, $name))));
|
|
71
|
+
ftruncate($lock, (int) ftell($lock));
|
|
72
|
+
|
|
73
|
+
if (function_exists('opcache_invalidate')) {
|
|
74
|
+
@opcache_invalidate($file, force: true); // @ can be restricted
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if ((include $file) === false) {
|
|
79
|
+
throw new RuntimeException("Unable to load '$file'.");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
flock($lock, LOCK_UN);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
/** @return resource */
|
|
87
|
+
private function acquireLock(string $file, int $mode)
|
|
88
|
+
{
|
|
89
|
+
$dir = dirname($file);
|
|
90
|
+
if (!is_dir($dir) && !@mkdir($dir) && !is_dir($dir)) { // @ - dir may already exist
|
|
91
|
+
throw new RuntimeException("Unable to create directory '$dir'. " . (error_get_last()['message'] ?? ''));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
$handle = @fopen($file, 'c+'); // @ is escalated to exception
|
|
95
|
+
if (!$handle) {
|
|
96
|
+
throw new RuntimeException("Unable to create file '$file'. " . (error_get_last()['message'] ?? ''));
|
|
97
|
+
} elseif (!@flock($handle, $mode)) { // @ is escalated to exception
|
|
98
|
+
throw new RuntimeException('Unable to acquire ' . ($mode & LOCK_EX ? 'exclusive' : 'shared') . " lock on file '$file'. " . (error_get_last()['message'] ?? ''));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return $handle;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Returns the file path where compiled template will be cached.
|
|
107
|
+
* Different configurations produce different file paths.
|
|
108
|
+
*/
|
|
109
|
+
public function generateFilePath(Engine $engine, string $name): string
|
|
110
|
+
{
|
|
111
|
+
$base = preg_match('#([/\\\][\w@.-]{3,35}){1,3}$#D', '/' . $name, $m)
|
|
112
|
+
? preg_replace('#[^\w@.-]+#', '-', substr($m[0], 1))
|
|
113
|
+
: '';
|
|
114
|
+
if (!str_ends_with($base, 'latte')) {
|
|
115
|
+
$base .= '-latte';
|
|
116
|
+
}
|
|
117
|
+
return $this->directory . '/' . $base . '--' . $engine->generateTemplateHash($name) . '.php';
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
public static function isCacheFile(string $file): bool
|
|
122
|
+
{
|
|
123
|
+
return (bool) preg_match('/latte--\w{10}\.php$/', $file);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Returns values used to detect if cached template needs recompilation when autoRefresh is enabled.
|
|
129
|
+
* Triggers recompilation when template code, Latte engine, or any extension changes.
|
|
130
|
+
* @return list<mixed>
|
|
131
|
+
*/
|
|
132
|
+
protected function generateRefreshSignature(Engine $engine, string $name): array
|
|
133
|
+
{
|
|
134
|
+
return [
|
|
135
|
+
Engine::Version,
|
|
136
|
+
$engine->getLoader()->getContent($name),
|
|
137
|
+
array_map(
|
|
138
|
+
fn($extension) => @filemtime((string) (new \ReflectionObject($extension))->getFileName()), // @ file may not exist
|
|
139
|
+
$engine->getExtensions(),
|
|
140
|
+
),
|
|
141
|
+
];
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
<?php
|
|
1
|
+
<?php declare(strict_types=1);
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is part of the Latte (https://latte.nette.org)
|
|
5
5
|
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
declare(strict_types=1);
|
|
9
|
-
|
|
10
8
|
namespace Latte\Runtime;
|
|
11
9
|
|
|
12
10
|
use Latte;
|
|
13
11
|
use Latte\ContentType;
|
|
14
12
|
use Latte\Helpers;
|
|
13
|
+
use function array_column, array_combine, array_keys, array_unshift, strtoupper;
|
|
15
14
|
|
|
16
15
|
|
|
17
16
|
/**
|
|
@@ -21,7 +20,7 @@ use Latte\Helpers;
|
|
|
21
20
|
#[\AllowDynamicProperties]
|
|
22
21
|
class FilterExecutor
|
|
23
22
|
{
|
|
24
|
-
/** @var callable
|
|
23
|
+
/** @var array<callable> */
|
|
25
24
|
private array $_dynamic = [];
|
|
26
25
|
|
|
27
26
|
/** @var array<string, array{callable, ?bool}> */
|
|
@@ -46,7 +45,7 @@ class FilterExecutor
|
|
|
46
45
|
|
|
47
46
|
/**
|
|
48
47
|
* Returns all run-time filters.
|
|
49
|
-
* @return callable
|
|
48
|
+
* @return array<string, callable>
|
|
50
49
|
*/
|
|
51
50
|
public function getAll(): array
|
|
52
51
|
{
|
|
@@ -117,7 +116,7 @@ class FilterExecutor
|
|
|
117
116
|
$hint = ($t = Helpers::getSuggestion(array_keys($this->_static), $name))
|
|
118
117
|
? ", did you mean '$t'?"
|
|
119
118
|
: '.';
|
|
120
|
-
throw new \LogicException("Filter '$name' is not defined$hint");
|
|
119
|
+
throw new \LogicException("Filter '$name' is not defined or not allowed here$hint");
|
|
121
120
|
}
|
|
122
121
|
|
|
123
122
|
|