Completed
Pull Request — master (#470)
by Claus
01:33
created

TemplateParser::getOrParseAndStoreTemplate()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 2
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
namespace TYPO3Fluid\Fluid\Core\Parser;
4
5
/*
6
 * This file belongs to the package "TYPO3 Fluid".
7
 * See LICENSE.txt that was shipped with this package.
8
 */
9
10
use TYPO3Fluid\Fluid\Component\ComponentInterface;
11
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
12
13
/**
14
 * Template parser building up an object syntax tree
15
 */
16
class TemplateParser
17
{
18
    /**
19
     * @var Configuration
20
     */
21
    protected $configuration;
22
23
    /**
24
     * @var RenderingContextInterface
25
     */
26
    protected $renderingContext;
27
28
    /**
29
     * @var array 
30
     */
31
    protected $stack = [];
32
33
    public function __construct(RenderingContextInterface $renderingContext)
34
    {
35
        $this->renderingContext = $renderingContext;
36
        $this->configuration = $renderingContext->getParserConfiguration();
37
    }
38
39
    public function parseFile(string $templatePathAndFilename, ?Configuration $configuration = null): ComponentInterface
0 ignored issues
show
Unused Code introduced by
The parameter $configuration is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
40
    {
41
        $hash = sha1_file($templatePathAndFilename);
42
        if (isset($this->stack[$hash])) {
43
            return $this->stack[$hash];
44
        }
45
        return $this->getOrParseAndStoreTemplate(
46
            $this->createIdentifierForFile($templatePathAndFilename, ''),
47
            function () use ($templatePathAndFilename): string {
48
                return file_get_contents($templatePathAndFilename);
49
            }
50
        );
51
    }
52
53
    /**
54
     * Parses a given template string and returns a parsed template object.
55
     *
56
     * The resulting ParsedTemplate can then be rendered by calling evaluate() on it.
57
     *
58
     * Normally, you should use a subclass of AbstractTemplateView instead of calling the
59
     * TemplateParser directly.
60
     *
61
     * @param string $templateString The template to parse as a string
62
     * @param Configuration|null Template parsing configuration to use
63
     * @return ComponentInterface Parsed template
64
     * @throws Exception
65
     */
66
    public function parse(string $templateString, ?Configuration $configuration = null): ComponentInterface
67
    {
68
        $hash = sha1($templateString);
69
        $source = new Source($templateString);
70
        $contexts = new Contexts();
71
        $sequencer = new Sequencer(
72
            $this->renderingContext,
73
            $contexts,
74
            $source,
75
            $configuration ?? $this->configuration
76
        );
77
        // Recursion support: triggering parsing of the same source file from within the file returns a reference
78
        // to the still unfinished EntryNode created by the Sequencer. The returned instance still does not have all
79
        // child nodes until the Sequencer has finished. The second time the template is parsed the temporary EntryNode
80
        // is returned to prevent infinite recursion.
81
        // The first instance now contains a circular reference to itself, as a branch nested in children somewhere.
82
        // Any subsequent usages of the same source creates additional references to the original/root/parent.
83
        $this->stack[$hash] = $sequencer->getComponent();
84
        $component = $sequencer->sequence();
85
        return $component;
86
    }
87
88
    /**
89
     * @param string $templateIdentifier
90
     * @param \Closure $templateSourceClosure Closure which returns the template source if needed
91
     * @return ComponentInterface
92
     */
93
    public function getOrParseAndStoreTemplate(string $templateIdentifier, \Closure $templateSourceClosure): ComponentInterface
94
    {
95
        if (!$this->configuration->isFeatureEnabled(Configuration::FEATURE_RUNTIME_CACHE)) {
96
            return $this->parseTemplateSource($templateIdentifier, $templateSourceClosure);
97
        }
98
        static $cache = [];
99
        if (!isset($cache[$templateIdentifier])) {
100
            $cache[$templateIdentifier] = $this->parseTemplateSource($templateIdentifier, $templateSourceClosure);
101
        }
102
        return $cache[$templateIdentifier];
103
    }
104
105
    /**
106
     * @param string $templateIdentifier
107
     * @param \Closure $templateSourceClosure
108
     * @return ComponentInterface
109
     */
110
    protected function parseTemplateSource(string $templateIdentifier, \Closure $templateSourceClosure): ComponentInterface
0 ignored issues
show
Unused Code introduced by
The parameter $templateIdentifier is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
111
    {
112
        $parsedTemplate = $this->parse(
113
            $templateSourceClosure($this->renderingContext),
114
            $this->renderingContext->getParserConfiguration()
115
        );
116
        //$parsedTemplate->setIdentifier($templateIdentifier);
117
        return $parsedTemplate;
118
    }
119
120
    /**
121
     * Returns a unique identifier for the given file in the format
122
     * <PackageKey>_<SubPackageKey>_<ControllerName>_<prefix>_<SHA1>
123
     * The SH1 hash is a checksum that is based on the file path and last modification date
124
     *
125
     * @param string $pathAndFilename
126
     * @param string $prefix
127
     * @return string
128
     */
129
    protected function createIdentifierForFile(string $pathAndFilename, string $prefix): string
130
    {
131
        return sprintf('%s_%s', $prefix, sha1($pathAndFilename));
132
    }
133
}
134