From 9618006aeeb7058c23cdfb1f5a9f01bd4d9958ed Mon Sep 17 00:00:00 2001 From: Benni Mack <benni@typo3.org> Date: Fri, 18 Jan 2019 20:18:37 +0100 Subject: [PATCH] [!!!][TASK] Build strict PSR-15 middlewares All PSR-15 middlewares now do not set the $GLOBALS['TYPO3_REQUEST'] object anymore. Instead, the RequestHandlers are using them for all other logic (e.g. GP etc) where the request object or any other attribute has not been handed in yet. It is now safe to say that PSR-7 request/response objects have to be used within middlewares to access or manipulate GET/POST data. Also, the safety net for overriding GET/POST again is still in place for FE (data = GP:id) in order for existing TypoScript to work still, until all other code gets global-free. There are still places in TYPO3 Core where $TYPO3_REQUEST is necessary (TypoScriptConditionMatcher, Error Handling) which are added accordingly. Resolves: #87661 Releases: master Change-Id: Ibe499b6fda86ccd3abefcb3c8be294a7cb765d74 Reviewed-on: https://review.typo3.org/59490 Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Tested-by: TYPO3com <noreply@typo3.com> Reviewed-by: Georg Ringer <georg.ringer@gmail.com> Tested-by: Georg Ringer <georg.ringer@gmail.com> --- .../backend/Classes/Http/RequestHandler.php | 34 +++- .../Classes/Middleware/SiteResolver.php | 1 - .../Middleware/NormalizedParamsAttribute.php | 6 - ...g-87193-DeprecatedFunctionalityRemoved.rst | 1 + .../frontend/Classes/Http/RequestHandler.php | 40 +---- .../Middleware/FrontendUserAuthenticator.php | 2 - .../Classes/Middleware/PageResolver.php | 7 +- .../PrepareTypoScriptFrontendRendering.php | 15 +- .../Middleware/PreprocessRequestHook.php | 50 ------ .../Classes/Middleware/SiteResolver.php | 5 - .../TypoScriptFrontendInitialization.php | 13 +- .../Configuration/RequestMiddlewares.php | 9 +- .../Tests/Unit/Http/RequestHandlerTest.php | 147 ------------------ 13 files changed, 52 insertions(+), 278 deletions(-) delete mode 100644 typo3/sysext/frontend/Classes/Middleware/PreprocessRequestHook.php diff --git a/typo3/sysext/backend/Classes/Http/RequestHandler.php b/typo3/sysext/backend/Classes/Http/RequestHandler.php index d117e393d907..469b5164a557 100644 --- a/typo3/sysext/backend/Classes/Http/RequestHandler.php +++ b/typo3/sysext/backend/Classes/Http/RequestHandler.php @@ -19,6 +19,7 @@ use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; use TYPO3\CMS\Backend\Routing\Exception\InvalidRequestTokenException; +use TYPO3\CMS\Backend\Routing\UriBuilder; use TYPO3\CMS\Backend\Template\DocumentTemplate; use TYPO3\CMS\Core\Http\RedirectResponse; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -35,6 +36,32 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; */ class RequestHandler implements RequestHandlerInterface { + /** + * Sets the global GET and POST to the values, so if people access $_GET and $_POST + * Within hooks starting NOW (e.g. cObject), they get the "enriched" data from query params. + * + * This needs to be run after the request object has been enriched with modified GET/POST variables. + * + * @param ServerRequestInterface $request + * @internal this safety net will be removed in TYPO3 v10.0. + */ + protected function resetGlobalsToCurrentRequest(ServerRequestInterface $request) + { + if ($request->getQueryParams() !== $_GET) { + $queryParams = $request->getQueryParams(); + $_GET = $queryParams; + $GLOBALS['HTTP_GET_VARS'] = $_GET; + } + if ($request->getMethod() === 'POST') { + $parsedBody = $request->getParsedBody(); + if (is_array($parsedBody) && $parsedBody !== $_POST) { + $_POST = $parsedBody; + $GLOBALS['HTTP_POST_VARS'] = $_POST; + } + } + $GLOBALS['TYPO3_REQUEST'] = $request; + } + /** * Handles a backend request, after finishing running middlewares * Dispatch the request to the appropriate controller through the @@ -49,14 +76,17 @@ class RequestHandler implements RequestHandlerInterface // PageRenderer (= which is a singleton) to populate Backend Styles from TBE_STYLES // which should be built only if necessary, but currently done all over the place. GeneralUtility::makeInstance(DocumentTemplate::class); + // safety net to have the fully-added request object globally available as long as + // there are Core classes that need the Request object but do not get it handed in + $this->resetGlobalsToCurrentRequest($request); try { // Check if the router has the available route and dispatch. $dispatcher = GeneralUtility::makeInstance(RouteDispatcher::class); return $dispatcher->dispatch($request); } catch (InvalidRequestTokenException $e) { // When token was invalid redirect to login - $url = GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir; - return new RedirectResponse($url); + $loginPage = GeneralUtility::makeInstance(UriBuilder::class)->buildUriFromRoute('login'); + return new RedirectResponse((string)$loginPage); } } } diff --git a/typo3/sysext/backend/Classes/Middleware/SiteResolver.php b/typo3/sysext/backend/Classes/Middleware/SiteResolver.php index 328ccb545840..9d601f9b2ec5 100644 --- a/typo3/sysext/backend/Classes/Middleware/SiteResolver.php +++ b/typo3/sysext/backend/Classes/Middleware/SiteResolver.php @@ -54,7 +54,6 @@ class SiteResolver implements MiddlewareInterface } $site = GeneralUtility::makeInstance(SiteMatcher::class)->matchByPageId($pageId, $rootLine); $request = $request->withAttribute('site', $site); - $GLOBALS['TYPO3_REQUEST'] = $request; } return $handler->handle($request); } diff --git a/typo3/sysext/core/Classes/Middleware/NormalizedParamsAttribute.php b/typo3/sysext/core/Classes/Middleware/NormalizedParamsAttribute.php index e0e9358d0b94..f1496bdb5d30 100644 --- a/typo3/sysext/core/Classes/Middleware/NormalizedParamsAttribute.php +++ b/typo3/sysext/core/Classes/Middleware/NormalizedParamsAttribute.php @@ -49,12 +49,6 @@ class NormalizedParamsAttribute implements MiddlewareInterface Environment::getPublicPath() ) ); - - // Set $request as global variable. This is needed in a transition phase until core code has been - // refactored to have ServerRequest object available where it is needed. This global will be - // deprecated then and removed. - $GLOBALS['TYPO3_REQUEST'] = $request; - return $handler->handle($request); } } diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-87193-DeprecatedFunctionalityRemoved.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-87193-DeprecatedFunctionalityRemoved.rst index b1f158928c78..3614a90ba22e 100644 --- a/typo3/sysext/core/Documentation/Changelog/master/Breaking-87193-DeprecatedFunctionalityRemoved.rst +++ b/typo3/sysext/core/Documentation/Changelog/master/Breaking-87193-DeprecatedFunctionalityRemoved.rst @@ -1431,6 +1431,7 @@ The following features have been removed: * EXT:form: renderingOptions._isHiddenFormElement and renderingOptions._isReadOnlyFormElement are dropped * :php:`$TBE_MODULES`: configuring a module via a custom "configureModuleFunction" is dropped * CLI Command alias "lang:language:update" is dropped in favor of "language:update" +* Accessing or modifying $_GET/$_POST parameters during any PSR-15 middleware will not reflect any change during the actual Request processing anymore as it is overridden by the incoming PSR-7 request object, but overriden again when the RequestHandler is accessed The following database tables have been removed: diff --git a/typo3/sysext/frontend/Classes/Http/RequestHandler.php b/typo3/sysext/frontend/Classes/Http/RequestHandler.php index 59cbdf765b0c..f74176df93d4 100644 --- a/typo3/sysext/frontend/Classes/Http/RequestHandler.php +++ b/typo3/sysext/frontend/Classes/Http/RequestHandler.php @@ -27,7 +27,6 @@ use TYPO3\CMS\Core\Site\Entity\SiteLanguage; use TYPO3\CMS\Core\TimeTracker\TimeTracker; use TYPO3\CMS\Core\Type\File\ImageInfo; use TYPO3\CMS\Core\TypoScript\TypoScriptService; -use TYPO3\CMS\Core\Utility\ArrayUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\PathUtility; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; @@ -63,41 +62,6 @@ class RequestHandler implements RequestHandlerInterface */ protected $timeTracker; - /** - * Puts parameters that have been added or removed from the global _GET or _POST arrays - * into the given request (however, the PSR-7 request information takes precedence). - * - * @param ServerRequestInterface $request - * @return ServerRequestInterface - */ - protected function addModifiedGlobalsToIncomingRequest(ServerRequestInterface $request): ServerRequestInterface - { - $originalGetParameters = $request->getAttribute('_originalGetParameters', null); - if ($originalGetParameters !== null && !empty($_GET) && $_GET !== $originalGetParameters) { - // Find out what has been changed. - $modifiedGetParameters = ArrayUtility::arrayDiffAssocRecursive($_GET ?? [], $originalGetParameters); - if (!empty($modifiedGetParameters)) { - $queryParams = array_replace_recursive($modifiedGetParameters, $request->getQueryParams()); - $request = $request->withQueryParams($queryParams); - $GLOBALS['TYPO3_REQUEST'] = $request; - $this->timeTracker->setTSlogMessage('GET parameters have been modified during Request building in a hook.'); - } - } - // do same for $_POST if the request is a POST request - $originalPostParameters = $request->getAttribute('_originalPostParameters', null); - if ($request->getMethod() === 'POST' && $originalPostParameters !== null && !empty($_POST) && $_POST !== $originalPostParameters) { - // Find out what has been changed - $modifiedPostParameters = ArrayUtility::arrayDiffAssocRecursive($_POST ?? [], $originalPostParameters); - if (!empty($modifiedPostParameters)) { - $parsedBody = array_replace_recursive($modifiedPostParameters, $request->getParsedBody()); - $request = $request->withParsedBody($parsedBody); - $GLOBALS['TYPO3_REQUEST'] = $request; - $this->timeTracker->setTSlogMessage('POST parameters have been modified during Request building in a hook.'); - } - } - return $request; - } - /** * Sets the global GET and POST to the values, so if people access $_GET and $_POST * Within hooks starting NOW (e.g. cObject), they get the "enriched" data from query params. @@ -121,7 +85,9 @@ class RequestHandler implements RequestHandlerInterface $GLOBALS['HTTP_POST_VARS'] = $_POST; } } + $GLOBALS['TYPO3_REQUEST'] = $request; } + /** * Handles a frontend request, after finishing running middlewares * @@ -135,8 +101,6 @@ class RequestHandler implements RequestHandlerInterface /** @var TypoScriptFrontendController $controller */ $controller = $GLOBALS['TSFE']; - // safety net, will be removed in TYPO3 v10.0. Aligns $_GET/$_POST to the incoming request. - $request = $this->addModifiedGlobalsToIncomingRequest($request); $this->resetGlobalsToCurrentRequest($request); // Generate page diff --git a/typo3/sysext/frontend/Classes/Middleware/FrontendUserAuthenticator.php b/typo3/sysext/frontend/Classes/Middleware/FrontendUserAuthenticator.php index a5f35fe90c9e..15293abf3719 100644 --- a/typo3/sysext/frontend/Classes/Middleware/FrontendUserAuthenticator.php +++ b/typo3/sysext/frontend/Classes/Middleware/FrontendUserAuthenticator.php @@ -99,8 +99,6 @@ class FrontendUserAuthenticator implements MiddlewareInterface $cookieParams = $request->getCookieParams(); $cookieParams[$cookieName] = $sessionId; $request = $request->withCookieParams($cookieParams); - // @deprecated: we override the current request because it was enriched by cookie information here. - $GLOBALS['TYPO3_REQUEST'] = $request; $frontendUser->forceSetCookie = true; $frontendUser->dontSetCookie = false; } diff --git a/typo3/sysext/frontend/Classes/Middleware/PageResolver.php b/typo3/sysext/frontend/Classes/Middleware/PageResolver.php index 4d782af296db..508ad4b1ca21 100644 --- a/typo3/sysext/frontend/Classes/Middleware/PageResolver.php +++ b/typo3/sysext/frontend/Classes/Middleware/PageResolver.php @@ -132,12 +132,11 @@ class PageResolver implements MiddlewareInterface $queryParams = array_replace_recursive($request->getQueryParams(), $pageArguments->getArguments()); $request = $request->withQueryParams($queryParams); $this->controller->setPageArguments($pageArguments); - - // At this point, we later get further route modifiers - // for bw-compat we update $GLOBALS[TYPO3_REQUEST] to be used later in TSFE. - $GLOBALS['TYPO3_REQUEST'] = $request; } + // as long as TSFE throws errors with the global object, this needs to be set, but + // should be removed later-on + $GLOBALS['TYPO3_REQUEST'] = $request; $this->controller->determineId(); // No access? Then remove user & Re-evaluate the page-id diff --git a/typo3/sysext/frontend/Classes/Middleware/PrepareTypoScriptFrontendRendering.php b/typo3/sysext/frontend/Classes/Middleware/PrepareTypoScriptFrontendRendering.php index 8452c9cff86c..fb0b0a71f6d0 100644 --- a/typo3/sysext/frontend/Classes/Middleware/PrepareTypoScriptFrontendRendering.php +++ b/typo3/sysext/frontend/Classes/Middleware/PrepareTypoScriptFrontendRendering.php @@ -60,6 +60,9 @@ class PrepareTypoScriptFrontendRendering implements MiddlewareInterface */ public function process(ServerRequestInterface $request, PsrRequestHandlerInterface $handler): ResponseInterface { + // as long as TSFE throws errors with the global object, this needs to be set, but + // should be removed later-on once TypoScript Condition Matcher is built with the current request object. + $GLOBALS['TYPO3_REQUEST'] = $request; // Get from cache $this->timeTracker->push('Get Page from cache'); // Locks may be acquired here @@ -84,7 +87,6 @@ class PrepareTypoScriptFrontendRendering implements MiddlewareInterface ArrayUtility::mergeRecursiveWithOverrule($modifiedGetVars, $request->getQueryParams()); } $request = $request->withQueryParams($modifiedGetVars); - $GLOBALS['TYPO3_REQUEST'] = $request; } // Setting language and locale @@ -94,13 +96,12 @@ class PrepareTypoScriptFrontendRendering implements MiddlewareInterface $this->timeTracker->pull(); // Convert POST data to utf-8 for internal processing if metaCharset is different - if ($this->controller->metaCharset !== 'utf-8' && is_array($_POST) && !empty($_POST)) { - $this->convertCharsetRecursivelyToUtf8($_POST, $this->controller->metaCharset); - $GLOBALS['HTTP_POST_VARS'] = $_POST; + if ($this->controller->metaCharset !== 'utf-8' && $request->getMethod() === 'POST') { $parsedBody = $request->getParsedBody(); - $this->convertCharsetRecursivelyToUtf8($parsedBody, $this->controller->metaCharset); - $request = $request->withParsedBody($parsedBody); - $GLOBALS['TYPO3_REQUEST'] = $request; + if (is_array($parsedBody) && !empty($parsedBody)) { + $this->convertCharsetRecursivelyToUtf8($parsedBody, $this->controller->metaCharset); + $request = $request->withParsedBody($parsedBody); + } } return $handler->handle($request); } diff --git a/typo3/sysext/frontend/Classes/Middleware/PreprocessRequestHook.php b/typo3/sysext/frontend/Classes/Middleware/PreprocessRequestHook.php deleted file mode 100644 index 9f224788b90a..000000000000 --- a/typo3/sysext/frontend/Classes/Middleware/PreprocessRequestHook.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -declare(strict_types = 1); -namespace TYPO3\CMS\Frontend\Middleware; - -/* - * This file is part of the TYPO3 CMS project. - * - * It is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, either version 2 - * of the License, or any later version. - * - * For the full copyright and license information, please read the - * LICENSE.txt file that was distributed with this source code. - * - * The TYPO3 project - inspiring people to share! - */ - -use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\ServerRequestInterface; -use Psr\Http\Server\MiddlewareInterface; -use Psr\Http\Server\RequestHandlerInterface; - -/** - * Calls a hook before processing a request for the TYPO3 Frontend. - * - * @internal - * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0. - */ -class PreprocessRequestHook implements MiddlewareInterface -{ - - /** - * Hook to preprocess the current request - * - * @param ServerRequestInterface $request - * @param RequestHandlerInterface $handler - * @return ResponseInterface - */ - public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface - { - // Legacy functionality to check if any hook modified global GET/POST - // This is a safety net, see RequestHandler for how this is validated. - // This information is just a compat layer which will be removed in TYPO3 v10.0. - $request = $request->withAttribute('_originalGetParameters', $_GET); - if ($request->getMethod() === 'POST') { - $request = $request->withAttribute('_originalPostParameters', $_POST); - } - return $handler->handle($request); - } -} diff --git a/typo3/sysext/frontend/Classes/Middleware/SiteResolver.php b/typo3/sysext/frontend/Classes/Middleware/SiteResolver.php index 7f5d60febe2c..8423e557af44 100644 --- a/typo3/sysext/frontend/Classes/Middleware/SiteResolver.php +++ b/typo3/sysext/frontend/Classes/Middleware/SiteResolver.php @@ -60,11 +60,6 @@ class SiteResolver implements MiddlewareInterface $request = $request->withAttribute('site', $routeResult->getSite()); $request = $request->withAttribute('language', $routeResult->getLanguage()); $request = $request->withAttribute('routing', $routeResult); - - // At this point, we later get further route modifiers - // for bw-compat we update $GLOBALS[TYPO3_REQUEST] to be used later in TSFE. - $GLOBALS['TYPO3_REQUEST'] = $request; - return $handler->handle($request); } } diff --git a/typo3/sysext/frontend/Classes/Middleware/TypoScriptFrontendInitialization.php b/typo3/sysext/frontend/Classes/Middleware/TypoScriptFrontendInitialization.php index b83d686a5712..7ccf12b8a528 100644 --- a/typo3/sysext/frontend/Classes/Middleware/TypoScriptFrontendInitialization.php +++ b/typo3/sysext/frontend/Classes/Middleware/TypoScriptFrontendInitialization.php @@ -32,9 +32,6 @@ use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; * Creates an instance of TypoScriptFrontendController and makes this globally available * via $GLOBALS['TSFE']. * - * For now, GeneralUtility::_GP() is used in favor of $request->getQueryParams() due to - * hooks who could have $_GET/$_POST modified before. - * * @internal this middleware might get removed in TYPO3 v10.0. */ class TypoScriptFrontendInitialization implements MiddlewareInterface, LoggerAwareInterface @@ -54,14 +51,14 @@ class TypoScriptFrontendInitialization implements MiddlewareInterface, LoggerAwa $GLOBALS['TSFE'] = GeneralUtility::makeInstance( TypoScriptFrontendController::class, null, - GeneralUtility::_GP('id'), - GeneralUtility::_GP('type'), + $request->getParsedBody()['id'] ?? $request->getQueryParams()['id'] ?? 0, + $request->getParsedBody()['type'] ?? $request->getQueryParams()['type'] ?? 0, null, - GeneralUtility::_GP('cHash'), + $request->getParsedBody()['cHash'] ?? $request->getQueryParams()['cHash'] ?? '', null, - GeneralUtility::_GP('MP') + $request->getParsedBody()['MP'] ?? $request->getQueryParams()['MP'] ?? '' ); - if (GeneralUtility::_GP('no_cache')) { + if ($request->getParsedBody()['no_cache'] ?? $request->getQueryParams()['no_cache'] ?? false) { $GLOBALS['TSFE']->set_no_cache('&no_cache=1 has been supplied, so caching is disabled! URL: "' . (string)$request->getUri() . '"'); } diff --git a/typo3/sysext/frontend/Configuration/RequestMiddlewares.php b/typo3/sysext/frontend/Configuration/RequestMiddlewares.php index b0f6a662e50e..bf043ef2cd1a 100644 --- a/typo3/sysext/frontend/Configuration/RequestMiddlewares.php +++ b/typo3/sysext/frontend/Configuration/RequestMiddlewares.php @@ -23,17 +23,10 @@ return [ ] ], /** internal: do not use or reference this middleware in your own code, as this will be possibly be removed */ - 'typo3/cms-frontend/preprocessing' => [ - 'target' => \TYPO3\CMS\Frontend\Middleware\PreprocessRequestHook::class, - 'after' => [ - 'typo3/cms-core/normalized-params-attribute', - ] - ], - /** internal: do not use or reference this middleware in your own code, as this will be possibly be removed */ 'typo3/cms-frontend/eid' => [ 'target' => \TYPO3\CMS\Frontend\Middleware\EidHandler::class, 'after' => [ - 'typo3/cms-frontend/preprocessing' + 'typo3/cms-core/normalized-params-attribute', ] ], 'typo3/cms-frontend/maintenance-mode' => [ diff --git a/typo3/sysext/frontend/Tests/Unit/Http/RequestHandlerTest.php b/typo3/sysext/frontend/Tests/Unit/Http/RequestHandlerTest.php index 784d11449f30..4590cdc42ae9 100644 --- a/typo3/sysext/frontend/Tests/Unit/Http/RequestHandlerTest.php +++ b/typo3/sysext/frontend/Tests/Unit/Http/RequestHandlerTest.php @@ -420,153 +420,6 @@ class RequestHandlerTest extends UnitTestCase $pageRendererProphecy->setMetaTag($expectedTags[1]['type'], $expectedTags[1]['name'], $expectedTags[1]['content'], [], false)->shouldHaveBeenCalled(); } - /** - * Test if the method is called, and the object is still the same. - * - * @test - */ - public function addModifiedGlobalsToIncomingRequestFindsSameObject() - { - GeneralUtility::flushInternalRuntimeCaches(); - $_SERVER['REQUEST_METHOD'] = 'POST'; - $_SERVER['HTTP_HOST'] = 'https://www.example.com/my/path/'; - $_GET = ['foo' => '1']; - $_POST = ['bar' => 'yo']; - $request = ServerRequestFactory::fromGlobals(); - $request = $request->withAttribute('_originalGetParameters', $_GET); - $request = $request->withAttribute('_originalPostParameters', $_POST); - - $subject = $this->getAccessibleMock(RequestHandler::class, ['dummy'], [], '', false); - $resultRequest = $subject->_call('addModifiedGlobalsToIncomingRequest', $request); - $this->assertSame($request, $resultRequest); - } - - /** - * @return array - */ - public function addModifiedGlobalsToIncomingRequestDataProvider() - { - return [ - 'No parameters have been modified via hook or middleware' => [ - ['batman' => '1'], - ['no_cache' => 1], - // Enriched within PSR-7 query params + parsed body - [], - [], - // modified GET / POST parameters - [], - [], - // expected merged results - ['batman' => '1'], - ['no_cache' => 1], - ], - 'No parameters have been modified via hook' => [ - ['batman' => '1'], - [], - // Enriched within PSR-7 query params + parsed body - ['ARD' => 'TV', 'Oscars' => 'Cinema'], - ['no_cache' => '1'], - // modified GET / POST parameters - [], - [], - // expected merged results - ['batman' => '1', 'ARD' => 'TV', 'Oscars' => 'Cinema'], - ['no_cache' => 1], - ], - 'Hooks and Middlewares modified' => [ - ['batman' => '1'], - [], - // Enriched within PSR-7 query params + parsed body - ['ARD' => 'TV', 'Oscars' => 'Cinema'], - ['no_cache' => '1'], - // modified GET / POST parameters - ['batman' => '1', 'add_via_hook' => 'yes'], - ['submitForm' => 'download now'], - // expected merged results - ['batman' => '1', 'add_via_hook' => 'yes', 'ARD' => 'TV', 'Oscars' => 'Cinema'], - ['submitForm' => 'download now', 'no_cache' => 1], - ], - 'Hooks and Middlewares modified with middleware overruling hooks' => [ - ['batman' => '1'], - [], - // Enriched within PSR-7 query params + parsed body - ['ARD' => 'TV', 'Oscars' => 'Cinema'], - ['no_cache' => '1'], - // modified GET / POST parameters - ['batman' => '0', 'add_via_hook' => 'yes'], - ['submitForm' => 'download now', 'no_cache' => 0], - // expected merged results - ['batman' => '1', 'add_via_hook' => 'yes', 'ARD' => 'TV', 'Oscars' => 'Cinema'], - ['submitForm' => 'download now', 'no_cache' => 1], - ], - 'Hooks and Middlewares modified with middleware overruling hooks with nested parameters' => [ - ['batman' => '1'], - [['tx_siteexample_pi2' => ['uid' => 13]]], - // Enriched within PSR-7 query params + parsed body - ['ARD' => 'TV', 'Oscars' => 'Cinema', ['tx_blogexample_pi1' => ['uid' => 123]]], - ['no_cache' => '1', ['tx_siteexample_pi2' => ['name' => 'empty-tail']]], - // modified GET / POST parameters - ['batman' => '0', 'add_via_hook' => 'yes', ['tx_blogexample_pi1' => ['uid' => 234]]], - ['submitForm' => 'download now', 'no_cache' => 0], - // expected merged results - ['batman' => '1', 'add_via_hook' => 'yes', 'ARD' => 'TV', 'Oscars' => 'Cinema', ['tx_blogexample_pi1' => ['uid' => 123]]], - ['submitForm' => 'download now', 'no_cache' => '1', ['tx_siteexample_pi2' => ['uid' => 13, 'name' => 'empty-tail']]], - ], - ]; - } - - /** - * Test if the method modifies GET and POST to the expected result, when enriching an object. - * - * @param array $initialGetParams - * @param array $initialPostParams - * @param array $addedQueryParams - * @param array $addedParsedBody - * @param array $modifiedGetParams - * @param array $modifiedPostParams - * @param array $expectedQueryParams - * @param array $expectedParsedBody - * @dataProvider addModifiedGlobalsToIncomingRequestDataProvider - * @test - */ - public function addModifiedGlobalsToIncomingRequestModifiesObject( - $initialGetParams, - $initialPostParams, - $addedQueryParams, - $addedParsedBody, - $modifiedGetParams, - $modifiedPostParams, - $expectedQueryParams, - $expectedParsedBody - ) { - GeneralUtility::flushInternalRuntimeCaches(); - $_SERVER['REQUEST_METHOD'] = 'POST'; - $_SERVER['HTTP_HOST'] = 'https://www.example.com/my/path/'; - $_GET = $initialGetParams; - $_POST = $initialPostParams; - $request = ServerRequestFactory::fromGlobals(); - $request = $request->withAttribute('_originalGetParameters', $initialGetParams); - $request = $request->withAttribute('_originalPostParameters', $initialPostParams); - - // Now enriching the request object with other GET / POST parameters - $queryParams = $request->getQueryParams(); - $queryParams = array_replace_recursive($queryParams, $addedQueryParams); - $request = $request->withQueryParams($queryParams); - $parsedBody = $request->getParsedBody() ?? []; - $parsedBody = array_replace_recursive($parsedBody, $addedParsedBody); - $request = $request->withParsedBody($parsedBody); - - // Now overriding GET and POST parameters - $_GET = $modifiedGetParams; - $_POST = $modifiedPostParams; - - $subject = $this->getAccessibleMock(RequestHandler::class, ['dummy'], [], '', false); - $subject->_set('timeTracker', new TimeTracker(false)); - $resultRequest = $subject->_call('addModifiedGlobalsToIncomingRequest', $request); - $this->assertEquals($expectedQueryParams, $resultRequest->getQueryParams()); - $this->assertEquals($expectedParsedBody, $resultRequest->getParsedBody()); - } - /** * Test if the method is called, and the globals are still the same after calling the method * -- GitLab