Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

!!! FEATURE: Dispatcher psr overhaul #3311

Draft
wants to merge 39 commits into
base: 9.0
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
d94562f
!!!FEATURE: Clearer controller pattern
kitsunet Nov 11, 2023
8ee71e9
Controller cleanup
kitsunet Dec 26, 2023
0fcf522
Style and suggestions cleanup
kitsunet Dec 26, 2023
e3fb34b
Tests for SimpleActionController
kitsunet Dec 26, 2023
b12f1df
Fix AjaxWidget dispatching to use new StopActionException::response
kitsunet Dec 27, 2023
3360130
Correct style issues
kitsunet Dec 27, 2023
0689c78
Fix spelling error
kitsunet Dec 28, 2023
465c80b
Merge remote-tracking branch 'origin/9.0' into feature/actioncontroll…
mhsdesign Jan 25, 2024
88f43d5
TASK: Adjust typos and doc of `ControllerInterface`
mhsdesign Jan 25, 2024
03662a7
TASK: Fix `RestController::redirectToUri`
mhsdesign Jan 25, 2024
3df0dbd
Update Neos.Flow/Tests/Functional/Http/Fixtures/Controller/FooControl…
kitsunet Jan 26, 2024
57d8995
TASK: Update `ControllerInterface::processRequest` doc
mhsdesign Jan 25, 2024
f3ba560
TASK: Fix `FooController` test
mhsdesign Jan 26, 2024
e3cdfb4
!!! TASK: Separate `ForwardException` from `StopActionException`
mhsdesign Jan 25, 2024
d507942
!!! TASK: Adjust Signals Dispatcher `beforeControllerInvocation` and …
mhsdesign Jan 26, 2024
c1ce1bc
TASK: Set fix $code of `StopActionException`
mhsdesign Jan 26, 2024
18da350
TASK: Adjust docs of MVC Control flow exceptions
mhsdesign Jan 26, 2024
73d7214
TASK: Rename factory methods of MVC Control flow exceptions
mhsdesign Jan 26, 2024
a59bdaa
Merge pull request #3 from mhsdesign/test-can-i-push-to-christian-que…
kitsunet Jan 26, 2024
554aa08
SpecialResponses become final
kitsunet Jan 27, 2024
82caa27
TASK: Revert introduction of `SimpleActionController`
mhsdesign Feb 3, 2024
c96fd84
TASK: Revert introduction of `SpecialResponsesSupport`
mhsdesign Feb 3, 2024
e540eb3
TASK: Fix phpstan
mhsdesign Feb 3, 2024
52cafdd
Merge pull request #3232 from kitsunet/feature/actioncontroller-simpl…
mhsdesign Feb 6, 2024
d6d083d
TASK: Avoid accessing "global" request, response and arguments in act…
mhsdesign Jan 29, 2024
b959935
WIP: Experiment prefer PsrResponse over ActionResponse
mhsdesign Jan 29, 2024
144a06f
WIP: Adjust tests to use psr response and not action response
mhsdesign Jan 29, 2024
09c24f5
FEATURE: Allow `*Action` to return psr response
mhsdesign Jan 29, 2024
6cc4787
TASK: Adjust `StopActionException::createForResponse` to use psr resp…
mhsdesign Feb 6, 2024
6c13cae
TASK: Properly deprecate ActionResponse
mhsdesign Feb 6, 2024
c3a4a67
TASK: Avoid use of ActionResponse in controller
mhsdesign Feb 6, 2024
09e0dae
TASK: Prefer `new BufferStream()` over `streamFor('')`
mhsdesign Mar 2, 2024
3d32ace
TASK: Widget view helper explicitly merge things
mhsdesign Mar 2, 2024
6229f94
TASK: Allow still to return an `ActionResponse` from a view
mhsdesign Mar 3, 2024
415584b
Merge pull request #3294 from mhsdesign/task/makeActionResponseObsolete
mhsdesign Mar 3, 2024
43964e1
Merge remote-tracking branch 'origin/9.0' into feature/dispatcher-ret…
mhsdesign Mar 3, 2024
0002e5e
TASK: Type $controllerArguments correctly
mhsdesign Mar 3, 2024
f4c5479
Merge remote-tracking branch 'origin/9.0' into feature/dispatcher-ret…
mhsdesign Apr 24, 2024
066748a
TASK: Remove `Neos\Flow\Http\RequestHandler::getHttpResponse`
mhsdesign May 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 0 additions & 11 deletions Neos.Flow/Classes/Http/RequestHandler.php
Expand Up @@ -120,17 +120,6 @@ public function getHttpRequest()
return $this->httpRequest;
}

/**
* Returns the HTTP response corresponding to the currently handled request
*
* @return ResponseInterface|null
* @deprecated since 6.0. Don't depend on this method. The HTTP response only exists after the innermost middleware (dispatch) is done. For that stage use a middleware instead.
*/
public function getHttpResponse()
{
throw new \BadMethodCallException(sprintf('The method %s was removed with Flow version 7.0 since its behavior is unreliable. To get hold of the response a middleware should be used instead.', __METHOD__), 1606467754);
}

/**
* Boots up Flow to runtime
*
Expand Down
6 changes: 4 additions & 2 deletions Neos.Flow/Classes/Mvc/ActionRequest.php
Expand Up @@ -212,6 +212,7 @@ public function getMainRequest(): ActionRequest
* Checks if this request is the uppermost ActionRequest, just one below the
* HTTP request.
*
* @phpstan-assert-if-true null $this->getParentRequest()
* @return boolean
* @api
*/
Expand Down Expand Up @@ -510,7 +511,7 @@ public function setArgument(string $argumentName, $value): void
throw new Exception\InvalidArgumentNameException('Invalid argument name (must be a non-empty string).', 1210858767);
}

if (strpos($argumentName, '__') === 0) {
if (str_starts_with($argumentName, '__')) {
$this->internalArguments[$argumentName] = $value;
return;
}
Expand All @@ -520,7 +521,7 @@ public function setArgument(string $argumentName, $value): void
throw new Exception\InvalidArgumentTypeException('You are not allowed to store objects in the request arguments. Please convert the object of type "' . get_class($value) . '" given for argument "' . $argumentName . '" to a simple type first.', 1302783022);
}

if (strpos($argumentName, '--') === 0) {
if (str_starts_with($argumentName, '--')) {
$this->pluginArguments[substr($argumentName, 2)] = $value;
return;
}
Expand Down Expand Up @@ -698,6 +699,7 @@ public function getFormat(): string
* @return void
* @Flow\Signal
* @throws \Neos\Flow\SignalSlot\Exception\InvalidSlotException
* @deprecated Since Flow 9.0 as this signal has no meaning for quite some time, you might as well use Dispatcher::beforeControllerInvocation
*/
protected function emitRequestDispatched($request): void
{
Expand Down
64 changes: 49 additions & 15 deletions Neos.Flow/Classes/Mvc/ActionResponse.php
Expand Up @@ -3,18 +3,43 @@

use GuzzleHttp\Psr7\Utils;
use Neos\Flow\Http\Cookie;
use Neos\Flow\Mvc\Controller\AbstractController;
use Neos\Flow\Mvc\Controller\ControllerContext;
use Psr\Http\Message\ResponseInterface;
use Neos\Flow\Annotations as Flow;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;
use GuzzleHttp\Psr7\Response;

/**
* The minimal MVC response object.
* It allows for simple interactions with the HTTP response from within MVC actions. More specific requirements can be implemented via HTTP middlewares.
* The legacy MVC response object.
*
* Previously Flows MVC needed a single mutable response which was passed from dispatcher to controllers
* and even further to the view and other places via the controller context: {@see ControllerContext::getResponse()}.
* This allowed to manipulate the response at every place.
*
* With the dispatcher and controllers now directly returning a response, the mutability is no longer required.
* Additionally, the abstraction offers naturally nothing, that cant be archived by the psr response,
* as it directly translates to one: {@see ActionResponse::buildHttpResponse()}
*
* So you can and should use the immutable psr {@see ResponseInterface} instead where-ever possible.
*
* For backwards compatibility, each controller will might now manage an own instance of the action response
* via `$this->response` {@see AbstractController::$response} and pass it along to places.
* But this behaviour is deprecated!
*
* Instead, you can directly return a PSR repose {@see \GuzzleHttp\Psr7\Response} from a controller:
*
* ```php
* public function myAction()
* {
* return (new Response(status: 200, body: $output))
* ->withAddedHeader('X-My-Header', 'foo');
* }
* ```
*
* @deprecated with Flow 9
* @Flow\Proxy(false)
* @api
*/
final class ActionResponse
{
Expand Down Expand Up @@ -66,7 +91,7 @@ public function __construct()
/**
* @param string|StreamInterface $content
* @return void
* @api
* @deprecated please use {@see ResponseInterface::withBody()} in combination with {@see \GuzzleHttp\Psr7\Utils::streamFor} instead
*/
public function setContent($content): void
{
Expand All @@ -82,7 +107,7 @@ public function setContent($content): void
*
* @param string $contentType
* @return void
* @api
* @deprecated please use {@see ResponseInterface::withHeader()} with "Content-Type" instead.
*/
public function setContentType(string $contentType): void
{
Expand All @@ -95,7 +120,7 @@ public function setContentType(string $contentType): void
* @param UriInterface $uri
* @param int $statusCode
* @return void
* @api
* @deprecated please use {@see ResponseInterface::withStatus()} and {@see ResponseInterface::withHeader()} with "Header" instead.
*/
public function setRedirectUri(UriInterface $uri, int $statusCode = 303): void
{
Expand All @@ -109,7 +134,7 @@ public function setRedirectUri(UriInterface $uri, int $statusCode = 303): void
*
* @param int $statusCode
* @return void
* @api
* @deprecated please use {@see ResponseInterface::withStatus()} instead.
*/
public function setStatusCode(int $statusCode): void
{
Expand All @@ -121,7 +146,7 @@ public function setStatusCode(int $statusCode): void
* This leads to a corresponding `Set-Cookie` header to be set in the HTTP response
*
* @param Cookie $cookie Cookie to be set in the HTTP response
* @api
* @deprecated please use {@see ResponseInterface::withHeader()} with "Set-Cookie" instead.
*/
public function setCookie(Cookie $cookie): void
{
Expand All @@ -133,7 +158,7 @@ public function setCookie(Cookie $cookie): void
* This leads to a corresponding `Set-Cookie` header with an expired Cookie to be set in the HTTP response
*
* @param string $cookieName Name of the cookie to delete
* @api
* @deprecated
*/
public function deleteCookie(string $cookieName): void
{
Expand All @@ -145,6 +170,8 @@ public function deleteCookie(string $cookieName): void
/**
* Set the specified header in the response, overwriting any previous value set for this header.
*
* This behaviour is unsafe and partially unspecified: https://github.com/neos/flow-development-collection/issues/2492
*
* @param string $headerName The name of the header to set
* @param array|string|\DateTime $headerValue An array of values or a single value for the specified header field
* @return void
Expand All @@ -163,6 +190,8 @@ public function setHttpHeader(string $headerName, $headerValue): void
/**
* Add the specified header to the response, without overwriting any previous value set for this header.
*
* This behaviour is unsafe and partially unspecified: https://github.com/neos/flow-development-collection/issues/2492
*
* @param string $headerName The name of the header to set
* @param array|string|\DateTime $headerValue An array of values or a single value for the specified header field
* @return void
Expand Down Expand Up @@ -232,7 +261,9 @@ public function getContentType(): string
}

/**
* Use this if you want build your own HTTP Response inside your action
* Unsafe. Please avoid the use of this escape hatch as the behaviour is partly unspecified
* https://github.com/neos/flow-development-collection/issues/2492
*
* @param ResponseInterface $response
*/
public function replaceHttpResponse(ResponseInterface $response): void
Expand Down Expand Up @@ -274,13 +305,16 @@ public function mergeIntoParentResponse(ActionResponse $actionResponse): ActionR
}

/**
* Note this is a special use case method that will apply the internal properties (Content-Type, StatusCode, Location, Set-Cookie and Content)
* to the given PSR-7 Response and return a modified response. This is used to merge the ActionResponse properties into a possible HttpResponse
* created in a View (see ActionController::renderView()) because those would be overwritten otherwise. Note that any component parameters will
* still run through the component chain and will not be propagated here.
* During the migration of {@see ActionResponse} to {@see HttpResponse} this might come in handy.
*
* Note this is a special use case method that will apply the internal properties
* (Content-Type, StatusCode, Location, Set-Cookie and Content)
* to a new or replaced PSR-7 Response and return it.
*
* Possibly unsafe when used in combination with {@see self::replaceHttpResponse()}
* https://github.com/neos/flow-development-collection/issues/2492
*
* @return ResponseInterface
* @internal
*/
public function buildHttpResponse(): ResponseInterface
{
Expand Down