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: Render ResponseInterface directly in Fusion Views #4856

Merged
merged 31 commits into from Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
53c3ed4
WIP: FEATURE: Fusion Runtime render directly http response
mhsdesign Jan 28, 2024
bd64cdd
WIP: Neos Fusion View use Runtime::renderResponse
mhsdesign Jan 28, 2024
95169a6
WIP: Hacky HttpResponseConstraints
mhsdesign Jan 28, 2024
d567bdc
WIP: Hurray make Runtime independent of ControllerContext
mhsdesign Jan 28, 2024
1aeaa49
WIP: Migrate PluginImplementation to use `unsafeHttpResponseConstrains`
mhsdesign Jan 28, 2024
b9128fb
WIP: FusionObject to not depend on the controller context
mhsdesign Jan 28, 2024
c3d3681
WIP: Skip non working test :(
mhsdesign Jan 28, 2024
6ae0b24
TASK: Migrate further fusion objects to `$this->runtime->fusionGlobal…
mhsdesign Jan 30, 2024
6298673
Revert introduction of `HttpResponseConstraints` and api in runtime t…
mhsdesign Jan 30, 2024
cc70fed
TASK: Migrate further fusion objects to `$this->runtime->fusionGlobal…
mhsdesign Jan 30, 2024
58cefd6
TASK: Document legacy Runtime::getControllerContext
mhsdesign Feb 3, 2024
7559f87
TASK: Extract controller context legacy layer into withSimulatedLegac…
mhsdesign Feb 3, 2024
35f688d
TASK: Runtime fix `renderResponse` lock not being released
mhsdesign Feb 16, 2024
8adfc90
TASK: Runtime `renderResponse` unwrap `RuntimeException` itself
mhsdesign Feb 16, 2024
05aefc7
TASK: Add Fusion RuntimeException::getWrappedException
mhsdesign Feb 18, 2024
706ccc7
TASK: Remove manual http response parsing from FusionExceptionView
mhsdesign Feb 18, 2024
aca97ab
TASK: Revert Fusion `FusionView` HttpResponse support
mhsdesign Feb 18, 2024
8a53df6
TASK: Make Fusion `FusionView` independent of `ControllerContext`
mhsdesign Feb 18, 2024
c0ddd45
!!! TASK: Introduce `LegacyFusionControllerContext` instead of using …
mhsdesign Feb 22, 2024
64c1a41
TASK: Fix passing `tags` to plugin
mhsdesign Feb 22, 2024
35d06fb
!!! BUGFIX: Fusions `FusionView` will return `ResponseInterface` inst…
mhsdesign Feb 23, 2024
a24805e
TASK: `FusionExceptionView` handles psr response correctly
mhsdesign Feb 23, 2024
9450f74
TASK: `Runtime::renderResponse` will try to jsonSerialize result if n…
mhsdesign Feb 23, 2024
2e79a6d
TASK: Improve `fusionGlobals` handling in the Fusion `FusionView`
mhsdesign Feb 25, 2024
4184042
TASK: Runtime remove magic fusion jsonSerialize again
mhsdesign Feb 25, 2024
3f4089a
TASK: Refine fusion inline docs
mhsdesign Feb 25, 2024
51fb7f7
TASK: Adjust views to stricter return types
mhsdesign Mar 15, 2024
e1a2678
TASK: Return `ResponseInterface` or `StreamInterface` in fusion view
mhsdesign Mar 15, 2024
a99de6c
TASK: Adjust to strict types in `ViewInterface`
mhsdesign Mar 17, 2024
716e6a8
Fix typos
mhsdesign Apr 19, 2024
2cf100f
TASK: Introduce `TestingViewForFusionRuntime` for testing instead of …
mhsdesign Apr 22, 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
2 changes: 1 addition & 1 deletion Neos.Fusion/Classes/Core/Cache/FusionContextSerializer.php
Expand Up @@ -9,7 +9,7 @@
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

/**
* Serializer for Fusion's [at]cache.context values
* Serializer for Fusion's \@cache.context values
*
* Uses the Flows's property mapper as implementation.
* It relies on a converter being available from the context value type to string and reverse.
Expand Down
33 changes: 24 additions & 9 deletions Neos.Fusion/Classes/Core/FusionGlobals.php
Expand Up @@ -5,21 +5,31 @@
namespace Neos\Fusion\Core;

/**
* Fusion allows to add variable to the context either via
* \@context.foo = "bar" or by leveraging the php api {@see Runtime::pushContext()}.
* Fusion differentiates between dynamic context variables and fixed Fusion globals.
*
* Those approaches are highly dynamic and don't guarantee the existence of variables,
* Context variables are allowed to be set via Fusion's \@context.foo = "bar"
* or by leveraging the php api {@see Runtime::pushContext()}.
*
* Context variables are highly dynamic and don't guarantee the existence of a specific variables,
* as they have to be explicitly preserved in uncached \@cache segments,
* or might accidentally be popped from the stack.
*
* The Fusion runtime is instantiated with a set of global variables which contain the EEL helper definitions
* or functions like FlowQuery. Also, variables like "request" are made available via it.
* The Fusion globals are immutable and part of the runtime's constructor.
* A fixed set of global variables which might contain the EEL helper definitions
* or functions like FlowQuery can be passed this way.
*
* Additionally, also special variables like "request" are made available.
*
* The "${request}" special case: To make the request available in uncached segments, it would need to be serialized,
* but we don't allow this currently and despite that, it would be absurd to cache a random request.
* The speciality with "request" and similar is that they should be always available but never cached.
* Regular context variables must be serialized to be available in uncached segments,
* but the current request must not be serialized into the cache as it contains user specific information.
* This is avoided by always exposing the current action request via the global variable.
*
* Overriding Fusion globals is disallowed via \@context and {@see Runtime::pushContext()}.
*
* Fusion globals are case-sensitive, though it's not recommend to leverage this behaviour.
*
* @internal The globals will be set inside the FusionView as declared
*/
final readonly class FusionGlobals
{
Expand All @@ -45,8 +55,13 @@ public static function fromArray(array $variables): self
}

/**
* You can access the current request like via this getter:
* `$runtime->fusionGlobals->get('request')`
* Access the possible current request or other globals:
*
* $actionRequest = $this->runtime->fusionGlobals->get('request');
* if (!$actionRequest instanceof ActionRequest) {
* // fallback or error
* }
*
*/
public function get(string $name): mixed
{
Expand Down
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Neos\Fusion\Core;

final class IllegalEntryFusionPathValueException extends \Neos\Fusion\Exception
{
}
127 changes: 127 additions & 0 deletions Neos.Fusion/Classes/Core/LegacyFusionControllerContext.php
@@ -0,0 +1,127 @@
<?php

declare(strict_types=1);

namespace Neos\Fusion\Core;

use Neos\Flow\Annotations as Flow;
use Neos\Flow\Mvc\ActionRequest;
use Neos\Flow\Mvc\ActionResponse;
use Neos\Flow\Mvc\Controller\ControllerContext;
use Neos\Flow\Mvc\FlashMessage\FlashMessageContainer;
use Neos\Flow\Mvc\FlashMessage\FlashMessageService;
use Neos\Flow\Mvc\Routing\UriBuilder;

/**
* Legacy stub to replace the original {@see ControllerContext} inside Fusion {@see Runtime::getControllerContext()}.
*
* The concept of the controller context inside Fusion has been deprecated.
*
* You should definitely not pass this object along further, which will also most likely not work as it doesn't
* satisfy the constraint of `instanceof ControllerContext`!
*
* To migrate the use case of fetching the active request, please look into {@see FusionGlobals::get()} instead.
* By convention, an {@see ActionRequest} will be available as `request`:
*
* $actionRequest = $this->runtime->fusionGlobals->get('request');
* if (!$actionRequest instanceof ActionRequest) {
* // fallback or error
* }
*
* To get an {@see UriBuilder} proceed with:
*
* $uriBuilder = new UriBuilder();
* $uriBuilder->setRequest($actionRequest);
*
* WARNING regarding {@see Runtime::getControllerContext()}:
* Invoking this backwards-compatible layer is possibly unsafe, if the rendering was not started
* in {@see self::renderResponse()} or no `request` global is available. This will raise an exception.
*
* @deprecated with Neos 9.0 can be removed with 10
* @internal
*/
final class LegacyFusionControllerContext
{
/**
* @Flow\Inject
* @var FlashMessageService
*/
protected $flashMessageService;

public function __construct(
private readonly ActionRequest $request,
private readonly ActionResponse $legacyActionResponseForCurrentRendering
) {
}

/**
* To migrate the use case of fetching the active request, please look into {@see FusionGlobals::get()} instead.
* By convention, an {@see ActionRequest} will be available as `request`:
*
* $actionRequest = $this->runtime->fusionGlobals->get('request');
* if (!$actionRequest instanceof ActionRequest) {
* // fallback or error
* }
*
* @deprecated with Neos 9.0 can be removed with 10
*/
public function getRequest(): ActionRequest
{
return $this->request;
}

/**
* To migrate the use case of getting the UriBuilder please use this instead:
*
* $actionRequest = $this->runtime->fusionGlobals->get('request');
* if (!$actionRequest instanceof ActionRequest) {
* // fallback or error
* }
* $uriBuilder = new UriBuilder();
* $uriBuilder->setRequest($actionRequest);
*
* @deprecated with Neos 9.0 can be removed with 10
*/
public function getUriBuilder(): UriBuilder
{
$uriBuilder = new UriBuilder();
$uriBuilder->setRequest($this->request);
return $uriBuilder;
}

/**
* To migrate this use case please use {@see FlashMessageService::getFlashMessageContainerForRequest()} in
* combination with fetching the active request as described here {@see getRequest} instead.
*
* @deprecated with Neos 9.0 can be removed with 10
*/
public function getFlashMessageContainer(): FlashMessageContainer
{
return $this->flashMessageService->getFlashMessageContainerForRequest($this->request);
}

/**
* PURELY INTERNAL with partially undefined behaviour!!!
*
* Gives access to the legacy mutable action response simulation {@see Runtime::withSimulatedLegacyControllerContext()}
*
* Initially it was possible to mutate the current response of the active MVC controller through this getter.
*
* While *HIGHLY* internal behaviour and *ONLY* to be used by Neos.Fusion.Form or Neos.Neos:Plugin
* this legacy layer is in place to still allow this functionality.
*
* @deprecated with Neos 9.0 can be removed with 10
* @internal THIS SHOULD NEVER BE CALLED ON USER-LAND
*/
public function getResponse(): ActionResponse
{
// expose action response to be possibly mutated in neos forms or fusion plugins.
// this behaviour is highly internal and deprecated!
return $this->legacyActionResponseForCurrentRendering;
}

/**
* The method {@see ControllerContext::getArguments()} was removed without replacement.
*/
// public function getArguments(): Arguments;
grebaldi marked this conversation as resolved.
Show resolved Hide resolved
}