Skip to content
Snippets Groups Projects
Commit 1c7d7b75 authored by Stefan Neufeind's avatar Stefan Neufeind Committed by Markus Klein
Browse files

[!!!][TASK] Use fallbacks for AbstractWidgetController view-configuration

The fallback-paths functionality offered by the parent class
is now available for Fluid-widgets.

Change-Id: I73d3a792b261502b1eafd92b3b7b514e049e6ac2
Resolves: #59505
Releases: master
Reviewed-on: http://review.typo3.org/30672


Reviewed-by: default avatarStefan Neufeind <typo3.neufeind@speedpartner.de>
Reviewed-by: default avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: default avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: default avatarMarkus Klein <markus.klein@typo3.org>
Tested-by: default avatarMarkus Klein <markus.klein@typo3.org>
parent 795db07d
Branches
Tags
No related merge requests found
================================================================================
Breaking: #59505 - Use fallbacks for AbstractWidgetController view-configuration
================================================================================
Description
===========
The ``AbstractWidgetController`` is now capable of view fallbacks. This it is using the existing functionality of Extbase controllers.
Impact
======
Paths to templates, layouts and partials specified in the old syntax do not work anymore.
Old syntax:
.. code-block:: typoscript
plugin.tx_ext.settings.view.widget.widgetName.templateRootPath = some/path/Template.html
Affected Installations
======================
Any installation using third party extensions including wizards
Migration
=========
Specifying paths for layouts, templates and partials must now use the array syntax.
New syntax:
.. code-block:: typoscript
plugin.tx_ext.settings.view.widget.widgetName.templateRootPaths.10 = some/path/Template.html
...@@ -20,6 +20,14 @@ namespace TYPO3\CMS\Fluid\Core\Widget; ...@@ -20,6 +20,14 @@ namespace TYPO3\CMS\Fluid\Core\Widget;
* * * *
* The TYPO3 project - inspiring people to share! * * The TYPO3 project - inspiring people to share! *
* */ * */
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Extbase\Mvc\RequestInterface;
use TYPO3\CMS\Extbase\Mvc\ResponseInterface;
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
/** /**
* This is the base class for all widget controllers. * This is the base class for all widget controllers.
* Basically, it is an ActionController, and it additionally * Basically, it is an ActionController, and it additionally
...@@ -27,12 +35,12 @@ namespace TYPO3\CMS\Fluid\Core\Widget; ...@@ -27,12 +35,12 @@ namespace TYPO3\CMS\Fluid\Core\Widget;
* *
* @api * @api
*/ */
abstract class AbstractWidgetController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController implements \TYPO3\CMS\Core\SingletonInterface { abstract class AbstractWidgetController extends ActionController implements SingletonInterface {
/** /**
* @var array * @var array
*/ */
protected $supportedRequestTypes = array(\TYPO3\CMS\Fluid\Core\Widget\WidgetRequest::class); protected $supportedRequestTypes = array(WidgetRequest::class);
/** /**
* Configuration for this widget. * Configuration for this widget.
...@@ -45,32 +53,38 @@ abstract class AbstractWidgetController extends \TYPO3\CMS\Extbase\Mvc\Controlle ...@@ -45,32 +53,38 @@ abstract class AbstractWidgetController extends \TYPO3\CMS\Extbase\Mvc\Controlle
/** /**
* Handles a request. The result output is returned by altering the given response. * Handles a request. The result output is returned by altering the given response.
* *
* @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request The request object * @param RequestInterface $request The request object
* @param \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response The response, modified by this handler * @param ResponseInterface $response The response, modified by this handler
* @return void * @return void
* @api * @api
*/ */
public function processRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request, \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response) { public function processRequest(RequestInterface $request, ResponseInterface $response) {
$this->widgetConfiguration = $request->getWidgetContext()->getWidgetConfiguration(); if ($request instanceof WidgetRequest) {
$this->widgetConfiguration = $request->getWidgetContext()->getWidgetConfiguration();
}
parent::processRequest($request, $response); parent::processRequest($request, $response);
} }
/** /**
* Allows the widget template root path to be overriden via the framework configuration, * Allows the widget template root path to be overridden via the framework configuration,
* e.g. plugin.tx_extension.view.widget.<WidgetViewHelperClassName>.templateRootPath * e.g. plugin.tx_extension.view.widget.<WidgetViewHelperClassName>.templateRootPaths
* *
* @param \TYPO3\CMS\Extbase\Mvc\View\ViewInterface $view * @param ViewInterface $view
* @return void * @return void
*/ */
protected function setViewConfiguration(\TYPO3\CMS\Extbase\Mvc\View\ViewInterface $view) { protected function setViewConfiguration(ViewInterface $view) {
$extbaseFrameworkConfiguration = $this->configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK); if ($this->request instanceof WidgetRequest) {
$widgetViewHelperClassName = $this->request->getWidgetContext()->getWidgetViewHelperClassName(); $extbaseFrameworkConfiguration = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK, $this->extensionName);
if ( $widgetViewHelperClassName = $this->request->getWidgetContext()->getWidgetViewHelperClassName();
isset($extbaseFrameworkConfiguration['view']['widget'][$widgetViewHelperClassName]['templateRootPath']) if (isset($extbaseFrameworkConfiguration['view']['widget'][$widgetViewHelperClassName])) {
&& $extbaseFrameworkConfiguration['view']['widget'][$widgetViewHelperClassName]['templateRootPath'] !== '' $configurationOverridden = $extbaseFrameworkConfiguration;
&& method_exists($view, 'setTemplateRootPath') $configurationOverridden['view'] = array_replace_recursive($configurationOverridden['view'], $configurationOverridden['view']['widget'][$widgetViewHelperClassName]);
) { $this->configurationManager->setConfiguration($configurationOverridden);
$view->setTemplateRootPath(\TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($extbaseFrameworkConfiguration['view']['widget'][$widgetViewHelperClassName]['templateRootPath'])); parent::setViewConfiguration($view);
$this->configurationManager->setConfiguration($extbaseFrameworkConfiguration);
} else {
parent::setViewConfiguration($view);
}
} }
} }
......
...@@ -21,25 +21,34 @@ namespace TYPO3\CMS\Fluid\Tests\Unit\Core\Widget; ...@@ -21,25 +21,34 @@ namespace TYPO3\CMS\Fluid\Tests\Unit\Core\Widget;
* The TYPO3 project - inspiring people to share! * * The TYPO3 project - inspiring people to share! *
* */ * */
use TYPO3\CMS\Core\Tests\UnitTestCase;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
use TYPO3\CMS\Extbase\Mvc\Controller\Arguments; use TYPO3\CMS\Extbase\Mvc\Controller\Arguments;
use TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext;
use TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService;
use TYPO3\CMS\Extbase\Mvc\ResponseInterface; use TYPO3\CMS\Extbase\Mvc\ResponseInterface;
use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
use TYPO3\CMS\Fluid\Core\Widget\AbstractWidgetController; use TYPO3\CMS\Fluid\Core\Widget\AbstractWidgetController;
use TYPO3\CMS\Fluid\Core\Widget\WidgetContext;
use TYPO3\CMS\Fluid\Core\Widget\WidgetRequest; use TYPO3\CMS\Fluid\Core\Widget\WidgetRequest;
use TYPO3\CMS\Fluid\View\TemplateView;
use TYPO3\CMS\Fluid\ViewHelpers\Widget\PaginateViewHelper;
/** /**
* Test case * Test case
*/ */
class AbstractWidgetControllerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase { class AbstractWidgetControllerTest extends UnitTestCase {
/** /**
* @test * @test
*/ */
public function canHandleWidgetRequest() { public function canHandleWidgetRequest() {
/** @var WidgetRequest|\PHPUnit_Framework_MockObject_MockObject $request */ /** @var WidgetRequest|\PHPUnit_Framework_MockObject_MockObject $request */
$request = $this->getMock(\TYPO3\CMS\Fluid\Core\Widget\WidgetRequest::class, array('dummy'), array(), '', FALSE); $request = $this->getMock(WidgetRequest::class, array('dummy'), array(), '', FALSE);
/** @var AbstractWidgetController|\PHPUnit_Framework_MockObject_MockObject $abstractWidgetController */ /** @var AbstractWidgetController|\PHPUnit_Framework_MockObject_MockObject $abstractWidgetController */
$abstractWidgetController = $this->getMock(\TYPO3\CMS\Fluid\Core\Widget\AbstractWidgetController::class, array('dummy'), array(), '', FALSE); $abstractWidgetController = $this->getMock(AbstractWidgetController::class, array('dummy'), array(), '', FALSE);
$this->assertTrue($abstractWidgetController->canProcessRequest($request)); $this->assertTrue($abstractWidgetController->canProcessRequest($request));
} }
...@@ -47,20 +56,20 @@ class AbstractWidgetControllerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase { ...@@ -47,20 +56,20 @@ class AbstractWidgetControllerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
* @test * @test
*/ */
public function processRequestSetsWidgetConfiguration() { public function processRequestSetsWidgetConfiguration() {
$widgetContext = $this->getMock(\TYPO3\CMS\Fluid\Core\Widget\WidgetContext::class); $widgetContext = $this->getMock(WidgetContext::class);
$widgetContext->expects($this->once())->method('getWidgetConfiguration')->will($this->returnValue('myConfiguration')); $widgetContext->expects($this->once())->method('getWidgetConfiguration')->will($this->returnValue('myConfiguration'));
/** @var WidgetRequest|\PHPUnit_Framework_MockObject_MockObject $request */ /** @var WidgetRequest|\PHPUnit_Framework_MockObject_MockObject $request */
$request = $this->getMock(\TYPO3\CMS\Fluid\Core\Widget\WidgetRequest::class, array(), array(), '', FALSE); $request = $this->getMock(WidgetRequest::class, array(), array(), '', FALSE);
$request->expects($this->once())->method('getWidgetContext')->will($this->returnValue($widgetContext)); $request->expects($this->once())->method('getWidgetContext')->will($this->returnValue($widgetContext));
/** @var ResponseInterface|\PHPUnit_Framework_MockObject_MockObject $response */ /** @var ResponseInterface|\PHPUnit_Framework_MockObject_MockObject $response */
$response = $this->getMock(\TYPO3\CMS\Extbase\Mvc\ResponseInterface::class); $response = $this->getMock(ResponseInterface::class);
/** @var AbstractWidgetController|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface $abstractWidgetController */ /** @var AbstractWidgetController|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface $abstractWidgetController */
$abstractWidgetController = $this->getAccessibleMock(\TYPO3\CMS\Fluid\Core\Widget\AbstractWidgetController::class, array('resolveActionMethodName', 'initializeActionMethodArguments', 'initializeActionMethodValidators', 'initializeAction', 'checkRequestHash', 'mapRequestArgumentsToControllerArguments', 'buildControllerContext', 'resolveView', 'callActionMethod'), array(), '', FALSE); $abstractWidgetController = $this->getAccessibleMock(AbstractWidgetController::class, array('resolveActionMethodName', 'initializeActionMethodArguments', 'initializeActionMethodValidators', 'initializeAction', 'checkRequestHash', 'mapRequestArgumentsToControllerArguments', 'buildControllerContext', 'resolveView', 'callActionMethod'), array(), '', FALSE);
$mockUriBuilder = $this->getMock(\TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder::class); $mockUriBuilder = $this->getMock(UriBuilder::class);
$objectManager = $this->getMock(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface::class); $objectManager = $this->getMock(ObjectManagerInterface::class);
$objectManager->expects($this->any())->method('get')->with(\TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder::class)->will($this->returnValue($mockUriBuilder)); $objectManager->expects($this->any())->method('get')->with(UriBuilder::class)->will($this->returnValue($mockUriBuilder));
$configurationService = $this->getMock(\TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService::class); $configurationService = $this->getMock(MvcPropertyMappingConfigurationService::class);
$abstractWidgetController->_set('mvcPropertyMappingConfigurationService', $configurationService); $abstractWidgetController->_set('mvcPropertyMappingConfigurationService', $configurationService);
$abstractWidgetController->_set('arguments', new Arguments()); $abstractWidgetController->_set('arguments', new Arguments());
...@@ -77,24 +86,39 @@ class AbstractWidgetControllerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase { ...@@ -77,24 +86,39 @@ class AbstractWidgetControllerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
$frameworkConfiguration = array( $frameworkConfiguration = array(
'view' => array( 'view' => array(
'widget' => array( 'widget' => array(
\TYPO3\CMS\Fluid\ViewHelpers\Widget\PaginateViewHelper::class => array( PaginateViewHelper::class => array(
'templateRootPath' => 'EXT:fluid/Resources/Private/DummyTestTemplates' 'templateRootPath' => 'EXT:fluid/Resources/Private',
'templateRootPaths' => ['EXT:fluid/Resources/Private']
) )
) )
) )
); );
$widgetContext = $this->getMock(\TYPO3\CMS\Fluid\Core\Widget\WidgetContext::class); $overriddenConfiguration['view'] = array_merge_recursive($frameworkConfiguration['view'], $frameworkConfiguration['view']['widget'][PaginateViewHelper::class]);
$widgetContext->expects($this->any())->method('getWidgetViewHelperClassName')->will($this->returnValue(\TYPO3\CMS\Fluid\ViewHelpers\Widget\PaginateViewHelper::class));
$request = $this->getMock(\TYPO3\CMS\Fluid\Core\Widget\WidgetRequest::class, array(), array(), '', FALSE); $widgetContext = $this->getMock(WidgetContext::class);
$widgetContext->expects($this->any())->method('getWidgetViewHelperClassName')->will($this->returnValue(PaginateViewHelper::class));
$request = $this->getMock(WidgetRequest::class, array(), array(), '', FALSE);
$request->expects($this->any())->method('getWidgetContext')->will($this->returnValue($widgetContext)); $request->expects($this->any())->method('getWidgetContext')->will($this->returnValue($widgetContext));
$configurationManager = $this->getMock(\TYPO3\CMS\Extbase\Configuration\ConfigurationManager::class); $request->expects($this->any())->method('getControllerExtensionKey')->will($this->returnValue('fluid'));
$configurationManager->expects($this->any())->method('getConfiguration')->will($this->returnValue($frameworkConfiguration));
$view = $this->getAccessibleMock(\TYPO3\CMS\Fluid\View\TemplateView::class, array('dummy'), array(), '', FALSE); $configurationManager = $this->getMock(ConfigurationManager::class);
$abstractWidgetController = $this->getAccessibleMock(\TYPO3\CMS\Fluid\Core\Widget\AbstractWidgetController::class, array('dummy')); $configurationManager->expects($this->at(1))->method('setConfiguration')->with($overriddenConfiguration);
$configurationManager->expects($this->any())->method('getConfiguration')->willReturnOnConsecutiveCalls($this->returnValue($frameworkConfiguration), $this->returnValue($overriddenConfiguration));
$controllerContext = $this->getMock(ControllerContext::class);
$controllerContext->expects($this->any())->method('getRequest')->will($this->returnValue($request));
/** @var TemplateView|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface $view */
$view = $this->getAccessibleMock(TemplateView::class, array('dummy'), array(), '', FALSE);
$view->_set('controllerContext', $controllerContext);
$abstractWidgetController = $this->getAccessibleMock(AbstractWidgetController::class, array('dummy'));
$abstractWidgetController->_set('configurationManager', $configurationManager); $abstractWidgetController->_set('configurationManager', $configurationManager);
$abstractWidgetController->_set('request', $request); $abstractWidgetController->_set('request', $request);
$abstractWidgetController->_set('controllerContext', $controllerContext);
$abstractWidgetController->_call('setViewConfiguration', $view); $abstractWidgetController->_call('setViewConfiguration', $view);
$this->assertSame(array(GeneralUtility::getFileAbsFileName('EXT:fluid/Resources/Private/DummyTestTemplates')), $view->_call('getTemplateRootPaths')); $this->assertSame(array('EXT:fluid/Resources/Private'), $view->_call('getTemplateRootPaths'));
} }
} }
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