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: Introduce routingArguments and queryParameters to Fusion link prototypes to eventually replace arguments and additionalParams #3914

Open
wants to merge 4 commits into
base: 8.4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 69 additions & 19 deletions Neos.Fusion/Classes/FusionObjects/ActionUriImplementation.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,15 @@
* source code.
*/

use GuzzleHttp\Psr7\Uri;
use Neos\Flow\Mvc\ActionRequest;
use Neos\Flow\Mvc\Routing\UriBuilder;
use Neos\Fusion\Exception\RuntimeException;
use Neos\Utility\Arrays;

/**
* A Fusion ActionUri object
*
* The following Fusion properties are evaluated:
* * package
* * subpackage
* * controller
* * action
* * arguments
* * format
* * section
* * additionalParams
* * addQueryString
* * argumentsToBeExcludedFromQueryString
* * absolute
* * request
*
* See respective getters for descriptions
*/
class ActionUriImplementation extends AbstractFusionObject
Expand Down Expand Up @@ -85,15 +74,41 @@ public function getAction(): ?string
return $this->fusionValue('action');
}

/**
* Option to set custom routing arguments
*
* Please do not use this functionality to append query parameters and use 'queryParameters' instead:
*
* Neos.Fusion:ActionUri {
* queryParameters = ${{'q':'search term'}}
* }
*
* Appending query parameters via the use of exceeding routing arguments relies
* on `appendExceedingArguments` internally which is discouraged to leverage.
*
* But in case you meant to use routing arguments for advanced uri building,
* you can leverage this low level option.
*
* Be aware in order for the routing framework to match and resolve the arguments,
* your have to define a custom route in Routes.yaml
*
* @return array<string, mixed>
*/
public function getRoutingArguments(): array
{
return $this->fusionValue('routingArguments') ?: [];
}

/**
* Controller arguments
*
* @return array|null
* @deprecated with Neos 8.4 please use routingArguments or queryParameters instead
*/
public function getArguments(): ?array
{
$arguments = $this->fusionValue('arguments');
return is_array($arguments) ? $arguments: [];
return is_array($arguments) ? $arguments : [];
}

/**
Expand All @@ -120,16 +135,28 @@ public function getSection(): ?string
* Additional query parameters that won't be prefixed like $arguments (overrule $arguments)
*
* @return array|null
* @deprecated with Neos 8.4 please use routingArguments or queryParameters instead
*/
public function getAdditionalParams(): ?array
{
return $this->fusionValue('additionalParams');
}

/**
* Query parameters that are appended to the url
*
* @return array
*/
public function getQueryParameters(): array
{
return $this->fusionValue('queryParameters') ?: [];
}

/**
* Arguments to be removed from the URI. Only active if addQueryString = true
*
* @return array|null
* @deprecated to be removed with Neos 9
*/
public function getArgumentsToBeExcludedFromQueryString(): ?array
{
Expand All @@ -140,6 +167,7 @@ public function getArgumentsToBeExcludedFromQueryString(): ?array
* If true, the current query parameters will be kept in the URI
*
* @return boolean
* @deprecated to be removed with Neos 9
*/
public function isAddQueryString(): bool
{
Expand All @@ -157,12 +185,21 @@ public function isAbsolute(): bool
}

/**
* @return string
* @return UriBuilder
*/
public function evaluate()
public function createUriBuilder(): UriBuilder
{
$uriBuilder = new UriBuilder();
$uriBuilder->setRequest($this->getRequest());
return $uriBuilder;
}

/**
* @return string
*/
public function evaluate()
{
$uriBuilder = $this->createUriBuilder();

$format = $this->getFormat();
if ($format !== null) {
Expand Down Expand Up @@ -195,13 +232,26 @@ public function evaluate()
}

try {
return $uriBuilder->uriFor(
$arguments = $this->getArguments();
$routingArguments = $this->getRoutingArguments();
if ($arguments && $routingArguments) {
throw new RuntimeException('Neos.Fusion:ActionUri does not allow to combine "arguments" and "routingArguments"', 1665431866);
}
mhsdesign marked this conversation as resolved.
Show resolved Hide resolved
$uriString = $uriBuilder->uriFor(
$this->getAction(),
$this->getArguments(),
$routingArguments ?: $arguments,
$this->getController(),
$this->getPackage(),
$this->getSubpackage()
);
$queryParameters = $this->getQueryParameters();
if (empty($queryParameters)) {
return $uriString;
}
$uri = new Uri($uriString);
Copy link
Member

@mhsdesign mhsdesign Feb 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would look great in a flow uri utility or service, but I know the hassle since it’s in another repo… it might be enough time to pull it up (and you have my +1)

Advantage beeign that we can super easily tests this ugly code snippet isolated against all scenarios.

… or we can always later adjust it too (which is more likely a never thought ^^)

Copy link
Member Author

@mficzel mficzel Feb 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventually this code will be replaced by an all new action-uri-builder on the flow side. See neos/flow-development-collection#2744 (not finished and still in discussion). Once this is in place ActionUri should be adjusted to use this internally.

In the meantime this pr allows to handle the negative effects of additionalParams ending up in the routingCache and introduces the distinction between routingArguments and queryParameters.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay i see then its totally fine with inlining this temporarily ;)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI now with neos/flow-development-collection#3316 in place we can actually use a proper helper instead ;)

parse_str($uri->getQuery(), $queryParametersFromRouting);
$mergedQueryParameters = Arrays::arrayMergeRecursiveOverrule($queryParametersFromRouting, $queryParameters);
return (string)$uri->withQuery(http_build_query($mergedQueryParameters, '', '&'));
} catch (\Exception $exception) {
return $this->runtime->handleRenderingException($this->path, $exception);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ prototype(Neos.Fusion:ActionUri) {
action = null
format = null
section = null
routingArguments = Neos.Fusion:DataStructure
queryParameters = Neos.Fusion:DataStructure
additionalParams = Neos.Fusion:DataStructure
arguments = Neos.Fusion:DataStructure
argumentsToBeExcludedFromQueryString = Neos.Fusion:DataStructure
Expand Down
Loading
Loading