Skip to content
Snippets Groups Projects
Commit f1475e8d authored by Benni Mack's avatar Benni Mack Committed by Georg Ringer
Browse files

[TASK] Unify Backend module registration for Extbase modules

This patch unifies the Backend module registration for Extbase modules
like it has already been done for all other Backend modules using PSR-7
entry-points. This way backend route dispatching and module registration
has been simplified.

The entrypoint for Extbase Backend modules is now
\TYPO3\CMS\Extbase\Core\Bootstrap->handleBackendRequest()
which returns a PSR-7 response object.

The following functionality has been marked as deprecated as it was
solely built to handle Extbase modules when conf.php and index.php were
still in style:

ExtensionManagementUtility::configureModule()
$GLOBALS['TBE_MODULES']['_configuration'][$name]['configureModuleFunction']

Releases: master
Resolves: #82902
Related: #58621
Change-Id: I7956b350d650ed52bc7b5d83db20df386d79eb65
Reviewed-on: https://review.typo3.org/54531


Tested-by: default avatarTYPO3com <no-reply@typo3.com>
Reviewed-by: default avatarHenning Liebe <h.liebe@neusta.de>
Reviewed-by: default avatarSusanne Moog <susanne.moog@typo3.org>
Tested-...
parent 2b7e7c9c
Branches
Tags
No related merge requests found
......@@ -55,7 +55,7 @@ class RouteDispatcher extends Dispatcher implements DispatcherInterface
}
if ($route->getOption('module')) {
return $this->dispatchModule($request, $response);
$this->addAndValidateModuleConfiguration($request, $route);
}
$targetIdentifier = $route->getOption('target');
$target = $this->getCallableFromTarget($targetIdentifier);
......@@ -92,18 +92,18 @@ class RouteDispatcher extends Dispatcher implements DispatcherInterface
}
/**
* Executes the modules configured via Extbase
* Adds configuration for a module and checks module permissions for the
* current user.
*
* @param ServerRequestInterface $request
* @param ResponseInterface $response
* @return ResponseInterface A PSR-7 response object
* @param Route $route
* @throws \RuntimeException
*/
protected function dispatchModule(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
protected function addAndValidateModuleConfiguration(ServerRequestInterface $request, Route $route)
{
$route = $request->getAttribute('route');
$moduleName = $route->getOption('moduleName');
$moduleConfiguration = $this->getModuleConfiguration($moduleName);
$route->setOption('moduleConfiguration', $moduleConfiguration);
$backendUserAuthentication = $GLOBALS['BE_USER'];
......@@ -123,37 +123,6 @@ class RouteDispatcher extends Dispatcher implements DispatcherInterface
}
}
}
// Use regular Dispatching
// @todo: unify with the code above
$targetIdentifier = $route->getOption('target');
if (!empty($targetIdentifier)) {
// @internal routeParameters are a helper construct for the install tool only.
// @todo: remove this, after sub-actions in install tool can be addressed directly
if (!empty($moduleConfiguration['routeParameters'])) {
$request = $request->withQueryParams(array_merge_recursive(
$request->getQueryParams(),
$moduleConfiguration['routeParameters']
));
}
return parent::dispatch($request, $response);
}
// extbase module
$configuration = [
'extensionName' => $moduleConfiguration['extensionName'],
'pluginName' => $moduleName
];
if (isset($moduleConfiguration['vendorName'])) {
$configuration['vendorName'] = $moduleConfiguration['vendorName'];
}
// Run Extbase
$bootstrap = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Core\Bootstrap::class);
$content = $bootstrap->run('', $configuration);
$response->getBody()->write($content);
return $response;
}
/**
......
......@@ -140,6 +140,7 @@ class ModuleLoader
{
// Check for own way of configuring module
if (is_array($GLOBALS['TBE_MODULES']['_configuration'][$name]['configureModuleFunction'])) {
trigger_error('Registering a module using "configureModuleFunction" is deprecated and will be removed in TYPO3 v10.', E_USER_DEPRECATED);
$obj = $GLOBALS['TBE_MODULES']['_configuration'][$name]['configureModuleFunction'];
if (is_callable($obj)) {
$MCONF = call_user_func($obj, $name);
......@@ -170,14 +171,8 @@ class ModuleLoader
// Language processing. This will add module labels and image reference to the internal ->moduleLabels array of the LANG object.
$this->addLabelsForModule($name, ($finalModuleConfiguration['labels'] ?? $setupInformation['labels']));
// Default script setup
if ($setupInformation['configuration']['script'] === '_DISPATCH' || isset($setupInformation['configuration']['routeTarget'])) {
if ($setupInformation['configuration']['extbase']) {
$finalModuleConfiguration['script'] = BackendUtility::getModuleUrl('Tx_' . $name);
} else {
// just go through BackendModuleRequestHandler where the routeTarget is resolved
$finalModuleConfiguration['script'] = BackendUtility::getModuleUrl($name);
}
if (isset($setupInformation['configuration']['routeTarget'])) {
$finalModuleConfiguration['script'] = BackendUtility::getModuleUrl($name);
} else {
$finalModuleConfiguration['script'] = BackendUtility::getModuleUrl('dummy');
}
......
......@@ -801,9 +801,11 @@ class ExtensionManagementUtility
*
* @param string $moduleSignature The module name
* @return array Configuration of the module
* @deprecated since TYPO3 v9, will be removed in TYPO3 v10, addModule() works the same way nowadays.
*/
public static function configureModule($moduleSignature)
{
trigger_error('This method will be removed in TYPO3 v10, as the same functionality is found in addModule() as well.', E_USER_DEPRECATED);
$moduleConfiguration = $GLOBALS['TBE_MODULES']['_configuration'][$moduleSignature];
// Register the icon and move it too "iconIdentifier"
......
.. include:: ../../Includes.txt
================================================================
Deprecation: #82902 - Custom Backend Module registration methods
================================================================
See :issue:`82902`
Description
===========
The internal API to register backend modules via ``ExtensionManagementUtility::configureModule()`` and
``configureModuleFunction`` has been marked as deprecated.
It was solely introduced to allow script-based dispatching of backend modules used in TYPO3 v6.2 which
had multiple entry-points (mod1/conf.php and mod1/index.php).
Since TYPO3 v7 Backend Routing is available, thus the old registration API is no longer needed.
Impact
======
Registering a `configureModuleFunction` will trigger a deprecation warning.
Calling ``ExtensionManagementUtility::configureModule()`` will trigger a deprecation warning.
Affected Installations
======================
Installations with legacy and/or custom Backend modules in extensions.
Migration
=========
Use either ``ExtensionManagementUtility::addModule()`` or Extbase's
``ExtensionUtility::registerModule()`` to register a module, always providing a ``routeTarget``.
.. index:: Backend, PHP-API, PartiallyScanned
......@@ -14,6 +14,11 @@ namespace TYPO3\CMS\Extbase\Core;
* The TYPO3 project - inspiring people to share!
*/
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Backend\Routing\Route;
use TYPO3\CMS\Extbase\Mvc\Web\Response;
/**
* Creates a request an dispatches it to the controller which was specified
* by TS Setup, flexForm and returns the content to the v4 framework.
......@@ -171,6 +176,62 @@ class Bootstrap implements \TYPO3\CMS\Extbase\Core\BootstrapInterface
return $content;
}
/**
* Entrypoint for backend modules, handling PSR-7 requests/responses
*
* @param ServerRequestInterface $request
* @return ResponseInterface
* @internal
*/
public function handleBackendRequest(ServerRequestInterface $request): ResponseInterface
{
// build the configuration from the Server request / route
/** @var Route $route */
$route = $request->getAttribute('route');
$moduleConfiguration = $route->getOption('moduleConfiguration');
$configuration = [
'extensionName' => $moduleConfiguration['extensionName'],
'pluginName' => $route->getOption('moduleName')
];
if (isset($moduleConfiguration['vendorName'])) {
$configuration['vendorName'] = $moduleConfiguration['vendorName'];
}
$this->initialize($configuration);
/** @var $requestHandlerResolver \TYPO3\CMS\Extbase\Mvc\RequestHandlerResolver */
$requestHandlerResolver = $this->objectManager->get(\TYPO3\CMS\Extbase\Mvc\RequestHandlerResolver::class);
$requestHandler = $requestHandlerResolver->resolveRequestHandler();
/** @var Response $extbaseResponse */
$extbaseResponse = $requestHandler->handleRequest();
// Convert to PSR-7 response and hand it back to TYPO3 Core
$response = $this->convertExtbaseResponseToPsr7Response($extbaseResponse);
$this->resetSingletons();
$this->objectManager->get(\TYPO3\CMS\Extbase\Service\CacheService::class)->clearCachesOfRegisteredPageIds();
return $response;
}
/**
* Converts a Extbase response object into a PSR-7 Response
*
* @param Response $extbaseResponse
* @return ResponseInterface
*/
protected function convertExtbaseResponseToPsr7Response(Response $extbaseResponse): ResponseInterface
{
$response = new \TYPO3\CMS\Core\Http\Response(
'php://temp',
$extbaseResponse->getStatusCode(),
$extbaseResponse->getUnpreparedHeaders()
);
$content = $extbaseResponse->getContent();
if ($content !== null) {
$response->getBody()->write($content);
}
return $response;
}
/**
* Resets global singletons for the next plugin
*/
......
......@@ -157,6 +157,17 @@ class Response extends \TYPO3\CMS\Extbase\Mvc\Response
return $this->statusCode . ' ' . $this->statusMessage;
}
/**
* Returns the status code, if not set, uses the OK status code 200
*
* @return int
* @internal only use for backend module handling
*/
public function getStatusCode()
{
return $this->statusCode ?: 200;
}
/**
* Sets the specified HTTP header
*
......@@ -200,6 +211,17 @@ class Response extends \TYPO3\CMS\Extbase\Mvc\Response
return $preparedHeaders;
}
/**
* Returns the HTTP headers grouped by name without the status header
*
* @return array all headers set for this request
* @internal only used within TYPO3 Core to convert to PSR-7 response headers
*/
public function getUnpreparedHeaders(): array
{
return $this->headers;
}
/**
* Sends the HTTP headers.
*
......
......@@ -193,8 +193,7 @@ tt_content.' . $pluginSignature . ' {
$moduleConfiguration['vendorName'] = $vendorName;
}
$moduleConfiguration['extensionName'] = $extensionName;
$moduleConfiguration['configureModuleFunction'] = [\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::class, 'configureModule'];
$GLOBALS['TBE_MODULES']['_configuration'][$moduleSignature] = $moduleConfiguration;
$moduleConfiguration['routeTarget'] = \TYPO3\CMS\Extbase\Core\Bootstrap::class . '::handleBackendRequest';
if (!is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['modules'][$moduleSignature])) {
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['modules'][$moduleSignature] = [];
}
......@@ -203,7 +202,7 @@ tt_content.' . $pluginSignature . ' {
'actions' => \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $actions)
];
}
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addModule($mainModuleName, $subModuleName, $position);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addModule($mainModuleName, $subModuleName, $position, null, $moduleConfiguration);
}
/**
......
......@@ -491,4 +491,11 @@ return [
'Deprecation-82899-ExtensionManagementUtilityMethods.rst',
],
],
'TYPO3\CMS\Core\Utility\ExtensionManagementUtility::configureModule' => [
'numberOfMandatoryArguments' => 0,
'maximumNumberOfArguments' => 0,
'restFiles' => [
'Deprecation-82902-CustomBackendModuleRegistrationMethods.rst',
],
],
];
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