Skip to content

Commit

Permalink
[!!!][TASK] Remove view related properties from ActionController
Browse files Browse the repository at this point in the history
Both properties $namespacesViewObjectNamePattern and
$viewFormatToObjectNameMap of class ActionController
have been removed without replacement.

Both properties provided a functionality to set a
custom view object class during runtime. As this
contradicts the idea of having a defined state per
request by configuring concrete implementations
before runtime, these properties needed to vanish.

While there is no dependency injection with a proper
configuration available, the view object class can
still be defined via property $defaultViewObjectName.

Releases: master
Resolves: #87511
Change-Id: I4b89a9434f71a3cbf38a9ad113ba8233e7f327f9
Reviewed-on: https://review.typo3.org/59514
Tested-by: TYPO3com <noreply@typo3.com>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Achim Fritz <af@achimfritz.de>
Reviewed-by: Benni Mack <benni@typo3.org>
Tested-by: Benni Mack <benni@typo3.org>
  • Loading branch information
alexanderschnitzler authored and bmack committed Jan 31, 2019
1 parent 6c58192 commit e4e01dd
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 128 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.. include:: ../../Includes.txt

===================================================================
Breaking: #87511 - Remove $namespacesViewObjectNamePattern property
===================================================================

See :issue:`87511`

Description
===========

Property :php:`$namespacesViewObjectNamePattern` of class
:php:`\TYPO3\CMS\Extbase\Mvc\Controller\ActionController` has been
removed without replacement.

Impact
======

Overriding the property :php:`$namespacesViewObjectNamePattern` in
controllers that extend :php`ActionController` will no longer trigger
the instantiation of another view object, derived from the pattern.

Affected Installations
======================

All extensions that override the property :php:`$namespacesViewObjectNamePattern`.

Migration
=========

If an action needs another template object other than the default
:php:`\TYPO3\CMS\Fluid\View\TemplateView`, the property :php:`$defaultViewObjectName`
needs to be overridden instead.

.. index:: PHP-API, FullyScanned, ext:extbase
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.. include:: ../../Includes.txt

=============================================================
Breaking: #87511 - Remove $viewFormatToObjectNameMap property
=============================================================

See :issue:`87511`

Description
===========

Property :php:`$viewFormatToObjectNameMap` of class
:php:`\TYPO3\CMS\Extbase\Mvc\Controller\ActionController` has been
removed without replacement.

Impact
======

Overriding the property :php:`$viewFormatToObjectNameMap` in
controllers that extend :php`ActionController` will no longer trigger
the instantiation of another view object, derived from the mapping.

Affected Installations
======================

All extensions that override the property :php:`$viewFormatToObjectNameMap`.

Migration
=========

If an action needs another template object other than the default
:php:`\TYPO3\CMS\Fluid\View\TemplateView`, the property :php:`$defaultViewObjectName`
needs to be overridden instead.

.. index:: PHP-API, FullyScanned, ext:extbase
65 changes: 1 addition & 64 deletions typo3/sysext/extbase/Classes/Mvc/Controller/ActionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,22 +46,6 @@ class ActionController extends AbstractController
*/
protected $view;

/**
* @var string
*/
protected $namespacesViewObjectNamePattern = '@vendor\@extension\View\@controller\@action@format';

/**
* A list of formats and object names of the views which should render them.
*
* Example:
*
* array('html' => 'Tx_MyExtension_View_MyHtmlView', 'json' => 'F3...
*
* @var array
*/
protected $viewFormatToObjectNameMap = [];

/**
* The default view object to use if none of the resolved views can render
* a response for the current request.
Expand Down Expand Up @@ -347,16 +331,7 @@ protected function emitBeforeCallActionMethodSignal(array $preparedArguments)
*/
protected function resolveView()
{
$viewObjectName = $this->resolveViewObjectName();
if ($viewObjectName !== false) {
/** @var ViewInterface $view */
$view = $this->objectManager->get($viewObjectName);
$this->setViewConfiguration($view);
if ($view->canRender($this->controllerContext) === false) {
unset($view);
}
}
if (!isset($view) && $this->defaultViewObjectName != '') {
if ($this->defaultViewObjectName != '') {
/** @var ViewInterface $view */
$view = $this->objectManager->get($this->defaultViewObjectName);
$this->setViewConfiguration($view);
Expand Down Expand Up @@ -447,44 +422,6 @@ protected function getViewProperty($extbaseFrameworkConfiguration, $setting)
return $values;
}

/**
* Determines the fully qualified view object name.
*
* @return mixed The fully qualified view object name or FALSE if no matching view could be found.
*/
protected function resolveViewObjectName()
{
$vendorName = $this->request->getControllerVendorName();
if ($vendorName === null) {
return false;
}

$possibleViewName = str_replace(
[
'@vendor',
'@extension',
'@controller',
'@action'
],
[
$vendorName,
$this->request->getControllerExtensionName(),
$this->request->getControllerName(),
ucfirst($this->request->getControllerActionName())
],
$this->namespacesViewObjectNamePattern
);
$format = $this->request->getFormat();
$viewObjectName = str_replace('@format', ucfirst($format), $possibleViewName);
if (class_exists($viewObjectName) === false) {
$viewObjectName = str_replace('@format', '', $possibleViewName);
}
if (isset($this->viewFormatToObjectNameMap[$format]) && class_exists($viewObjectName) === false) {
$viewObjectName = $this->viewFormatToObjectNameMap[$format];
}
return class_exists($viewObjectName) ? $viewObjectName : false;
}

/**
* Initializes the view before invoking an action method.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,14 @@
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Extbase\Mvc\Controller\Arguments;
use TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext;
use TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentTypeException;
use TYPO3\CMS\Extbase\Mvc\Exception\NoSuchActionException;
use TYPO3\CMS\Extbase\Mvc\Request;
use TYPO3\CMS\Extbase\Mvc\RequestInterface;
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
use TYPO3\CMS\Extbase\Reflection\ClassSchema;
use TYPO3\CMS\Extbase\Reflection\ReflectionService;
use TYPO3\CMS\Fluid\View\TemplateView;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
use TYPO3Fluid\Fluid\View\AbstractTemplateView;
use TYPO3Fluid\Fluid\View\TemplateView as FluidTemplateView;
Expand Down Expand Up @@ -64,67 +61,6 @@ class ActionControllerTest extends UnitTestCase
*/
protected $mockMvcPropertyMappingConfigurationService;

/**
* @test
*/
public function resolveViewUsesFluidTemplateViewIfTemplateIsAvailable()
{
$mockControllerContext = $this->createMock(ControllerContext::class);
$mockFluidTemplateView = $this->createMock(ViewInterface::class);
$mockFluidTemplateView->expects($this->once())->method('setControllerContext')->with($mockControllerContext);
$mockFluidTemplateView->expects($this->once())->method('canRender')->with($mockControllerContext)->will($this->returnValue(true));
$mockObjectManager = $this->createMock(ObjectManagerInterface::class);
$mockObjectManager->expects($this->at(0))->method('get')->with(TemplateView::class)->will($this->returnValue($mockFluidTemplateView));
$mockController = $this->getAccessibleMock(ActionController::class, ['buildControllerContext', 'resolveViewObjectName', 'setViewConfiguration'], [], '', false);
$mockController->expects($this->once())->method('resolveViewObjectName')->will($this->returnValue(false));
$mockController->_set('objectManager', $mockObjectManager);
$mockController->_set('controllerContext', $mockControllerContext);
$this->assertSame($mockFluidTemplateView, $mockController->_call('resolveView'));
}

/**
* @test
*/
public function resolveViewObjectNameUsesViewObjectNamePatternToResolveViewObjectName()
{
$mockRequest = $this->createMock(Request::class);
$mockRequest->expects($this->once())->method('getControllerVendorName')->will($this->returnValue('MyVendor'));
$mockRequest->expects($this->once())->method('getControllerExtensionName')->will($this->returnValue('MyPackage'));
$mockRequest->expects($this->once())->method('getControllerName')->will($this->returnValue('MyController'));
$mockRequest->expects($this->once())->method('getControllerActionName')->will($this->returnValue('MyAction'));
$mockRequest->expects($this->atLeastOnce())->method('getFormat')->will($this->returnValue('MyFormat'));
$mockObjectManager = $this->createMock(ObjectManagerInterface::class);
$mockController = $this->getAccessibleMock(ActionController::class, ['dummy'], [], '', false);
$mockController->_set('request', $mockRequest);
$mockController->_set('objectManager', $mockObjectManager);
$mockController->_set('namespacesViewObjectNamePattern', 'RandomViewObject@vendor\@extension\View\@controller\@action@format');
$mockController->_call('resolveViewObjectName');
}

/**
* @test
*/
public function resolveViewObjectNameUsesNamespacedViewObjectNamePatternForExtensionsWithVendor()
{
eval('namespace MyVendor\MyPackage\View\MyController; class MyActionMyFormat {}');

$mockRequest = $this->createMock(Request::class);
$mockRequest->expects($this->once())->method('getControllerExtensionName')->will($this->returnValue('MyPackage'));
$mockRequest->expects($this->once())->method('getControllerName')->will($this->returnValue('MyController'));
$mockRequest->expects($this->once())->method('getControllerActionName')->will($this->returnValue('MyAction'));
$mockRequest->expects($this->once())->method('getControllerVendorName')->will($this->returnValue('MyVendor'));
$mockRequest->expects($this->atLeastOnce())->method('getFormat')->will($this->returnValue('MyFormat'));
$mockObjectManager = $this->createMock(ObjectManagerInterface::class);
$mockController = $this->getAccessibleMock(ActionController::class, ['dummy'], [], '', false);
$mockController->_set('request', $mockRequest);
$mockController->_set('objectManager', $mockObjectManager);

$this->assertEquals(
'MyVendor\MyPackage\View\MyController\MyActionMyFormat',
$mockController->_call('resolveViewObjectName')
);
}

/**
* @test
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1243,4 +1243,14 @@
'Breaking-87193-DeprecatedFunctionalityRemoved.rst',
],
],
'TYPO3\CMS\Extbase\Mvc\Controller\ActionController->namespacesViewObjectNamePattern' => [
'restFiles' => [
'Breaking-87511-RemoveNamespacesViewObjectNamePatternProperty.rst',
],
],
'TYPO3\CMS\Extbase\Mvc\Controller\ActionController->viewFormatToObjectNameMap' => [
'restFiles' => [
'Breaking-87511-RemoveViewFormatToObjectNameMapProperty.rst',
],
],
];
Original file line number Diff line number Diff line change
Expand Up @@ -519,4 +519,14 @@
'Breaking-87193-DeprecatedFunctionalityRemoved.rst',
],
],
'TYPO3\CMS\Extbase\Mvc\Controller\ActionController->namespacesViewObjectNamePattern' => [
'restFiles' => [
'Breaking-87511-RemoveNamespacesViewObjectNamePatternProperty.rst',
],
],
'TYPO3\CMS\Extbase\Mvc\Controller\ActionController->viewFormatToObjectNameMap' => [
'restFiles' => [
'Breaking-87511-RemoveViewFormatToObjectNameMapProperty.rst',
],
],
];

0 comments on commit e4e01dd

Please sign in to comment.