From 9369ea39f03abf65a16451046f1636843c48a739 Mon Sep 17 00:00:00 2001 From: Benni Mack <benni@typo3.org> Date: Fri, 25 May 2018 11:15:29 +0200 Subject: [PATCH] [TASK] Deprecate Backend Module Routing methods Since TYPO3 v9.0, all routing in backend is handled unified, thus, the old methods from historical reasons can be deprecated. - BackendUtility::getModuleUrl() - UriBuilder->buildUriFromModule() Instead of guessing the name to a module route, an "id" for the route (like the path) can be explictly given. Resolves: #85113 Releases: master Change-Id: I8cf2b9dc3a938dd7227dcc972e0782619ede4213 Reviewed-on: https://review.typo3.org/57048 Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl> Tested-by: Wouter Wolters <typo3@wouterwolters.nl> --- .../backend/Classes/Routing/UriBuilder.php | 2 + .../Classes/Utility/BackendUtility.php | 3 +- .../Utility/ExtensionManagementUtility.php | 18 +++------ ...5113-LegacyBackendModuleRoutingMethods.rst | 38 +++++++++++++++++++ .../Classes/Mvc/Web/Routing/UriBuilder.php | 25 +++++++----- .../Unit/Mvc/Web/Routing/UriBuilderTest.php | 9 +++-- .../Php/MethodCallMatcher.php | 7 ++++ .../Php/MethodCallStaticMatcher.php | 7 ++++ .../Classes/RecordList/DatabaseRecordList.php | 2 +- 9 files changed, 83 insertions(+), 28 deletions(-) create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Deprecation-85113-LegacyBackendModuleRoutingMethods.rst diff --git a/typo3/sysext/backend/Classes/Routing/UriBuilder.php b/typo3/sysext/backend/Classes/Routing/UriBuilder.php index 6086927ac16a..10e998d8bff0 100644 --- a/typo3/sysext/backend/Classes/Routing/UriBuilder.php +++ b/typo3/sysext/backend/Classes/Routing/UriBuilder.php @@ -121,9 +121,11 @@ class UriBuilder * @param string $referenceType The type of reference to be generated (one of the constants) * * @return Uri The generated Uri + * @deprecated since TYPO3 v9.3, will be removed in TYPO3 v10. Use buildUriFromRoute() instead. */ public function buildUriFromModule($moduleName, $parameters = [], $referenceType = self::ABSOLUTE_PATH) { + trigger_error('UriBuilder->buildUriFromModule() will be removed in TYPO3 v10, use buildUriFromRoute() instead.', E_USER_DEPRECATED); $parameters = [ 'route' => $moduleName, 'token' => FormProtectionFactory::get('backend')->generateToken('route', $moduleName) diff --git a/typo3/sysext/backend/Classes/Utility/BackendUtility.php b/typo3/sysext/backend/Classes/Utility/BackendUtility.php index b6476d9f8819..5f33c73ab414 100644 --- a/typo3/sysext/backend/Classes/Utility/BackendUtility.php +++ b/typo3/sysext/backend/Classes/Utility/BackendUtility.php @@ -3205,10 +3205,11 @@ class BackendUtility * @param string $moduleName Name of the module * @param array $urlParameters URL parameters that should be added as key value pairs * @return string Calculated URL + * @deprecated since TYPO3 v9, will be removed in TYPO3 v10. Use UriBuilder instead. */ public static function getModuleUrl($moduleName, $urlParameters = []) { - /** @var UriBuilder $uriBuilder */ + trigger_error('BackendUtility::getModuleUrl() will be removed in TYPO3 v10, use UriBuilder->buildUriFromRoute() instead.', E_USER_DEPRECATED); $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); try { $uri = $uriBuilder->buildUriFromRoute($moduleName, $urlParameters); diff --git a/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php b/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php index f588433d68ce..7e647b832e37 100644 --- a/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php +++ b/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php @@ -15,6 +15,8 @@ namespace TYPO3\CMS\Core\Utility; */ use Symfony\Component\Finder\Finder; +use TYPO3\CMS\Backend\Routing\Route; +use TYPO3\CMS\Backend\Routing\Router; use TYPO3\CMS\Core\Category\CategoryRegistry; use TYPO3\CMS\Core\Core\Environment; use TYPO3\CMS\Core\Imaging\IconRegistry; @@ -904,13 +906,9 @@ class ExtensionManagementUtility } // Also register the module as regular route + $routeName = $moduleConfiguration['id'] ?? $fullModuleSignature; // Build Route objects from the data - $name = $fullModuleSignature; - if (isset($moduleConfiguration['path'])) { - $path = $moduleConfiguration['path']; - } else { - $path = str_replace('_', '/', $name); - } + $path = $moduleConfiguration['path'] ?? str_replace('_', '/', $fullModuleSignature); $path = '/' . trim($path, '/') . '/'; $options = [ @@ -922,12 +920,8 @@ class ExtensionManagementUtility $options['target'] = $moduleConfiguration['routeTarget']; } - $router = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\Router::class); - $router->addRoute( - $name, - // @todo: see if we should do a "module route" - GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\Route::class, $path, $options) - ); + $router = GeneralUtility::makeInstance(Router::class); + $router->addRoute($routeName, GeneralUtility::makeInstance(Route::class, $path, $options)); } /** diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-85113-LegacyBackendModuleRoutingMethods.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-85113-LegacyBackendModuleRoutingMethods.rst new file mode 100644 index 000000000000..7bb6cb6e0f9c --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-85113-LegacyBackendModuleRoutingMethods.rst @@ -0,0 +1,38 @@ +.. include:: ../../Includes.txt + +=========================================================== +Deprecation: #85113 - Legacy Backend Module Routing methods +=========================================================== + +See :issue:`85113` + +Description +=========== + +In TYPO3 v9, Backend routing was unified to be handled via the "route" query string parameter. Backend modules +are now automatically registered to be a backend route. + +The following methods are thus deprecated in favor of using the method above. + +* :php:`BackendUtility::getModuleUrl()` +* :php:`UriBuilder->buildUriFromModule()` + + +Impact +====== + +Calling one of the deprecated methods above will trigger a deprecation message. + + +Affected Installations +====================== + +Any TYPO3 installation with a custom backend-related extension using one of the methods directly in a PHP context. + + +Migration +========= + +Use :php:`UriBuilder->buildUriFromRoute($moduleIdentifier)` instead. + +.. index:: Backend, PHP-API, FullyScanned diff --git a/typo3/sysext/extbase/Classes/Mvc/Web/Routing/UriBuilder.php b/typo3/sysext/extbase/Classes/Mvc/Web/Routing/UriBuilder.php index 9d8dbd1dcbae..ea6b929bb555 100644 --- a/typo3/sysext/extbase/Classes/Mvc/Web/Routing/UriBuilder.php +++ b/typo3/sysext/extbase/Classes/Mvc/Web/Routing/UriBuilder.php @@ -15,6 +15,7 @@ namespace TYPO3\CMS\Extbase\Mvc\Web\Routing; */ use TYPO3\CMS\Backend\Routing\Exception\ResourceNotFoundException; +use TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException; use TYPO3\CMS\Core\Utility\ArrayUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Mvc\Request; @@ -667,31 +668,35 @@ class UriBuilder $id = GeneralUtility::_GP('id'); // backwards compatibility: check for M parameter // @deprecated since TYPO3 CMS 9, will be removed in TYPO3 CMS 10. - $module = GeneralUtility::_GP('route') ?: GeneralUtility::_GP('M'); + $route = GeneralUtility::_GP('route') ?: GeneralUtility::_GP('M'); if ($id !== null) { $arguments['id'] = $id; } - if ($module !== null) { - $arguments['route'] = $module; + if ($route !== null) { + $arguments['route'] = $route; } } ArrayUtility::mergeRecursiveWithOverrule($arguments, $this->arguments); $arguments = $this->convertDomainObjectsToIdentityArrays($arguments); $this->lastArguments = $arguments; - $moduleName = $arguments['route'] ?? null; + $routeName = $arguments['route'] ?? null; unset($arguments['route'], $arguments['token']); $backendUriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class); try { if ($this->request instanceof WebRequest && $this->createAbsoluteUri) { - $uri = (string)$backendUriBuilder->buildUriFromRoutePath($moduleName, $arguments, \TYPO3\CMS\Backend\Routing\UriBuilder::ABSOLUTE_URL); + $uri = (string)$backendUriBuilder->buildUriFromRoutePath($routeName, $arguments, \TYPO3\CMS\Backend\Routing\UriBuilder::ABSOLUTE_URL); } else { - $uri = (string)$backendUriBuilder->buildUriFromRoutePath($moduleName, $arguments, \TYPO3\CMS\Backend\Routing\UriBuilder::ABSOLUTE_PATH); + $uri = (string)$backendUriBuilder->buildUriFromRoutePath($routeName, $arguments, \TYPO3\CMS\Backend\Routing\UriBuilder::ABSOLUTE_PATH); } } catch (ResourceNotFoundException $e) { - if ($this->request instanceof WebRequest && $this->createAbsoluteUri) { - $uri = (string)$backendUriBuilder->buildUriFromModule($moduleName, $arguments, \TYPO3\CMS\Backend\Routing\UriBuilder::ABSOLUTE_URL); - } else { - $uri = (string)$backendUriBuilder->buildUriFromModule($moduleName, $arguments, \TYPO3\CMS\Backend\Routing\UriBuilder::ABSOLUTE_PATH); + try { + if ($this->request instanceof WebRequest && $this->createAbsoluteUri) { + $uri = (string)$backendUriBuilder->buildUriFromRoute($routeName, $arguments, \TYPO3\CMS\Backend\Routing\UriBuilder::ABSOLUTE_URL); + } else { + $uri = (string)$backendUriBuilder->buildUriFromRoute($routeName, $arguments, \TYPO3\CMS\Backend\Routing\UriBuilder::ABSOLUTE_PATH); + } + } catch (RouteNotFoundException $e) { + $uri = ''; } } if ($this->section !== '') { diff --git a/typo3/sysext/extbase/Tests/Unit/Mvc/Web/Routing/UriBuilderTest.php b/typo3/sysext/extbase/Tests/Unit/Mvc/Web/Routing/UriBuilderTest.php index 5cf4d0ba5d88..f84b16007f88 100644 --- a/typo3/sysext/extbase/Tests/Unit/Mvc/Web/Routing/UriBuilderTest.php +++ b/typo3/sysext/extbase/Tests/Unit/Mvc/Web/Routing/UriBuilderTest.php @@ -83,6 +83,7 @@ class UriBuilderTest extends UnitTestCase $router = GeneralUtility::makeInstance(Router::class); $router->addRoute('module_key', new Route('/test/Path', [])); $router->addRoute('module_key2', new Route('/test/Path2', [])); + $router->addRoute('', new Route('', [])); // Mocking backend user is required for backend URI generation as BackendUtility::getModuleUrl() is called $backendUserMock = $this->createMock(BackendUserAuthentication::class); $backendUserMock->expects($this->any())->method('check')->will($this->returnValue(true)); @@ -258,7 +259,7 @@ class UriBuilderTest extends UnitTestCase 'route', 'id' ], - '/typo3/index.php?route=&token=dummyToken&foo=bar&foo2=bar2' + '/typo3/index.php?route=%2F&token=dummyToken&foo=bar&foo2=bar2' ], 'Arguments to be excluded in the end' => [ [ @@ -273,7 +274,7 @@ class UriBuilderTest extends UnitTestCase 'route', 'id' ], - '/typo3/index.php?route=&token=dummyToken&foo=bar&foo2=bar2' + '/typo3/index.php?route=%2F&token=dummyToken&foo=bar&foo2=bar2' ], 'Arguments in nested array to be excluded' => [ [ @@ -428,7 +429,7 @@ class UriBuilderTest extends UnitTestCase ]; $this->uriBuilder->setAddQueryString(true); $this->uriBuilder->setAddQueryStringMethod('POST,GET'); - $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('/typo3/index.php?route=&token=dummyToken&key1=POST1&key2=GET2&key3[key31]=POST31&key3[key32]=GET32&key3[key33][key331]=GET331&key3[key33][key332]=POST332'); + $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('/typo3/index.php?route=%2F&token=dummyToken&key1=POST1&key2=GET2&key3[key31]=POST31&key3[key32]=GET32&key3[key33][key331]=GET331&key3[key33][key332]=POST332'); $actualResult = $this->uriBuilder->buildBackendUri(); $this->assertEquals($expectedResult, $actualResult); } @@ -461,7 +462,7 @@ class UriBuilderTest extends UnitTestCase ]; $this->uriBuilder->setAddQueryString(true); $this->uriBuilder->setAddQueryStringMethod('GET,POST'); - $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('/typo3/index.php?route=&token=dummyToken&key1=GET1&key2=POST2&key3[key31]=GET31&key3[key32]=POST32&key3[key33][key331]=POST331&key3[key33][key332]=GET332'); + $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('/typo3/index.php?route=%2F&token=dummyToken&key1=GET1&key2=POST2&key3[key31]=GET31&key3[key32]=POST32&key3[key33][key331]=POST331&key3[key33][key332]=GET332'); $actualResult = $this->uriBuilder->buildBackendUri(); $this->assertEquals($expectedResult, $actualResult); } diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php index 3dfd88579845..60cd80afcebc 100644 --- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php +++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php @@ -2317,4 +2317,11 @@ return [ 'Deprecation-85125-UsagesOfCharsetConverterInCore.rst' ], ], + 'TYPO3\CMS\Backend\Routing\UriBuilder->buildUriFromModule' => [ + 'numberOfMandatoryArguments' => 0, + 'maximumNumberOfArguments' => 0, + 'restFiles' => [ + 'Deprecation-85113-LegacyBackendModuleRoutingMethods.rst', + ] + ], ]; diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php index a47d5faae27d..08b1ec360850 100644 --- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php +++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php @@ -596,4 +596,11 @@ return [ 'Deprecation-85102-PhpOptionsUtility.rst', ], ], + 'TYPO3\CMS\Backend\Utility\BackendUtility::getModuleUrl' => [ + 'numberOfMandatoryArguments' => 1, + 'maximumNumberOfArguments' => 2, + 'restFiles' => [ + 'Deprecation-85113-LegacyBackendModuleRoutingMethods.rst', + ], + ], ]; diff --git a/typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php b/typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php index b1d5d64abcd0..0acccfe93d1c 100644 --- a/typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php +++ b/typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php @@ -2002,7 +2002,7 @@ class DatabaseRecordList if ($this->isEditable($table)) { // "Revert" link (history/undo) if ((bool)\trim($userTsConfig['options.']['showHistory.'][$table] ?? $userTsConfig['options.']['showHistory'] ?? '1')) { - $moduleUrl = BackendUtility::getModuleUrl('record_history', ['element' => $table . ':' . $row['uid']]); + $moduleUrl = (string)$uriBuilder->buildUriFromRoute('record_history', ['element' => $table . ':' . $row['uid']]); $onClick = 'return jumpExt(' . GeneralUtility::quoteJSvalue($moduleUrl) . ',\'#latest\');'; $historyAction = '<a class="btn btn-default" href="#" onclick="' . htmlspecialchars($onClick) . '" title="' . htmlspecialchars($this->getLanguageService()->getLL('history')) . '">' -- GitLab