Skip to content

Commit

Permalink
Revert "TASK: Revert introduction of SpecialResponsesSupport"
Browse files Browse the repository at this point in the history
This reverts commit c96fd84.
  • Loading branch information
mhsdesign committed Feb 3, 2024
1 parent f5b137f commit 33c4d0d
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 42 deletions.
40 changes: 11 additions & 29 deletions Neos.Flow/Classes/Mvc/Controller/AbstractController.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
*/
abstract class AbstractController implements ControllerInterface
{
use SpecialResponsesSupport;

/**
* @var UriBuilder
*/
Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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('<html><head><meta http-equiv="refresh" content="' . (int)$delay . ';url=' . $uri . '"/></head></html>');
if (!$uri instanceof UriInterface) {
$uri = new Uri($uri);
}
throw StopActionException::createForResponse($this->response, '');

$response = $this->responseRedirectsToUri($uri, $delay, $statusCode, $this->response);
$this->throwStopActionWithResponse($response, '');
}

/**
Expand All @@ -343,20 +325,20 @@ 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',
$statusCode,
$statusMessage ?? ResponseInformationHelper::getStatusMessageByCode($statusCode)
);
}
$this->response->setContent($content);
throw StopActionException::createForResponse($this->response, $content);

$this->responseThrowsStatus($statusCode, $content, $this->response);
}

/**
Expand Down
19 changes: 10 additions & 9 deletions Neos.Flow/Classes/Mvc/Controller/RestController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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, '');
}
}
88 changes: 88 additions & 0 deletions Neos.Flow/Classes/Mvc/Controller/SpecialResponsesSupport.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php
namespace Neos\Flow\Mvc\Controller;

use Neos\Flow\Mvc\ActionRequest;
use Neos\Flow\Mvc\ActionResponse;
use Neos\Flow\Mvc\Exception\ForwardException;
use Neos\Flow\Mvc\Exception\StopActionException;
use Psr\Http\Message\UriInterface;

/**
* provides helper methods to facilitate redirects, status throws, stop action and forwards
*/
trait SpecialResponsesSupport
{
/**
* Sends the specified HTTP status immediately.
*
* @param integer $statusCode The HTTP status code
* @param string $content Body content which further explains the status the body of a given response will be overwritten if this is not empty
* @param ActionResponse|null $response The response to use or null for an empty response with the given status and message or content
* @return never
* @throws StopActionException
*/
final protected function responseThrowsStatus(int $statusCode, string $content = '', ?ActionResponse $response = null): never
{
$response = $response ?? new ActionResponse;

$response->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('<html lang="en"><head><meta http-equiv="refresh" content="%u;url=%s"/><title>Redirect to %s</title></head></html>', $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, '');
}
}
3 changes: 1 addition & 2 deletions Neos.Flow/Classes/Mvc/Exception/ForwardException.php
Original file line number Diff line number Diff line change
Expand Up @@ -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}
*
Expand Down
4 changes: 2 additions & 2 deletions Neos.Flow/Classes/Mvc/Exception/StopActionException.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@
*/

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
* action and return the control to the dispatcher. The dispatcher catches this
* 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}
*
Expand Down

0 comments on commit 33c4d0d

Please sign in to comment.