From 1c7d7b753e2ed1df7d06461a9304631b1e169b38 Mon Sep 17 00:00:00 2001 From: Stefan Neufeind <typo3.neufeind@speedpartner.de> Date: Wed, 11 Jun 2014 22:34:53 +0200 Subject: [PATCH] [!!!][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: Stefan Neufeind <typo3.neufeind@speedpartner.de> Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Reviewed-by: Markus Klein <markus.klein@typo3.org> Tested-by: Markus Klein <markus.klein@typo3.org> --- ...ractWidgetControllerView-configuration.rst | 39 +++++++++++ .../Core/Widget/AbstractWidgetController.php | 50 +++++++++----- .../Widget/AbstractWidgetControllerTest.php | 66 +++++++++++++------ 3 files changed, 116 insertions(+), 39 deletions(-) create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Breaking-59505-UseFallbacksForAbstractWidgetControllerView-configuration.rst diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-59505-UseFallbacksForAbstractWidgetControllerView-configuration.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-59505-UseFallbacksForAbstractWidgetControllerView-configuration.rst new file mode 100644 index 000000000000..92045c42feed --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Breaking-59505-UseFallbacksForAbstractWidgetControllerView-configuration.rst @@ -0,0 +1,39 @@ +================================================================================ +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 + diff --git a/typo3/sysext/fluid/Classes/Core/Widget/AbstractWidgetController.php b/typo3/sysext/fluid/Classes/Core/Widget/AbstractWidgetController.php index f7620bb99b27..0b422d9352c4 100644 --- a/typo3/sysext/fluid/Classes/Core/Widget/AbstractWidgetController.php +++ b/typo3/sysext/fluid/Classes/Core/Widget/AbstractWidgetController.php @@ -20,6 +20,14 @@ namespace TYPO3\CMS\Fluid\Core\Widget; * * * 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. * Basically, it is an ActionController, and it additionally @@ -27,12 +35,12 @@ namespace TYPO3\CMS\Fluid\Core\Widget; * * @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 */ - protected $supportedRequestTypes = array(\TYPO3\CMS\Fluid\Core\Widget\WidgetRequest::class); + protected $supportedRequestTypes = array(WidgetRequest::class); /** * Configuration for this widget. @@ -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. * - * @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request The request object - * @param \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response The response, modified by this handler + * @param RequestInterface $request The request object + * @param ResponseInterface $response The response, modified by this handler * @return void * @api */ - public function processRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request, \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response) { - $this->widgetConfiguration = $request->getWidgetContext()->getWidgetConfiguration(); + public function processRequest(RequestInterface $request, ResponseInterface $response) { + if ($request instanceof WidgetRequest) { + $this->widgetConfiguration = $request->getWidgetContext()->getWidgetConfiguration(); + } parent::processRequest($request, $response); } /** - * Allows the widget template root path to be overriden via the framework configuration, - * e.g. plugin.tx_extension.view.widget.<WidgetViewHelperClassName>.templateRootPath + * Allows the widget template root path to be overridden via the framework configuration, + * e.g. plugin.tx_extension.view.widget.<WidgetViewHelperClassName>.templateRootPaths * - * @param \TYPO3\CMS\Extbase\Mvc\View\ViewInterface $view + * @param ViewInterface $view * @return void */ - protected function setViewConfiguration(\TYPO3\CMS\Extbase\Mvc\View\ViewInterface $view) { - $extbaseFrameworkConfiguration = $this->configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK); - $widgetViewHelperClassName = $this->request->getWidgetContext()->getWidgetViewHelperClassName(); - if ( - isset($extbaseFrameworkConfiguration['view']['widget'][$widgetViewHelperClassName]['templateRootPath']) - && $extbaseFrameworkConfiguration['view']['widget'][$widgetViewHelperClassName]['templateRootPath'] !== '' - && method_exists($view, 'setTemplateRootPath') - ) { - $view->setTemplateRootPath(\TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($extbaseFrameworkConfiguration['view']['widget'][$widgetViewHelperClassName]['templateRootPath'])); + protected function setViewConfiguration(ViewInterface $view) { + if ($this->request instanceof WidgetRequest) { + $extbaseFrameworkConfiguration = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK, $this->extensionName); + $widgetViewHelperClassName = $this->request->getWidgetContext()->getWidgetViewHelperClassName(); + if (isset($extbaseFrameworkConfiguration['view']['widget'][$widgetViewHelperClassName])) { + $configurationOverridden = $extbaseFrameworkConfiguration; + $configurationOverridden['view'] = array_replace_recursive($configurationOverridden['view'], $configurationOverridden['view']['widget'][$widgetViewHelperClassName]); + $this->configurationManager->setConfiguration($configurationOverridden); + parent::setViewConfiguration($view); + $this->configurationManager->setConfiguration($extbaseFrameworkConfiguration); + } else { + parent::setViewConfiguration($view); + } } } diff --git a/typo3/sysext/fluid/Tests/Unit/Core/Widget/AbstractWidgetControllerTest.php b/typo3/sysext/fluid/Tests/Unit/Core/Widget/AbstractWidgetControllerTest.php index b9a873e8f142..9438cf03b775 100644 --- a/typo3/sysext/fluid/Tests/Unit/Core/Widget/AbstractWidgetControllerTest.php +++ b/typo3/sysext/fluid/Tests/Unit/Core/Widget/AbstractWidgetControllerTest.php @@ -21,25 +21,34 @@ namespace TYPO3\CMS\Fluid\Tests\Unit\Core\Widget; * The TYPO3 project - inspiring people to share! * * */ +use TYPO3\CMS\Core\Tests\UnitTestCase; 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\ControllerContext; +use TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService; 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\WidgetContext; use TYPO3\CMS\Fluid\Core\Widget\WidgetRequest; +use TYPO3\CMS\Fluid\View\TemplateView; +use TYPO3\CMS\Fluid\ViewHelpers\Widget\PaginateViewHelper; /** * Test case */ -class AbstractWidgetControllerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase { +class AbstractWidgetControllerTest extends UnitTestCase { /** * @test */ public function canHandleWidgetRequest() { /** @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 */ - $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)); } @@ -47,20 +56,20 @@ class AbstractWidgetControllerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase { * @test */ 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')); /** @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)); /** @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 */ - $abstractWidgetController = $this->getAccessibleMock(\TYPO3\CMS\Fluid\Core\Widget\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); - $objectManager = $this->getMock(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface::class); - $objectManager->expects($this->any())->method('get')->with(\TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder::class)->will($this->returnValue($mockUriBuilder)); + $abstractWidgetController = $this->getAccessibleMock(AbstractWidgetController::class, array('resolveActionMethodName', 'initializeActionMethodArguments', 'initializeActionMethodValidators', 'initializeAction', 'checkRequestHash', 'mapRequestArgumentsToControllerArguments', 'buildControllerContext', 'resolveView', 'callActionMethod'), array(), '', FALSE); + $mockUriBuilder = $this->getMock(UriBuilder::class); + $objectManager = $this->getMock(ObjectManagerInterface::class); + $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('arguments', new Arguments()); @@ -77,24 +86,39 @@ class AbstractWidgetControllerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase { $frameworkConfiguration = array( 'view' => array( 'widget' => array( - \TYPO3\CMS\Fluid\ViewHelpers\Widget\PaginateViewHelper::class => array( - 'templateRootPath' => 'EXT:fluid/Resources/Private/DummyTestTemplates' + PaginateViewHelper::class => array( + 'templateRootPath' => 'EXT:fluid/Resources/Private', + 'templateRootPaths' => ['EXT:fluid/Resources/Private'] ) ) ) ); - $widgetContext = $this->getMock(\TYPO3\CMS\Fluid\Core\Widget\WidgetContext::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); + $overriddenConfiguration['view'] = array_merge_recursive($frameworkConfiguration['view'], $frameworkConfiguration['view']['widget'][PaginateViewHelper::class]); + + $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)); - $configurationManager = $this->getMock(\TYPO3\CMS\Extbase\Configuration\ConfigurationManager::class); - $configurationManager->expects($this->any())->method('getConfiguration')->will($this->returnValue($frameworkConfiguration)); - $view = $this->getAccessibleMock(\TYPO3\CMS\Fluid\View\TemplateView::class, array('dummy'), array(), '', FALSE); - $abstractWidgetController = $this->getAccessibleMock(\TYPO3\CMS\Fluid\Core\Widget\AbstractWidgetController::class, array('dummy')); + $request->expects($this->any())->method('getControllerExtensionKey')->will($this->returnValue('fluid')); + + $configurationManager = $this->getMock(ConfigurationManager::class); + $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('request', $request); + $abstractWidgetController->_set('controllerContext', $controllerContext); $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')); } } -- GitLab