Skip to content
Snippets Groups Projects
Commit 3bddf096 authored by Claus Due's avatar Claus Due Committed by Claus Due
Browse files

[TASK] Check methods in RenderingContext before calling

Checks for method presence before attempting to call
them, and exposes getControllerName/getControllerAction
for public usage.

Release: master, 9.5, 8.7
Resolves: #90284
Change-Id: I29b850ccb2f535c1f708af32a61e50c04386d9b7
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/63111


Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: default avatarManuel Selbach <manuel_selbach@yahoo.de>
Tested-by: default avatarKevin Appelt <kevin.appelt@icloud.com>
Tested-by: default avatarClaus Due <claus@phpmind.net>
Reviewed-by: default avatarManuel Selbach <manuel_selbach@yahoo.de>
Reviewed-by: default avatarKevin Appelt <kevin.appelt@icloud.com>
Reviewed-by: default avatarClaus Due <claus@phpmind.net>
parent 653dded5
Branches
Tags
No related merge requests found
......@@ -41,6 +41,16 @@ class RenderingContext extends \TYPO3Fluid\Fluid\Core\Rendering\RenderingContext
*/
protected $controllerContext;
/**
* @var string
*/
protected $controllerName = 'Default';
/**
* @var string
*/
protected $controllerAction = 'Default';
/**
* @param \TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperVariableContainer $viewHelperVariableContainer
*/
......@@ -62,26 +72,46 @@ class RenderingContext extends \TYPO3Fluid\Fluid\Core\Rendering\RenderingContext
} else {
// Reproduced partial initialisation from parent::__construct; minus the custom
// implementations we attach below.
$this->setTemplateParser(new TemplateParser());
$this->setTemplateCompiler(new TemplateCompiler());
$this->setViewHelperInvoker(new ViewHelperInvoker());
$this->setTemplateParser(new TemplateParser($this));
if (method_exists($this, 'setTemplateCompiler')) {
$this->setTemplateCompiler(new TemplateCompiler());
}
if (method_exists($this, 'setViewHelperInvoker')) {
$this->setViewHelperInvoker(new ViewHelperInvoker());
}
$this->setViewHelperVariableContainer(new ViewHelperVariableContainer());
$this->setVariableProvider(new StandardVariableProvider());
}
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$this->setTemplateProcessors(array_map([$objectManager, 'get'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['preProcessors']));
if (method_exists($this, 'setTemplateProcessors')) {
$this->setTemplateProcessors(array_map([$objectManager, 'get'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['preProcessors']));
}
$this->setExpressionNodeTypes($GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['expressionNodeTypes']);
$this->setTemplatePaths($objectManager->get(TemplatePaths::class));
$this->setViewHelperResolver($objectManager->get(ViewHelperResolver::class));
/** @var FluidTemplateCache $cache */
$cache = $objectManager->get(CacheManager::class)->getCache('fluid_template');
if (is_a($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['fluid_template']['frontend'], FluidTemplateCache::class, true)) {
$this->setCache($cache);
if (method_exists($this, 'setCache')) {
/** @var FluidTemplateCache $cache */
$cache = $objectManager->get(CacheManager::class)->getCache('fluid_template');
if (is_a($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['fluid_template']['frontend'], FluidTemplateCache::class, true)) {
$this->setCache($cache);
}
}
}
/**
* Alternative to buildParserConfiguration, called only in Fluid 3.0
*
* @return Configuration
*/
public function getParserConfiguration(): Configuration
{
$parserConfiguration = parent::getParserConfiguration();
$this->addInterceptorsToParserConfiguration($GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['interceptors'], $parserConfiguration);
return $parserConfiguration;
}
/**
* Build parser configuration
*
......@@ -91,17 +121,19 @@ class RenderingContext extends \TYPO3Fluid\Fluid\Core\Rendering\RenderingContext
public function buildParserConfiguration()
{
$parserConfiguration = parent::buildParserConfiguration();
if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['interceptors'])) {
foreach ($GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['interceptors'] as $className) {
$interceptor = GeneralUtility::makeInstance($className);
if (!$interceptor instanceof InterceptorInterface) {
throw new \InvalidArgumentException('Interceptor "' . $className . '" needs to implement ' . InterceptorInterface::class . '.', 1462869795);
}
$parserConfiguration->addInterceptor($interceptor);
$this->addInterceptorsToParserConfiguration($GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['interceptors'], $parserConfiguration);
return $parserConfiguration;
}
protected function addInterceptorsToParserConfiguration(iterable $interceptors, Configuration $parserConfiguration): void
{
foreach ($interceptors as $className) {
$interceptor = GeneralUtility::makeInstance($className);
if (!$interceptor instanceof InterceptorInterface) {
throw new \InvalidArgumentException('Interceptor "' . $className . '" needs to implement ' . InterceptorInterface::class . '.', 1462869795);
}
$parserConfiguration->addInterceptor($interceptor);
}
return $parserConfiguration;
}
/**
......@@ -123,8 +155,10 @@ class RenderingContext extends \TYPO3Fluid\Fluid\Core\Rendering\RenderingContext
if ($dotPosition !== false) {
$action = substr($action, 0, $dotPosition);
}
parent::setControllerAction($action);
$this->controllerContext->getRequest()->setControllerActionName(lcfirst($action));
$this->controllerAction = $action;
if ($this->controllerContext) {
$this->controllerContext->getRequest()->setControllerActionName(lcfirst($action));
}
}
/**
......@@ -133,8 +167,26 @@ class RenderingContext extends \TYPO3Fluid\Fluid\Core\Rendering\RenderingContext
*/
public function setControllerName($controllerName)
{
parent::setControllerName($controllerName);
$this->controllerContext->getRequest()->setControllerName($controllerName);
$this->controllerName = $controllerName;
if ($this->controllerContext) {
$this->controllerContext->getRequest()->setControllerName($controllerName);
}
}
/**
* @return string
*/
public function getControllerName()
{
return $this->controllerContext ? $this->controllerContext->getRequest()->getControllerName() : $this->controllerName;
}
/**
* @return string
*/
public function getControllerAction()
{
return $this->controllerContext ? $this->controllerContext->getRequest()->getControllerActionName() : $this->controllerAction;
}
/**
......
......@@ -109,14 +109,14 @@ class RenderingContextTest extends UnitTestCase
->addMethods(['dummy'])
->disableOriginalConstructor()
->getMock();
$request = $this->getMockBuilder(Request::class)->setMethods(['setControllerActionName'])->getMock();
$request->expects(self::at(0))->method('setControllerActionName')->with('index');
$request->expects(self::at(1))->method('setControllerActionName')->with(lcfirst($expected));
$request = $this->getMockBuilder(Request::class)->getMock();
$request->expects(self::exactly(2))->method('setControllerActionName')->with(lcfirst($expected));
$request->expects(self::exactly(2))->method('getControllerActionName')->willReturn(lcfirst($expected));
$controllerContext = $this->getMockBuilder(ControllerContext::class)->setMethods(['getRequest'])->getMock();
$controllerContext->expects(self::atLeastOnce())->method('getRequest')->willReturn($request);
$subject->setControllerContext($controllerContext);
$subject->setControllerAction($input);
self::assertEquals($expected, $subject->getControllerAction());
self::assertSame(lcfirst($expected), $subject->getControllerAction());
}
/**
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment