Passed
Push — master ( 93dc02...068351 )
by
unknown
16:21
created

RenderingContext::setRequest()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 10
nc 4
nop 1
dl 0
loc 16
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the TYPO3 CMS project.
5
 *
6
 * It is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License, either version 2
8
 * of the License, or any later version.
9
 *
10
 * For the full copyright and license information, please read the
11
 * LICENSE.txt file that was distributed with this source code.
12
 *
13
 * The TYPO3 project - inspiring people to share!
14
 */
15
16
namespace TYPO3\CMS\Fluid\Core\Rendering;
17
18
use TYPO3\CMS\Core\Cache\CacheManager;
19
use TYPO3\CMS\Core\Utility\GeneralUtility;
20
use TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext;
21
use TYPO3\CMS\Extbase\Mvc\Request;
22
use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
23
use TYPO3\CMS\Extbase\Object\ObjectManager;
24
use TYPO3\CMS\Fluid\Core\Cache\FluidTemplateCache;
25
use TYPO3\CMS\Fluid\Core\ViewHelper\ViewHelperResolver;
26
use TYPO3\CMS\Fluid\View\TemplatePaths;
27
use TYPO3Fluid\Fluid\Core\Compiler\TemplateCompiler;
28
use TYPO3Fluid\Fluid\Core\Parser\Configuration;
29
use TYPO3Fluid\Fluid\Core\Parser\InterceptorInterface;
30
use TYPO3Fluid\Fluid\Core\Parser\TemplateParser;
31
use TYPO3Fluid\Fluid\Core\Parser\TemplateProcessorInterface;
32
use TYPO3Fluid\Fluid\Core\Variables\StandardVariableProvider;
33
use TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperInvoker;
34
use TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperVariableContainer;
35
use TYPO3Fluid\Fluid\View\ViewInterface;
36
37
/**
38
 * Class RenderingContext
39
 */
40
class RenderingContext extends \TYPO3Fluid\Fluid\Core\Rendering\RenderingContext
41
{
42
    /**
43
     * Controller context being passed to the ViewHelper
44
     *
45
     * @var \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext|null
46
     */
47
    protected $controllerContext;
48
49
    /**
50
     * @var Request
51
     */
52
    protected $request;
53
54
    /**
55
     * @var string
56
     */
57
    protected $controllerName = 'Default';
58
59
    /**
60
     * @var string
61
     */
62
    protected $controllerAction = 'Default';
63
64
    /**
65
     * @param \TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperVariableContainer $viewHelperVariableContainer
66
     */
67
    public function injectViewHelperVariableContainer(ViewHelperVariableContainer $viewHelperVariableContainer)
68
    {
69
        $this->viewHelperVariableContainer = $viewHelperVariableContainer;
70
    }
71
72
    /**
73
     * @param ViewInterface $view
74
     */
75
    public function __construct(ViewInterface $view = null)
76
    {
77
        if ($view !== null) {
78
            // Note: if $view is received here this indicates internal framework instancing
79
            // and it is safe to call the parent constructor. Custom, non-view-providing
80
            // usages will only perform the initialisation below (which is sufficient mind you!)
81
            parent::__construct($view);
82
        } else {
83
            // Reproduced partial initialisation from parent::__construct; minus the custom
84
            // implementations we attach below.
85
            $this->setTemplateParser(new TemplateParser($this));
0 ignored issues
show
Unused Code introduced by
The call to TYPO3Fluid\Fluid\Core\Pa...teParser::__construct() has too many arguments starting with $this. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

85
            $this->setTemplateParser(/** @scrutinizer ignore-call */ new TemplateParser($this));

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
86
            if (method_exists($this, 'setTemplateCompiler')) {
87
                $this->setTemplateCompiler(new TemplateCompiler());
88
            }
89
            if (method_exists($this, 'setViewHelperInvoker')) {
90
                $this->setViewHelperInvoker(new ViewHelperInvoker());
91
            }
92
            $this->setViewHelperVariableContainer(new ViewHelperVariableContainer());
93
            $this->setVariableProvider(new StandardVariableProvider());
94
        }
95
96
        $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
97
        if (method_exists($this, 'setTemplateProcessors')) {
98
            /** @var TemplateProcessorInterface[] $processors */
99
            $processors = array_map([$objectManager, 'get'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['preProcessors']);
100
            $this->setTemplateProcessors($processors);
101
        }
102
        $this->setExpressionNodeTypes($GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['expressionNodeTypes']);
103
        $this->setTemplatePaths($objectManager->get(TemplatePaths::class));
104
        $this->setViewHelperResolver($objectManager->get(ViewHelperResolver::class));
105
106
        if (method_exists($this, 'setCache')) {
107
            /** @var FluidTemplateCache $cache */
108
            $cache = $objectManager->get(CacheManager::class)->getCache('fluid_template');
109
            if (is_a($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['fluid_template']['frontend'], FluidTemplateCache::class, true)) {
110
                $this->setCache($cache);
111
            }
112
        }
113
    }
114
115
    /**
116
     * Alternative to buildParserConfiguration, called only in Fluid 3.0
117
     *
118
     * @return Configuration
119
     */
120
    public function getParserConfiguration(): Configuration
121
    {
122
        $parserConfiguration = parent::getParserConfiguration();
0 ignored issues
show
introduced by
The method getParserConfiguration() does not exist on TYPO3Fluid\Fluid\Core\Rendering\RenderingContext. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

122
        /** @scrutinizer ignore-call */ 
123
        $parserConfiguration = parent::getParserConfiguration();
Loading history...
123
        $this->addInterceptorsToParserConfiguration($GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['interceptors'], $parserConfiguration);
124
        return $parserConfiguration;
125
    }
126
127
    /**
128
     * Build parser configuration
129
     *
130
     * @return Configuration
131
     * @throws \InvalidArgumentException if a class not implementing InterceptorInterface was registered
132
     */
133
    public function buildParserConfiguration()
134
    {
135
        $parserConfiguration = parent::buildParserConfiguration();
136
        $this->addInterceptorsToParserConfiguration($GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['interceptors'], $parserConfiguration);
137
        return $parserConfiguration;
138
    }
139
140
    protected function addInterceptorsToParserConfiguration(iterable $interceptors, Configuration $parserConfiguration): void
141
    {
142
        foreach ($interceptors as $className) {
143
            $interceptor = GeneralUtility::makeInstance($className);
144
            if (!$interceptor instanceof InterceptorInterface) {
145
                throw new \InvalidArgumentException('Interceptor "' . $className . '" needs to implement ' . InterceptorInterface::class . '.', 1462869795);
146
            }
147
            $parserConfiguration->addInterceptor($interceptor);
148
        }
149
    }
150
151
    /**
152
     * Get the controller context which will be passed to the ViewHelper
153
     *
154
     * @return \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext The controller context to set
155
     */
156
    public function getControllerContext()
157
    {
158
        if ($this->controllerContext) {
159
            return $this->controllerContext;
160
        }
161
        $controllerContext = GeneralUtility::makeInstance(ObjectManager::class)->get(ControllerContext::class);
162
        if ($this->request) {
163
            $controllerContext->setRequest($this->request);
164
        }
165
        return $controllerContext;
166
    }
167
168
    /**
169
     * @param string $action
170
     */
171
    public function setControllerAction($action)
172
    {
173
        $dotPosition = strpos($action, '.');
174
        if ($dotPosition !== false) {
175
            $action = substr($action, 0, $dotPosition);
176
        }
177
        $this->controllerAction = $action;
178
        if ($this->request) {
179
            $this->request->setControllerActionName(lcfirst($action));
180
        }
181
    }
182
183
    /**
184
     * @param string $controllerName
185
     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidControllerNameException
186
     */
187
    public function setControllerName($controllerName)
188
    {
189
        $this->controllerName = $controllerName;
190
        if ($this->request instanceof Request) {
0 ignored issues
show
introduced by
$this->request is always a sub-type of TYPO3\CMS\Extbase\Mvc\Request.
Loading history...
191
            $this->request->setControllerName($controllerName);
192
        }
193
    }
194
195
    /**
196
     * @return string
197
     */
198
    public function getControllerName()
199
    {
200
        return $this->request instanceof Request ? $this->request->getControllerName() : $this->controllerName;
0 ignored issues
show
introduced by
$this->request is always a sub-type of TYPO3\CMS\Extbase\Mvc\Request.
Loading history...
201
    }
202
203
    /**
204
     * @return string
205
     */
206
    public function getControllerAction()
207
    {
208
        return $this->request instanceof Request ? $this->request->getControllerActionName() : $this->controllerAction;
0 ignored issues
show
introduced by
$this->request is always a sub-type of TYPO3\CMS\Extbase\Mvc\Request.
Loading history...
209
    }
210
211
    /**
212
     * Set the controller context which will be passed to the ViewHelper
213
     *
214
     * @param \TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $controllerContext The controller context to set
215
     */
216
    public function setControllerContext(ControllerContext $controllerContext)
217
    {
218
        $request = $controllerContext->getRequest();
219
        $this->controllerContext = $controllerContext;
220
        $this->setRequest($request);
221
    }
222
223
    /**
224
     * @param Request $request
225
     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidControllerNameException
226
     * @throws \TYPO3\CMS\Extbase\Object\Exception
227
     * @internal this might change to use a PSR-7 compliant request
228
     */
229
    public function setRequest(Request $request): void
230
    {
231
        $this->request = $request;
232
        $this->setControllerAction($request->getControllerActionName());
233
        // Check if Request is using a sub-package key; in which case we translate this
234
        // for our RenderingContext as an emulated plain old sub-namespace controller.
235
        $controllerName = $request->getControllerName();
236
        if ($request->getControllerSubpackageKey() && !strpos($controllerName, '\\')) {
237
            $this->setControllerName($request->getControllerSubpackageKey() . '\\' . $controllerName);
238
        } else {
239
            $this->setControllerName($controllerName);
240
        }
241
        // Also ensure that controller context is filled, if not set yet.
242
        if ($this->controllerContext === null) {
243
            $this->controllerContext = GeneralUtility::makeInstance(ObjectManager::class)->get(ControllerContext::class);
244
            $this->controllerContext->setRequest($request);
245
        }
246
    }
247
248
    /**
249
     * @return Request
250
     * @internal this might change to use a PSR-7 compliant request
251
     */
252
    public function getRequest(): Request
253
    {
254
        return $this->request;
255
    }
256
257
    /**
258
     * @return UriBuilder
259
     * @internal this is subject to change
260
     */
261
    public function getUriBuilder(): UriBuilder
262
    {
263
        $uriBuilder = GeneralUtility::makeInstance(ObjectManager::class)->get(UriBuilder::class);
264
        $uriBuilder->setRequest($this->request);
265
        return $uriBuilder;
266
    }
267
}
268