diff --git a/typo3/sysext/backend/Classes/Clipboard/Clipboard.php b/typo3/sysext/backend/Classes/Clipboard/Clipboard.php index 12abf4150f867c1277369adc9ad301de2006d8a3..745a25bc68c07e42f471e867b32e344346b208a3 100644 --- a/typo3/sysext/backend/Classes/Clipboard/Clipboard.php +++ b/typo3/sysext/backend/Classes/Clipboard/Clipboard.php @@ -788,8 +788,8 @@ class Clipboard 1633604720 ); } - return (string)$this->uriBuilder->buildUriFromRoute( - $this->request->getAttribute('route')->getOption('_identifier'), + return (string)$this->uriBuilder->buildUriFromRequest( + $this->request, array_replace($this->request->getQueryParams(), $parameters) ); } diff --git a/typo3/sysext/backend/Classes/Controller/AbstractLinkBrowserController.php b/typo3/sysext/backend/Classes/Controller/AbstractLinkBrowserController.php index 45c5e4c9ca4649cc7a2e073cf375e5ec24a0f3f4..992f19bde67270374c5933f45b0364b48fb97b21 100644 --- a/typo3/sysext/backend/Classes/Controller/AbstractLinkBrowserController.php +++ b/typo3/sysext/backend/Classes/Controller/AbstractLinkBrowserController.php @@ -36,7 +36,6 @@ use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Page\PageRenderer; use TYPO3\CMS\Core\Service\DependencyOrderingService; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Core\Utility\HttpUtility; use TYPO3\CMS\Core\View\ViewInterface; /** @@ -48,11 +47,6 @@ abstract class AbstractLinkBrowserController { use PageRendererBackendSetupTrait; - /** - * URL of current request - */ - protected string $thisScript = ''; - /** * @var array<string, array> */ @@ -159,12 +153,11 @@ abstract class AbstractLinkBrowserController $this->pageRenderer->addInlineLanguageLabelFile('EXT:core/Resources/Private/Language/locallang_misc.xlf'); $this->pageRenderer->addInlineLanguageLabelFile('EXT:core/Resources/Private/Language/locallang_core.xlf'); - $this->determineScriptUrl($request); $this->initVariables($request); $this->loadLinkHandlers(); $this->initCurrentUrl(); - $menuData = $this->buildMenuArray(); + $menuData = $this->buildMenuArray($request); if ($this->displayedLinkHandler instanceof LinkHandlerViewProviderInterface) { $view = $this->displayedLinkHandler->createView($this->backendViewFactory, $request); } else { @@ -215,29 +208,11 @@ abstract class AbstractLinkBrowserController ]; } - public function getScriptUrl(): string - { - return $this->thisScript; - } - public function getParameters(): array { return $this->parameters; } - /** - * Sets the script url depending on being a module or script request. - */ - protected function determineScriptUrl(ServerRequestInterface $request): void - { - if ($route = $request->getAttribute('route')) { - $this->thisScript = (string)$this->uriBuilder->buildUriFromRoute($route->getOption('_identifier')); - } else { - $normalizedParams = $request->getAttribute('normalizedParams'); - $this->thisScript = $normalizedParams->getScriptName(); - } - } - protected function initVariables(ServerRequestInterface $request): void { $queryParams = $request->getQueryParams(); @@ -346,7 +321,7 @@ abstract class AbstractLinkBrowserController * * @return array[] */ - protected function buildMenuArray(): array + protected function buildMenuArray(ServerRequestInterface $request): array { $allowedItems = $this->getAllowedItems(); if ($this->displayedLinkHandlerId && !in_array($this->displayedLinkHandlerId, $allowedItems, true)) { @@ -373,7 +348,7 @@ abstract class AbstractLinkBrowserController $menuDef[$identifier] = [ 'isActive' => $isActive, 'label' => $configuration['label'], - 'url' => $this->thisScript . HttpUtility::buildQueryString($this->getUrlParameters(['act' => $identifier]), '&'), + 'url' => $this->uriBuilder->buildUriFromRequest($request, $this->getUrlParameters(['act' => $identifier])), 'addParams' => $configuration['addParams'] ?? '', 'before' => $configuration['displayBefore'], 'after' => $configuration['displayAfter'], diff --git a/typo3/sysext/backend/Classes/Controller/RecordListController.php b/typo3/sysext/backend/Classes/Controller/RecordListController.php index a4a6289dc02ee0f5588d074f52bdffecb0490b69..747005726720f7285e7d68db971876eff06ed27c 100644 --- a/typo3/sysext/backend/Classes/Controller/RecordListController.php +++ b/typo3/sysext/backend/Classes/Controller/RecordListController.php @@ -617,7 +617,7 @@ class RecordListController return $value !== null && trim((string)$value) !== ''; }); - return (string)$this->uriBuilder->buildUriFromRoute($request->getAttribute('route')->getOption('_identifier'), $params); + return (string)$this->uriBuilder->buildUriFromRequest($request, $params); } /** diff --git a/typo3/sysext/backend/Classes/ElementBrowser/AbstractElementBrowser.php b/typo3/sysext/backend/Classes/ElementBrowser/AbstractElementBrowser.php index cda8678e00d699b2fd8791615d43393ffd8d7607..f03fe2895b2f9d11d976bb1a68b9a45a35d83020 100644 --- a/typo3/sysext/backend/Classes/ElementBrowser/AbstractElementBrowser.php +++ b/typo3/sysext/backend/Classes/ElementBrowser/AbstractElementBrowser.php @@ -44,13 +44,6 @@ abstract class AbstractElementBrowser */ protected string $identifier = ''; - /** - * URL of current request - * - * @var string - */ - protected $thisScript = ''; - /** * Active with TYPO3 Element Browser: Contains the name of the form field for which this window * opens - thus allows us to make references back to the main window in which the form is. @@ -95,7 +88,6 @@ abstract class AbstractElementBrowser $this->pageRenderer->loadJavaScriptModule('@typo3/backend/viewport/resizable-navigation.js'); $this->pageRenderer->addInlineLanguageLabelFile('EXT:core/Resources/Private/Language/locallang_misc.xlf'); $this->pageRenderer->addInlineLanguageLabelFile('EXT:core/Resources/Private/Language/locallang_core.xlf'); - $this->determineScriptUrl(); $this->initVariables($request); } @@ -107,16 +99,6 @@ abstract class AbstractElementBrowser return $this->identifier; } - /** - * Sets the script url depending on being a module or script request - */ - protected function determineScriptUrl() - { - $this->thisScript = (string)$this->uriBuilder->buildUriFromRoute( - $this->getRequest()->getAttribute('route')->getOption('_identifier') - ); - } - protected function initVariables(ServerRequestInterface $request) { $this->bparams = $request->getParsedBody()['bparams'] ?? $request->getQueryParams()['bparams'] ?? ''; diff --git a/typo3/sysext/backend/Classes/ElementBrowser/DatabaseBrowser.php b/typo3/sysext/backend/Classes/ElementBrowser/DatabaseBrowser.php index 34370355e1088fc435bc463ebbe9979056132778..2bde02a4a73f6e84535b506155d98a997ddfbd4a 100644 --- a/typo3/sysext/backend/Classes/ElementBrowser/DatabaseBrowser.php +++ b/typo3/sysext/backend/Classes/ElementBrowser/DatabaseBrowser.php @@ -238,7 +238,7 @@ class DatabaseBrowser extends AbstractElementBrowser implements ElementBrowserIn * @param array $values Array of values to include into the parameters * @return string[] Array of parameters which have to be added to URLs */ - public function getUrlParameters(array $values) + public function getUrlParameters(array $values): array { $pid = $values['pid'] ?? $this->expandPage; return [ @@ -247,23 +247,4 @@ class DatabaseBrowser extends AbstractElementBrowser implements ElementBrowserIn 'bparams' => $this->bparams, ]; } - - /** - * @param array $values Values to be checked - * @return bool Returns TRUE if the given values match the currently selected item - */ - public function isCurrentlySelectedItem(array $values) - { - return false; - } - - /** - * Returns the URL of the current script - * - * @return string - */ - public function getScriptUrl() - { - return $this->thisScript; - } } diff --git a/typo3/sysext/backend/Classes/LinkHandler/PageLinkHandler.php b/typo3/sysext/backend/Classes/LinkHandler/PageLinkHandler.php index 168dc5e6cc34a02470eb5ad2c4747f6faa6588c7..bf2f1aee19364839d2fa8e28c5d476239480ee44 100644 --- a/typo3/sysext/backend/Classes/LinkHandler/PageLinkHandler.php +++ b/typo3/sysext/backend/Classes/LinkHandler/PageLinkHandler.php @@ -203,10 +203,9 @@ class PageLinkHandler extends AbstractLinkHandler implements LinkHandlerInterfac /** * @param array $values Array of values to include into the parameters or which might influence the parameters - * * @return string[] Array of parameters which have to be added to URLs */ - public function getUrlParameters(array $values) + public function getUrlParameters(array $values): array { $parameters = [ 'expandPage' => isset($values['pid']) ? (int)$values['pid'] : $this->expandPage, @@ -214,26 +213,6 @@ class PageLinkHandler extends AbstractLinkHandler implements LinkHandlerInterfac return array_merge($this->linkBrowser->getUrlParameters($values), $parameters); } - /** - * @param array $values Values to be checked - * - * @return bool Returns TRUE if the given values match the currently selected item - */ - public function isCurrentlySelectedItem(array $values) - { - return !empty($this->linkParts) && (int)$this->linkParts['url']['pageuid'] === (int)$values['pid']; - } - - /** - * Returns the URL of the current script - * - * @return string - */ - public function getScriptUrl() - { - return $this->linkBrowser->getScriptUrl(); - } - /** * @param string[] $fieldDefinitions Array of link attribute field definitions * @return string[] diff --git a/typo3/sysext/backend/Classes/LinkHandler/RecordLinkHandler.php b/typo3/sysext/backend/Classes/LinkHandler/RecordLinkHandler.php index 82f68ae417490573018c80e8ee30b3aec6166867..8c438b47b456f135f8fc4faa4e197c43f2587e6d 100644 --- a/typo3/sysext/backend/Classes/LinkHandler/RecordLinkHandler.php +++ b/typo3/sysext/backend/Classes/LinkHandler/RecordLinkHandler.php @@ -206,25 +206,6 @@ final class RecordLinkHandler extends AbstractLinkHandler implements LinkHandler ); } - /** - * Checks if the submitted page matches the current page. - * - * @param array $values Values to be checked - * @return bool Returns TRUE if the given values match the currently selected item - */ - public function isCurrentlySelectedItem(array $values): bool - { - return !empty($this->linkParts) && (int)$this->linkParts['pid'] === (int)$values['pid']; - } - - /** - * Returns the URL of the current script - */ - public function getScriptUrl(): string - { - return $this->linkBrowser->getScriptUrl(); - } - /** * Render elements of configured table */ diff --git a/typo3/sysext/backend/Classes/RecordList/DatabaseRecordList.php b/typo3/sysext/backend/Classes/RecordList/DatabaseRecordList.php index 0dc453d59e38ed49bb152ad98b853364c1c898e2..960b90b020689cc7d170fbdaffbe17c1da10e078 100644 --- a/typo3/sysext/backend/Classes/RecordList/DatabaseRecordList.php +++ b/typo3/sysext/backend/Classes/RecordList/DatabaseRecordList.php @@ -2678,8 +2678,8 @@ class DatabaseRecordList $urlParameters['sortRev'] = $this->sortRev; } - return (string)$this->uriBuilder->buildUriFromRoute( - $this->request->getAttribute('route')->getOption('_identifier'), + return (string)$this->uriBuilder->buildUriFromRequest( + $this->request, array_replace($urlParameters, $this->overrideUrlParameters) ); } diff --git a/typo3/sysext/backend/Classes/Routing/UriBuilder.php b/typo3/sysext/backend/Classes/Routing/UriBuilder.php index ad1c2df96f36ded4dda1943d933a02b39afcc328..fb19eb3bb1befc98e809a081dae808f124bb7895 100644 --- a/typo3/sysext/backend/Classes/Routing/UriBuilder.php +++ b/typo3/sysext/backend/Classes/Routing/UriBuilder.php @@ -15,10 +15,12 @@ namespace TYPO3\CMS\Backend\Routing; +use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\UriInterface; use Symfony\Component\Routing\Generator\UrlGenerator; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\RequestContext; +use Symfony\Component\Routing\Route as SymfonyRoute; use TYPO3\CMS\Backend\Routing\Exception\MethodNotAllowedException; use TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException; use TYPO3\CMS\Backend\Routing\Exception\RouteTypeNotAllowedException; @@ -123,6 +125,19 @@ class UriBuilder implements SingletonInterface return $this->buildUriFromRoute($name, $parameters, $referenceType); } + /** + * A shorthand function to link to e.g. the same as in the current request, so the internal attribute "route" + * is properly covered and does not need to be exposed all the time. + */ + public function buildUriFromRequest(ServerRequestInterface $request, array $parameters = [], string $referenceType = self::ABSOLUTE_PATH): UriInterface + { + $route = $request->getAttribute('route'); + if (!$route instanceof Route && !$route instanceof SymfonyRoute) { + throw new RouteNotFoundException('No route object was given inside the request object', 1691423325); + } + return $this->buildUriFromRoute($route->getOption('_identifier'), $parameters, $referenceType); + } + /** * Generates a URL or path for a specific route based on the given parameters. * When the route is configured with "access=public" then the token generation is left out. diff --git a/typo3/sysext/backend/Classes/Tree/View/LinkParameterProviderInterface.php b/typo3/sysext/backend/Classes/Tree/View/LinkParameterProviderInterface.php index 3126f0b1fc44e9b30d1621f25eab7442611137f1..9804ee6d352b4427a90a0777b046c611d4d31582 100644 --- a/typo3/sysext/backend/Classes/Tree/View/LinkParameterProviderInterface.php +++ b/typo3/sysext/backend/Classes/Tree/View/LinkParameterProviderInterface.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /* * This file is part of the TYPO3 CMS project. * @@ -17,30 +19,11 @@ namespace TYPO3\CMS\Backend\Tree\View; interface LinkParameterProviderInterface { - /** - * Returns the URL of the current script - * - * @return string - */ - public function getScriptUrl(); - /** * Provides an array or GET parameters for URL generation * * @param array $values Array of values to include into the parameters or which might influence the parameters - * * @return string[] Array of parameters which have to be added to URLs */ - public function getUrlParameters(array $values); - - /** - * Check if given value is currently the selected item - * - * This method is only used in the page tree. - * - * @param array $values Values to be checked - * - * @return bool Returns TRUE if the given values match the currently selected item - */ - public function isCurrentlySelectedItem(array $values); + public function getUrlParameters(array $values): array; } diff --git a/typo3/sysext/backend/Classes/View/FolderUtilityRenderer.php b/typo3/sysext/backend/Classes/View/FolderUtilityRenderer.php index 35fd4f8f4f7ec1e569e58ced1bca9381a4c5930e..13aec52c0b04091bd8e4271cb7dec62de42fca6a 100644 --- a/typo3/sysext/backend/Classes/View/FolderUtilityRenderer.php +++ b/typo3/sysext/backend/Classes/View/FolderUtilityRenderer.php @@ -17,6 +17,7 @@ declare(strict_types=1); namespace TYPO3\CMS\Backend\View; +use Psr\Http\Message\ServerRequestInterface; use TYPO3\CMS\Backend\Routing\UriBuilder; use TYPO3\CMS\Backend\Tree\View\LinkParameterProviderInterface; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; @@ -26,7 +27,6 @@ use TYPO3\CMS\Core\Resource\Folder; use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry; use TYPO3\CMS\Core\Resource\Security\FileNameValidator; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Core\Utility\HttpUtility; /** * Renders utility forms used in the views for files/folders of Element and Link Browser @@ -54,7 +54,7 @@ class FolderUtilityRenderer * * @return string HTML for the create folder form. */ - public function createFolder(Folder $folderObject) + public function createFolder(ServerRequestInterface $request, Folder $folderObject) { $lang = $this->getLanguageService(); @@ -77,11 +77,11 @@ class FolderUtilityRenderer . htmlspecialchars($folderObject->getCombinedIdentifier()) . '" />'; // Make footer of upload form, including the submit button: - $redirectValue = $this->parameterProvider->getScriptUrl() . HttpUtility::buildQueryString( + $redirectValue = (string)$this->uriBuilder->buildUriFromRequest( + $request, $this->parameterProvider->getUrlParameters( ['identifier' => $folderObject->getCombinedIdentifier()] - ), - '&' + ) ); $markup[] = '<input type="hidden" name="redirect" value="' . htmlspecialchars($redirectValue) . '" />'; @@ -96,7 +96,7 @@ class FolderUtilityRenderer * * @return string HTML for an upload form. */ - public function uploadForm(Folder $folderObject, ?FileExtensionFilter $fileExtensionFilter = null) + public function uploadForm(ServerRequestInterface $request, Folder $folderObject, ?FileExtensionFilter $fileExtensionFilter = null) { if (!$folderObject->checkActionPermission('write')) { return ''; @@ -140,10 +140,7 @@ class FolderUtilityRenderer $formAction = (string)$this->uriBuilder->buildUriFromRoute('tce_file'); $combinedIdentifier = $folderObject->getCombinedIdentifier(); - $redirectValue = $this->parameterProvider->getScriptUrl() . HttpUtility::buildQueryString( - $this->parameterProvider->getUrlParameters(['identifier' => $combinedIdentifier]), - '&' - ); + $redirectValue = (string)$this->uriBuilder->buildUriFromRequest($request, $this->parameterProvider->getUrlParameters(['identifier' => $combinedIdentifier])); $markup[] = '<form class="pt-3 pb-3" action="' . htmlspecialchars($formAction) . '" method="post" name="editform" enctype="multipart/form-data">'; $markup[] = '<input type="hidden" name="data[upload][0][target]" value="' . htmlspecialchars($combinedIdentifier) . '" />'; $markup[] = '<input type="hidden" name="data[upload][0][data]" value="0" />'; diff --git a/typo3/sysext/backend/Tests/Functional/Routing/UriBuilderTest.php b/typo3/sysext/backend/Tests/Functional/Routing/UriBuilderTest.php index 30e77f118dcaa9d6e7977749cfe4edeeec28fba6..7cc6e318b04f303372fdaadb471de0f212581203 100644 --- a/typo3/sysext/backend/Tests/Functional/Routing/UriBuilderTest.php +++ b/typo3/sysext/backend/Tests/Functional/Routing/UriBuilderTest.php @@ -17,7 +17,10 @@ declare(strict_types=1); namespace TYPO3\CMS\Backend\Tests\Functional\Routing; +use TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException; +use TYPO3\CMS\Backend\Routing\Router; use TYPO3\CMS\Backend\Routing\UriBuilder; +use TYPO3\CMS\Core\Http\ServerRequest; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; @@ -44,7 +47,49 @@ final class UriBuilderTest extends FunctionalTestCase public function buildUriFromRouteResolvesSubModule(): void { $subject = GeneralUtility::makeInstance(UriBuilder::class); - $route = $subject->buildUriFromRoute('site_configuration.edit'); - self::assertStringEndsWith('/module/site/configuration/edit', $route->getPath()); + $uri = $subject->buildUriFromRoute('site_configuration.edit'); + self::assertStringEndsWith('/module/site/configuration/edit', $uri->getPath()); + } + + /** + * @test + */ + public function buildUriFromRequestCanLinkToValidRoute(): void + { + $subject = GeneralUtility::makeInstance(UriBuilder::class); + $route = GeneralUtility::makeInstance(Router::class)->getRoute('site_configuration.edit'); + $route->setOption('_identifier', 'site_configuration.edit'); + $request = new ServerRequest('https://example.com/', 'GET'); + $request = $request->withAttribute('route', $route); + $uri = $subject->buildUriFromRequest($request, ['foo' => 'bar']); + self::assertStringEndsWith('/module/site/configuration/edit', $uri->getPath()); + } + + /** + * @test + */ + public function buildUriFromRequestWithInvalidRouteThrowsException(): void + { + self::expectException(RouteNotFoundException::class); + self::expectExceptionCode(1476050190); + $subject = GeneralUtility::makeInstance(UriBuilder::class); + $route = GeneralUtility::makeInstance(Router::class)->getRoute('site_configuration.edit'); + $request = new ServerRequest('https://example.com/', 'GET'); + // Route is not found in the registry of routes + $route->setOption('_identifier', 'foo.bar'); + $request = $request->withAttribute('route', $route); + $subject->buildUriFromRequest($request, ['foo' => 'bar']); + } + + /** + * @test + */ + public function buildUriFromRequestWithoutRouteThrowsException(): void + { + self::expectException(RouteNotFoundException::class); + self::expectExceptionCode(1691423325); + $subject = GeneralUtility::makeInstance(UriBuilder::class); + $request = new ServerRequest('https://example.com/', 'GET'); + $subject->buildUriFromRequest($request, ['foo' => 'bar']); } } diff --git a/typo3/sysext/core/Documentation/Changelog/13.0/Breaking-101612-LinkParameterProviderInterfaceChanged.rst b/typo3/sysext/core/Documentation/Changelog/13.0/Breaking-101612-LinkParameterProviderInterfaceChanged.rst new file mode 100644 index 0000000000000000000000000000000000000000..fd7c3ff608733a737e0f5d89c4317fa850c8e521 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/13.0/Breaking-101612-LinkParameterProviderInterfaceChanged.rst @@ -0,0 +1,49 @@ +.. include:: /Includes.rst.txt + +.. _breaking-101612-1691447955: + +=========================================================== +Breaking: #101612 - LinkParameterProvider Interface changed +=========================================================== + +See :issue:`101612` + +Description +=========== + +The PHP interface :php:`TYPO3\CMS\Backend\Tree\View\LinkParameterProviderInterface` +has changed. The interface is used to generate URLs with query parameters for links +within Element Browsers or Link Browsers in the TYPO3 Backend. + +The methods :php:`getScriptUrl()` and :php:`isCurrentlySelectedItem()` have been removed +from the interface, as the implementing Link Browsers do not need this information anymore +due to simplification in routing. + +The method :php:`getUrlParameters()` now has a native return type :php:`array`, whereas +previously this was only type-hinted. + + +Impact +====== + +When accessing implementing PHP objects, it should be noted that these methods do not +exist anymore. When called this might result in fatal PHP errors. + +When implementing the PHP interface, the implementing code will fail due to missing return +types. + + +Affected installations +====================== + +TYPO3 installations with custom implementations of this interface. + + +Migration +========= + +For extensions implementing the interface, the return type for :php:`getUrlParameters()` +can be added in order to be TYPO3 v12+ compatible. For v13-only compatibility, +it is recommended to remove the superfluous methods. + +.. index:: PHP-API, PartiallyScanned, ext:backend \ No newline at end of file diff --git a/typo3/sysext/core/Documentation/Changelog/13.0/Feature-101612-UriBuilder-buildUriFromRequest.rst b/typo3/sysext/core/Documentation/Changelog/13.0/Feature-101612-UriBuilder-buildUriFromRequest.rst new file mode 100644 index 0000000000000000000000000000000000000000..f45e1dfcb707d99228e362e818931c0fa7dc58ae --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/13.0/Feature-101612-UriBuilder-buildUriFromRequest.rst @@ -0,0 +1,28 @@ +.. include:: /Includes.rst.txt + +.. _feature-101612-1691425003: + +================================================== +Feature: #101612 - UriBuilder->buildUriFromRequest +================================================== + +See :issue:`101612` + +Description +=========== + +A new method within :php:`TYPO3\CMS\Backend\Routing\UriBuilder` named `buildUriFromRequest` is added which allows to generate a URL to a backend route of this +request. + + +Impact +====== + +This is typically useful when linking to the current route or module in the TYPO3 Backend for +extension authors to avoid internals with any PSR-7 Request Attribute. + +Usage within a PHP module controller in the TYPO3 Backend Context + +: :php:`$this->uriBuilder->buildUriFromRequest($request, ['id' => $id]);` + +.. index:: Backend, PHP-API, ext:backend \ No newline at end of file diff --git a/typo3/sysext/filelist/Classes/ElementBrowser/AbstractResourceBrowser.php b/typo3/sysext/filelist/Classes/ElementBrowser/AbstractResourceBrowser.php index 003a4be97b2c126b81ce0bbb5e543556f5db6087..6bcdabf26647b91aa5f2034e9f03d99283855ecd 100644 --- a/typo3/sysext/filelist/Classes/ElementBrowser/AbstractResourceBrowser.php +++ b/typo3/sysext/filelist/Classes/ElementBrowser/AbstractResourceBrowser.php @@ -18,7 +18,6 @@ namespace TYPO3\CMS\Filelist\ElementBrowser; use Psr\Http\Message\ServerRequestInterface; use TYPO3\CMS\Backend\ElementBrowser\AbstractElementBrowser; use TYPO3\CMS\Backend\ElementBrowser\ElementBrowserInterface; -use TYPO3\CMS\Backend\Routing\Route; use TYPO3\CMS\Backend\Template\Components\Buttons\ButtonInterface; use TYPO3\CMS\Backend\Template\Components\Buttons\DropDown\DropDownDivider; use TYPO3\CMS\Backend\Template\Components\Buttons\DropDown\DropDownItemInterface; @@ -26,13 +25,10 @@ use TYPO3\CMS\Backend\Template\Components\Buttons\DropDown\DropDownRadio; use TYPO3\CMS\Backend\Template\Components\Buttons\DropDown\DropDownToggle; use TYPO3\CMS\Backend\Template\Components\Buttons\DropDownButton; use TYPO3\CMS\Backend\Tree\View\LinkParameterProviderInterface; -use TYPO3\CMS\Core\Core\Environment; use TYPO3\CMS\Core\Resource\Exception\FolderDoesNotExistException; use TYPO3\CMS\Core\Resource\Folder; use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Core\Utility\HttpUtility; -use TYPO3\CMS\Core\Utility\PathUtility; use TYPO3\CMS\Filelist\FileList; use TYPO3\CMS\Filelist\Matcher\Matcher; use TYPO3\CMS\Filelist\Type\ViewMode; @@ -153,34 +149,28 @@ abstract class AbstractResourceBrowser extends AbstractElementBrowser implements } /** - * @param array $parameters Array of values to include into the parameters + * @param array $values Array of values to include into the parameters * @return string[] Array of parameters which have to be added to URLs */ - public function getUrlParameters(array $parameters): array + public function getUrlParameters(array $values): array { - $parameters = array_replace_recursive([ + $values = array_replace_recursive([ 'mode' => $this->identifier, - 'expandFolder' => $parameters['identifier'] ?? $this->expandFolder, + 'expandFolder' => $values['identifier'] ?? $this->expandFolder, 'bparams' => $this->bparams, - ], $parameters); + ], $values); - $parameters = array_filter($parameters, static function ($value) { + $values = array_filter($values, static function ($value) { return $value !== null && trim($value) !== ''; }); - return $parameters; + return $values; } protected function createUri(array $parameters = []): string { $parameters = $this->getUrlParameters($parameters); - if (($route = $this->getRequest()->getAttribute('route')) instanceof Route) { - $scriptUrl = (string)$this->uriBuilder->buildUriFromRoute($route->getOption('_identifier'), $parameters); - } else { - $scriptUrl = ($this->thisScript ?: PathUtility::basename(Environment::getCurrentScript())) . HttpUtility::buildQueryString($parameters, '&'); - } - - return $scriptUrl; + return (string)$this->uriBuilder->buildUriFromRequest($this->getRequest(), $parameters); } /** @@ -200,14 +190,4 @@ abstract class AbstractResourceBrowser extends AbstractElementBrowser implements } return [$data, $store]; } - - public function isCurrentlySelectedItem(array $values): bool - { - return false; - } - - public function getScriptUrl(): string - { - return $this->thisScript; - } } diff --git a/typo3/sysext/filelist/Classes/ElementBrowser/CreateFolderBrowser.php b/typo3/sysext/filelist/Classes/ElementBrowser/CreateFolderBrowser.php index 998034b7025c5bdb88db6b2116c224a0fcbd7550..6ee3d56f0922c1464e53926eece4962fc3014f0e 100644 --- a/typo3/sysext/filelist/Classes/ElementBrowser/CreateFolderBrowser.php +++ b/typo3/sysext/filelist/Classes/ElementBrowser/CreateFolderBrowser.php @@ -57,7 +57,7 @@ class CreateFolderBrowser extends AbstractResourceBrowser // Build the folder creation form $folderUtilityRenderer = GeneralUtility::makeInstance(FolderUtilityRenderer::class, $this); - $markup[] = $folderUtilityRenderer->createFolder($this->selectedFolder); + $markup[] = $folderUtilityRenderer->createFolder($this->getRequest(), $this->selectedFolder); // Create the filelist header bar $markup[] = '<div class="row justify-content-between mb-2">'; diff --git a/typo3/sysext/filelist/Classes/ElementBrowser/FileBrowser.php b/typo3/sysext/filelist/Classes/ElementBrowser/FileBrowser.php index b38bd348517904ce4eefe8a60aab905bbd3fe65d..bc3421c57e5bb71c4a496fe01d6476c9a39f08aa 100644 --- a/typo3/sysext/filelist/Classes/ElementBrowser/FileBrowser.php +++ b/typo3/sysext/filelist/Classes/ElementBrowser/FileBrowser.php @@ -135,8 +135,8 @@ class FileBrowser extends AbstractResourceBrowser // Build the file upload and folder creation form $folderUtilityRenderer = GeneralUtility::makeInstance(FolderUtilityRenderer::class, $this); - $markup[] = $folderUtilityRenderer->uploadForm($this->selectedFolder, $this->fileExtensionFilter); - $markup[] = $folderUtilityRenderer->createFolder($this->selectedFolder); + $markup[] = $folderUtilityRenderer->uploadForm($this->getRequest(), $this->selectedFolder, $this->fileExtensionFilter); + $markup[] = $folderUtilityRenderer->createFolder($this->getRequest(), $this->selectedFolder); $contentHtml = implode('', $markup); } diff --git a/typo3/sysext/filelist/Classes/ElementBrowser/FolderBrowser.php b/typo3/sysext/filelist/Classes/ElementBrowser/FolderBrowser.php index 3fe0fac44f7fcd7754e207f8c9304a1665380287..a2ba4caa41ee11ad1b9ee72f0a9b3da6bcc00ccf 100644 --- a/typo3/sysext/filelist/Classes/ElementBrowser/FolderBrowser.php +++ b/typo3/sysext/filelist/Classes/ElementBrowser/FolderBrowser.php @@ -90,7 +90,7 @@ class FolderBrowser extends AbstractResourceBrowser // Build the folder creation form $folderUtilityRenderer = GeneralUtility::makeInstance(FolderUtilityRenderer::class, $this); - $markup[] = $folderUtilityRenderer->createFolder($this->selectedFolder); + $markup[] = $folderUtilityRenderer->createFolder($this->getRequest(), $this->selectedFolder); $contentHtml = implode('', $markup); } diff --git a/typo3/sysext/filelist/Classes/FileList.php b/typo3/sysext/filelist/Classes/FileList.php index 8040a1a1c264a011bf048c9f461b7e6cbe4ab38d..4be12d3b72e82a3f7b8cf8ff9425655ae1f4b6f8 100644 --- a/typo3/sysext/filelist/Classes/FileList.php +++ b/typo3/sysext/filelist/Classes/FileList.php @@ -1474,7 +1474,7 @@ class FileList return (is_array($value) && $value !== []) || (trim((string)$value) !== ''); }); - return (string)$this->uriBuilder->buildUriFromRoute($route->getOption('_identifier'), $params); + return (string)$this->uriBuilder->buildUriFromRequest($request, $params); } protected function createEditDataUriForResource(ResourceInterface $resource): ?string diff --git a/typo3/sysext/filelist/Classes/LinkHandler/AbstractResourceLinkHandler.php b/typo3/sysext/filelist/Classes/LinkHandler/AbstractResourceLinkHandler.php index 06665c551658c427ba228cc0c82723dbc9deb11a..7236d953b0b287f057a4266d69c5bbd6e74c9a56 100644 --- a/typo3/sysext/filelist/Classes/LinkHandler/AbstractResourceLinkHandler.php +++ b/typo3/sysext/filelist/Classes/LinkHandler/AbstractResourceLinkHandler.php @@ -20,7 +20,6 @@ use TYPO3\CMS\Backend\Controller\AbstractLinkBrowserController; use TYPO3\CMS\Backend\LinkHandler\LinkHandlerInterface; use TYPO3\CMS\Backend\LinkHandler\LinkHandlerVariableProviderInterface; use TYPO3\CMS\Backend\LinkHandler\LinkHandlerViewProviderInterface; -use TYPO3\CMS\Backend\Routing\Route; use TYPO3\CMS\Backend\Routing\UriBuilder; use TYPO3\CMS\Backend\Template\Components\Buttons\ButtonInterface; use TYPO3\CMS\Backend\Template\Components\Buttons\DropDown\DropDownDivider; @@ -31,7 +30,6 @@ use TYPO3\CMS\Backend\Template\Components\Buttons\DropDownButton; use TYPO3\CMS\Backend\Tree\View\LinkParameterProviderInterface; use TYPO3\CMS\Backend\View\BackendViewFactory; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; -use TYPO3\CMS\Core\Core\Environment; use TYPO3\CMS\Core\Imaging\IconFactory; use TYPO3\CMS\Core\LinkHandling\LinkService; use TYPO3\CMS\Core\Localization\LanguageService; @@ -42,8 +40,6 @@ use TYPO3\CMS\Core\Resource\File; use TYPO3\CMS\Core\Resource\Folder; use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Core\Utility\HttpUtility; -use TYPO3\CMS\Core\Utility\PathUtility; use TYPO3\CMS\Core\View\ViewInterface; use TYPO3\CMS\Filelist\FileList; use TYPO3\CMS\Filelist\Matcher\Matcher; @@ -190,11 +186,6 @@ abstract class AbstractResourceLinkHandler implements LinkHandlerInterface, Link $this->filelist->thumbs = ($GLOBALS['TYPO3_CONF_VARS']['GFX']['thumbnails'] ?? false) && $this->displayThumbs; } - public function isCurrentlySelectedItem(array $values): bool - { - return false; - } - public function modifyLinkAttributes(array $fieldDefinitions): array { return $fieldDefinitions; @@ -205,11 +196,6 @@ abstract class AbstractResourceLinkHandler implements LinkHandlerInterface, Link return true; } - public function getScriptUrl(): string - { - return $this->linkBrowser->getScriptUrl(); - } - /** * @return string[] Array of body-tag attributes */ @@ -228,14 +214,7 @@ abstract class AbstractResourceLinkHandler implements LinkHandlerInterface, Link protected function createUri(ServerRequestInterface $request, array $parameters = []): string { - $parameters = $this->getUrlParameters($parameters); - if (($route = $request->getAttribute('route')) instanceof Route) { - $scriptUrl = (string)$this->uriBuilder->buildUriFromRoute($route->getOption('_identifier'), $parameters); - } else { - $scriptUrl = ($this->linkBrowser->getScriptUrl() ?: PathUtility::basename(Environment::getCurrentScript())) . HttpUtility::buildQueryString($parameters, '&'); - } - - return $scriptUrl; + return (string)$this->uriBuilder->buildUriFromRequest($request, $this->getUrlParameters($parameters)); } protected function getViewModeButton(ServerRequestInterface $request): ButtonInterface @@ -270,13 +249,13 @@ abstract class AbstractResourceLinkHandler implements LinkHandlerInterface, Link return $viewModeButton; } - public function getUrlParameters(array $parameters): array + public function getUrlParameters(array $values): array { - $parameters = array_replace_recursive([ - 'expandFolder' => $parameters['identifier'] ?? $this->expandFolder, - ], $parameters); + $values = array_replace_recursive([ + 'expandFolder' => $values['identifier'] ?? $this->expandFolder, + ], $values); - return array_merge($this->linkBrowser->getUrlParameters($parameters), $parameters); + return array_merge($this->linkBrowser->getUrlParameters($values), $values); } protected function getLanguageService(): LanguageService diff --git a/typo3/sysext/filelist/Classes/LinkHandler/FileLinkHandler.php b/typo3/sysext/filelist/Classes/LinkHandler/FileLinkHandler.php index 41c1c6a6fbbcd65cb4ed20cba740b380d6086fd3..b6ae2d4e957c00db467cb1e0404fbf224643e7c1 100644 --- a/typo3/sysext/filelist/Classes/LinkHandler/FileLinkHandler.php +++ b/typo3/sysext/filelist/Classes/LinkHandler/FileLinkHandler.php @@ -94,8 +94,8 @@ class FileLinkHandler extends AbstractResourceLinkHandler // Build the file upload and folder creation form $folderUtilityRenderer = GeneralUtility::makeInstance(FolderUtilityRenderer::class, $this); - $markup[] = $folderUtilityRenderer->uploadForm($this->selectedFolder); - $markup[] = $folderUtilityRenderer->createFolder($this->selectedFolder); + $markup[] = $folderUtilityRenderer->uploadForm($request, $this->selectedFolder); + $markup[] = $folderUtilityRenderer->createFolder($request, $this->selectedFolder); $contentHtml = implode(PHP_EOL, $markup); } diff --git a/typo3/sysext/filelist/Classes/LinkHandler/FolderLinkHandler.php b/typo3/sysext/filelist/Classes/LinkHandler/FolderLinkHandler.php index a9a346cbd1214d346331d4db972029074e47a9aa..cee44a15e083b2152bdb842a8b5573960863a960 100644 --- a/typo3/sysext/filelist/Classes/LinkHandler/FolderLinkHandler.php +++ b/typo3/sysext/filelist/Classes/LinkHandler/FolderLinkHandler.php @@ -81,7 +81,7 @@ class FolderLinkHandler extends AbstractResourceLinkHandler // Build the file upload and folder creation form $folderUtilityRenderer = GeneralUtility::makeInstance(FolderUtilityRenderer::class, $this); - $markup[] = $folderUtilityRenderer->createFolder($this->selectedFolder); + $markup[] = $folderUtilityRenderer->createFolder($request, $this->selectedFolder); $contentHtml = implode(PHP_EOL, $markup); } diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php index f097ca6a551c62b3b1d418a51c7fd6b44e8fcced..2e2a8c128e5d8a23f48cbeacf8d2d15412d8fa36 100644 --- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php +++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php @@ -5842,4 +5842,18 @@ return [ 'Deprecation-101475-IconSizeStringConstants.rst', ], ], + 'TYPO3\CMS\Backend\Tree\View\LinkParameterProviderInterface->getScriptUrl' => [ + 'numberOfMandatoryArguments' => 0, + 'maximumNumberOfArguments' => 0, + 'restFiles' => [ + 'Breaking-101612-LinkParameterProviderInterfaceChanged.rst', + ], + ], + 'TYPO3\CMS\Backend\Tree\View\LinkParameterProviderInterface->isCurrentlySelectedItem' => [ + 'numberOfMandatoryArguments' => 1, + 'maximumNumberOfArguments' => 1, + 'restFiles' => [ + 'Breaking-101612-LinkParameterProviderInterfaceChanged.rst', + ], + ], ];