From 33c4d0d5f03f953ca2ecc1b678a583ecef1139da Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Sat, 3 Feb 2024 14:10:07 +0100 Subject: [PATCH] Revert "TASK: Revert introduction of `SpecialResponsesSupport`" This reverts commit c96fd84431318e55297045beac984c73a01d94a1. --- .../Mvc/Controller/AbstractController.php | 40 +++------ .../Classes/Mvc/Controller/RestController.php | 19 ++-- .../Controller/SpecialResponsesSupport.php | 88 +++++++++++++++++++ .../Mvc/Exception/ForwardException.php | 3 +- .../Mvc/Exception/StopActionException.php | 4 +- 5 files changed, 112 insertions(+), 42 deletions(-) create mode 100644 Neos.Flow/Classes/Mvc/Controller/SpecialResponsesSupport.php diff --git a/Neos.Flow/Classes/Mvc/Controller/AbstractController.php b/Neos.Flow/Classes/Mvc/Controller/AbstractController.php index c36e276391..e4452524ac 100644 --- a/Neos.Flow/Classes/Mvc/Controller/AbstractController.php +++ b/Neos.Flow/Classes/Mvc/Controller/AbstractController.php @@ -42,6 +42,8 @@ */ abstract class AbstractController implements ControllerInterface { + use SpecialResponsesSupport; + /** * @var UriBuilder */ @@ -230,22 +232,6 @@ protected function forward(string $actionName, string $controllerName = null, st $this->forwardToRequest($nextRequest); } - /** - * Forwards the request to another action and / or controller. - * - * Request is directly transfered to the other action / controller - * - * @param ActionRequest $request The request to redirect to - * @throws ForwardException - * @see redirectToRequest() - * @api - */ - protected function forwardToRequest(ActionRequest $request): never - { - $nextRequest = clone $request; - throw ForwardException::createForNextRequest($nextRequest, ''); - } - /** * Redirects the request to another action and / or controller. * @@ -322,16 +308,12 @@ protected function redirectToRequest(ActionRequest $request, int $delay = 0, int */ protected function redirectToUri(string|UriInterface $uri, int $delay = 0, int $statusCode = 303): never { - if ($delay === 0) { - if (!$uri instanceof UriInterface) { - $uri = new Uri($uri); - } - $this->response->setRedirectUri($uri, $statusCode); - } else { - $this->response->setStatusCode($statusCode); - $this->response->setContent(''); + if (!$uri instanceof UriInterface) { + $uri = new Uri($uri); } - throw StopActionException::createForResponse($this->response, ''); + + $response = $this->responseRedirectsToUri($uri, $delay, $statusCode, $this->response); + $this->throwStopActionWithResponse($response, ''); } /** @@ -343,11 +325,11 @@ protected function redirectToUri(string|UriInterface $uri, int $delay = 0, int $ * @param string $statusMessage A custom HTTP status message * @param string $content Body content which further explains the status * @throws StopActionException - * @api + * @deprecated Use SpecialResponsesSupport::responseThrowsStatus + * @see SpecialResponsesSupport::responseThrowsStatus */ protected function throwStatus(int $statusCode, $statusMessage = null, $content = null): never { - $this->response->setStatusCode($statusCode); if ($content === null) { $content = sprintf( '%s %s', @@ -355,8 +337,8 @@ protected function throwStatus(int $statusCode, $statusMessage = null, $content $statusMessage ?? ResponseInformationHelper::getStatusMessageByCode($statusCode) ); } - $this->response->setContent($content); - throw StopActionException::createForResponse($this->response, $content); + + $this->responseThrowsStatus($statusCode, $content, $this->response); } /** diff --git a/Neos.Flow/Classes/Mvc/Controller/RestController.php b/Neos.Flow/Classes/Mvc/Controller/RestController.php index 79ec113edf..a6eb0c1a42 100644 --- a/Neos.Flow/Classes/Mvc/Controller/RestController.php +++ b/Neos.Flow/Classes/Mvc/Controller/RestController.php @@ -128,15 +128,16 @@ protected function initializeUpdateAction() */ protected function redirectToUri(string|UriInterface $uri, int $delay = 0, int $statusCode = 303): never { - // the parent method throws the exception, but we need to act afterwards - // thus the code in catch - it's the expected state - try { - parent::redirectToUri($uri, $delay, $statusCode); - } catch (StopActionException $exception) { - if ($this->request->getFormat() === 'json') { - $exception->response->setContent(''); - } - throw $exception; + if (!$uri instanceof UriInterface) { + $uri = new Uri($uri); + } + + $response = $this->responseRedirectsToUri($uri, $delay, $statusCode, $this->response); + if ($this->request->getFormat() === 'json') { + // send empty body on redirects for JSON requests + $response->setContent(''); } + + $this->throwStopActionWithResponse($response, ''); } } diff --git a/Neos.Flow/Classes/Mvc/Controller/SpecialResponsesSupport.php b/Neos.Flow/Classes/Mvc/Controller/SpecialResponsesSupport.php new file mode 100644 index 0000000000..733500c78c --- /dev/null +++ b/Neos.Flow/Classes/Mvc/Controller/SpecialResponsesSupport.php @@ -0,0 +1,88 @@ +setStatusCode($statusCode); + if ($content !== '') { + $response->setContent($content); + } + + $this->throwStopActionWithResponse($response, $content); + } + + /** + * Redirects to another URI + * + * @param UriInterface $uri Either a string representation of a URI or a UriInterface object + * @param integer $delay (optional) The delay in seconds. Default is no delay. + * @param integer $statusCode (optional) The HTTP status code for the redirect. Default is "303 See Other" + * @param ActionResponse|null $response response that will have status, and location or body overwritten. + * @return ActionResponse + * @throws StopActionException + */ + final protected function responseRedirectsToUri(UriInterface $uri, int $delay = 0, int $statusCode = 303, ?ActionResponse $response = null): ActionResponse + { + $nextResponse = $response !== null ? clone $response : new ActionResponse(); + + if ($delay < 1) { + $nextResponse->setRedirectUri($uri, $statusCode); + $this->throwStopActionWithResponse($nextResponse, ''); + } + + $nextResponse->setStatusCode($statusCode); + $content = sprintf('Redirect to %s', $delay, $uri, $uri); + $nextResponse->setContent($content); + return $nextResponse; + } + + /** + * @param ActionResponse $response The response to be received by the MVC Dispatcher. + * @param string $details Additional details just for the exception, in case it is logged (the regular exception message). + * @return never + * @throws StopActionException + */ + final protected function throwStopActionWithResponse(ActionResponse $response, string $details = ''): never + { + throw StopActionException::createForResponse($response, $details); + } + + /** + * Forwards the request to another action and / or controller + * Request is directly transferred to the other action / controller + * + * NOTE that this will not try to convert any objects in the requests arguments, + * this can be a fine or a problem depending on context of usage. + * + * @param ActionRequest $request The request to redirect to + * @return never + * @throws ForwardException + */ + final protected function forwardToRequest(ActionRequest $request): never + { + $nextRequest = clone $request; + throw ForwardException::createForNextRequest($nextRequest, ''); + } +} diff --git a/Neos.Flow/Classes/Mvc/Exception/ForwardException.php b/Neos.Flow/Classes/Mvc/Exception/ForwardException.php index 2a1564c920..075f3b8cdf 100644 --- a/Neos.Flow/Classes/Mvc/Exception/ForwardException.php +++ b/Neos.Flow/Classes/Mvc/Exception/ForwardException.php @@ -11,13 +11,12 @@ * source code. */ use Neos\Flow\Mvc\ActionRequest; -use Neos\Flow\Mvc\Controller\AbstractController; /** * This exception is thrown by a controller to stop the execution of the current * action and return the control to the dispatcher for the special case of a forward. * - * See {@see AbstractController::forward()} for more information. + * See {@see SpecialResponsesSupport::forwardToRequest()} for more information. * * Other control flow exceptions: {@see StopActionException} * diff --git a/Neos.Flow/Classes/Mvc/Exception/StopActionException.php b/Neos.Flow/Classes/Mvc/Exception/StopActionException.php index 50a4d6d9b9..18c4f7cbc4 100644 --- a/Neos.Flow/Classes/Mvc/Exception/StopActionException.php +++ b/Neos.Flow/Classes/Mvc/Exception/StopActionException.php @@ -12,7 +12,6 @@ */ use Neos\Flow\Mvc\ActionResponse; -use Neos\Flow\Mvc\Controller\AbstractController; /** * This exception is thrown by a controller to stop the execution of the current @@ -20,7 +19,8 @@ * exception and - depending on the "dispatched" status of the request - either * continues dispatching the request or returns control to the request handler. * - * See {@see AbstractController::throwStatus()} or {@see AbstractController::redirectToUri()} for more information. + * See {@see SpecialResponsesSupport::throwStopActionWithResponse()} + * or {@see SpecialResponsesSupport::responseRedirectsToUri()} for more information. * * Other control flow exceptions: {@see ForwardException} *