Skip to content

Commit

Permalink
TASK: Introduce NodeUri Options in favour of NodeUriSpecification
Browse files Browse the repository at this point in the history
The api will be

```
public function uriFor(NodeAddress $nodeAddress, Options $options = null): UriInterface
```
  • Loading branch information
mhsdesign committed May 22, 2024
1 parent 561ecbe commit 62e1dc0
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 149 deletions.
6 changes: 2 additions & 4 deletions Neos.Neos/Classes/Controller/Frontend/NodeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,8 @@
use Neos\Neos\Domain\Service\RenderingModeService;
use Neos\Neos\FrontendRouting\Exception\InvalidShortcutException;
use Neos\Neos\FrontendRouting\Exception\NodeNotFoundException;
use Neos\Neos\FrontendRouting\NodeAddressFactory;
use Neos\Neos\FrontendRouting\NodeShortcutResolver;
use Neos\Neos\FrontendRouting\NodeUriBuilderFactory;
use Neos\Neos\FrontendRouting\NodeUriSpecification;
use Neos\Neos\FrontendRouting\NodeUri\NodeUriBuilderFactory;
use Neos\Neos\FrontendRouting\SiteDetection\SiteDetectionResult;
use Neos\Neos\Utility\NodeTypeWithFallbackProvider;
use Neos\Neos\View\FusionView;
Expand Down Expand Up @@ -289,7 +287,7 @@ protected function handleShortcutNode(NodeAddress $nodeAddress): void
}
try {
$resolvedUri = $this->nodeUriBuilderFactory->forRequest($this->request->getHttpRequest())
->uriFor(NodeUriSpecification::create($nodeAddress));
->uriFor($nodeAddress);
} catch (NoMatchingRouteException $e) {
throw new NodeNotFoundException(sprintf(
'The shortcut node target of node %s could not be resolved: %s',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@

declare(strict_types=1);

namespace Neos\Neos\FrontendRouting;
namespace Neos\Neos\FrontendRouting\NodeUri;

use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress;
use Neos\Flow\Mvc\Exception\NoMatchingRouteException;
use Neos\Flow\Mvc\Routing\Dto\ResolveContext;
use Neos\Flow\Mvc\Routing\Dto\RouteParameters;
Expand Down Expand Up @@ -43,25 +44,7 @@ public function __construct(
* Return human readable host relative uris if the cr of the current request matches the one of the specified node.
* For cross-links to another cr the resulting uri be absolute and contain the host of the other site's domain.
*
* As the human readable uris are only routed for nodes of the live workspace (see DocumentUriProjection)
* This method requires the node to be passed to be in the live workspace and will throw otherwise.
*
* @throws NoMatchingRouteException
*/
public function uriFor(NodeUriSpecification $specification): UriInterface
{
return $this->router->resolve(
new ResolveContext(
$this->baseUri,
$this->toShowActionRouteValues($specification),
false,
ltrim($this->baseUri->getPath(), '\/'),
$this->routeParameters
)
);
}

/**
* absolute true:
* Return human readable absolute uris with host, independent if the node is cross linked or of the current request.
* For nodes of the current cr the passed base uri will be used as host. For cross-linked nodes the host will be derived by the site's domain.
*
Expand All @@ -70,13 +53,27 @@ public function uriFor(NodeUriSpecification $specification): UriInterface
*
* @throws NoMatchingRouteException
*/
public function absoluteUriFor(NodeUriSpecification $specification): UriInterface
public function uriFor(NodeAddress $nodeAddress, Options $options = null): UriInterface
{
if (!$nodeAddress->workspaceName->isLive()) {
return $this->previewUriFor($nodeAddress, $options);
}

$routeValues = $options?->routingArguments ?? [];
$routeValues['node'] = $nodeAddress;
$routeValues['@action'] = strtolower('show');
$routeValues['@controller'] = strtolower('Frontend\Node');
$routeValues['@package'] = strtolower('Neos.Neos');

if ($options?->format !== null && $options->format !== '') {
$routeValues['@format'] = $options->format;
}

return $this->router->resolve(
new ResolveContext(
$this->baseUri,
$this->toShowActionRouteValues($specification),
true,
$routeValues,
$options?->forceAbsolute ?? false,
ltrim($this->baseUri->getPath(), '\/'),
$this->routeParameters
)
Expand All @@ -86,50 +83,26 @@ public function absoluteUriFor(NodeUriSpecification $specification): UriInterfac
/**
* Returns a host relative uri with fully qualified node as query parameter encoded.
*/
public function previewUriFor(NodeUriSpecification $specification): UriInterface
public function previewUriFor(NodeAddress $nodeAddress, Options $options = null): UriInterface
{
$routeValues = $options?->routingArguments ?? [];
$routeValues['node'] = $nodeAddress->toUriString();
$routeValues['@action'] = strtolower('preview');
$routeValues['@controller'] = strtolower('Frontend\Node');
$routeValues['@package'] = strtolower('Neos.Neos');

if ($options?->format !== null && $options->format !== '') {
$routeValues['@format'] = $options->format;
}

return $this->router->resolve(
new ResolveContext(
$this->baseUri,
$this->toPreviewActionRouteValues($specification),
false,
$routeValues,
$options?->forceAbsolute ?? false,
ltrim($this->baseUri->getPath(), '\/'),
$this->routeParameters
)
);
}

/**
* @return array<string, mixed>
*/
private function toShowActionRouteValues(NodeUriSpecification $specification): array
{
$routeValues = $specification->routingArguments;
$routeValues['node'] = $specification->node;
$routeValues['@action'] = strtolower('show');
$routeValues['@controller'] = strtolower('Frontend\Node');
$routeValues['@package'] = strtolower('Neos.Neos');

if ($specification->format !== '') {
$routeValues['@format'] = $specification->format;
}
return $routeValues;
}

/**
* @return array<string, mixed>
*/
private function toPreviewActionRouteValues(NodeUriSpecification $specification): array
{
$routeValues = $specification->routingArguments;
$routeValues['node'] = $specification->node->toUriString();
$routeValues['@action'] = strtolower('preview');
$routeValues['@controller'] = strtolower('Frontend\Node');
$routeValues['@package'] = strtolower('Neos.Neos');

if ($specification->format !== '') {
$routeValues['@format'] = $specification->format;
}
return $routeValues;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Neos\Neos\FrontendRouting;
namespace Neos\Neos\FrontendRouting\NodeUri;

use Neos\Flow\Annotations as Flow;
use Neos\Flow\Http\Helper\RequestInformationHelper;
Expand Down
64 changes: 64 additions & 0 deletions Neos.Neos/Classes/FrontendRouting/NodeUri/Options.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

declare(strict_types=1);

namespace Neos\Neos\FrontendRouting\NodeUri;

/*
* Immutable filter DTO for {@see NodeUriBuilder::uriFor()}
*
* Example:
*
* Options::create(forceAbsolute: true);
*
* @api for the factory methods; NOT for the inner state.
*/
final readonly class Options
{
/**
* @internal the properties themselves are readonly; only the write-methods are API.
* @param array<string, mixed> $routingArguments
*/
private function __construct(
public ?bool $forceAbsolute,
public ?string $format,
public ?array $routingArguments,
) {
}

/**
* Creates an instance with the specified options
*
* Note: The signature of this method might be extended in the future, so it should always be used with named arguments
* @see https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments
*
* @param array<string, mixed> $routingArguments
*/
public static function create(
bool $forceAbsolute = null,
string $format = null,
array $routingArguments = null,
): self {
return new self($forceAbsolute, $format, $routingArguments);
}

/**
* Returns a new instance with the specified additional options
*
* Note: The signature of this method might be extended in the future, so it should always be used with named arguments
* @see https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments
*
* @param array<string, mixed> $routingArguments
*/
public function with(
bool $forceAbsolute = null,
string $format = null,
array $routingArguments = null,
): self {
return self::create(
$forceAbsolute ?? $this->forceAbsolute,
$format ?? $this->format,
$routingArguments ?? $this->routingArguments,
);
}
}
45 changes: 0 additions & 45 deletions Neos.Neos/Classes/FrontendRouting/NodeUriSpecification.php

This file was deleted.

14 changes: 7 additions & 7 deletions Neos.Neos/Classes/Fusion/ConvertUrisImplementation.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
use Neos\Media\Domain\Repository\AssetRepository;
use Neos\Neos\Domain\Exception as NeosException;
use Neos\Neos\Domain\Model\RenderingMode;
use Neos\Neos\FrontendRouting\NodeUriBuilderFactory;
use Neos\Neos\FrontendRouting\NodeUriSpecification;
use Neos\Neos\FrontendRouting\NodeUri\NodeUriBuilderFactory;
use Neos\Neos\FrontendRouting\NodeUri\Options;
use Neos\Neos\Fusion\Cache\CacheTag;
use Psr\Log\LoggerInterface;

Expand Down Expand Up @@ -142,9 +142,11 @@ public function evaluate()
$nodeAddress = NodeAddress::fromNode($node);

$unresolvedUris = [];
$absolute = $this->fusionValue('absolute');
$options = Options::create(
forceAbsolute: $this->fusionValue('absolute'),
);

$processedContent = preg_replace_callback(self::PATTERN_SUPPORTED_URIS, function (array $matches) use ($nodeAddress, &$unresolvedUris, $absolute) {
$processedContent = preg_replace_callback(self::PATTERN_SUPPORTED_URIS, function (array $matches) use ($nodeAddress, &$unresolvedUris, $options) {
$resolvedUri = null;
switch ($matches[1]) {
case 'node':
Expand All @@ -162,9 +164,7 @@ public function evaluate()
$nodeUriBuilder = $this->nodeUriBuilderFactory->forRequest(ServerRequest::fromGlobals());
}
try {
$resolvedUri = $absolute
? (string)$nodeUriBuilder->absoluteUriFor(NodeUriSpecification::create($nodeAddress))
: (string)$nodeUriBuilder->uriFor(NodeUriSpecification::create($nodeAddress));
$resolvedUri = (string)$nodeUriBuilder->uriFor($nodeAddress, $options);
} catch (NoMatchingRouteException) {
// todo log also arguments?
$this->systemLogger->warning(sprintf('Could not resolve "%s" to a node uri.', $matches[0]), LogEnvironment::fromMethodName(__METHOD__));
Expand Down
5 changes: 2 additions & 3 deletions Neos.Neos/Classes/Fusion/Helper/LinkHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
use Neos\Flow\ResourceManagement\ResourceManager;
use Neos\Media\Domain\Model\AssetInterface;
use Neos\Media\Domain\Repository\AssetRepository;
use Neos\Neos\FrontendRouting\NodeUriBuilderFactory;
use Neos\Neos\FrontendRouting\NodeUriSpecification;
use Neos\Neos\FrontendRouting\NodeUri\NodeUriBuilderFactory;
use Neos\Neos\Fusion\ConvertUrisImplementation;
use Psr\Http\Message\UriInterface;
use Psr\Log\LoggerInterface;
Expand Down Expand Up @@ -111,7 +110,7 @@ public function resolveNodeUri(
$nodeUriBuilder = $this->nodeUriBuilderFactory->forRequest($controllerContext->getRequest()->getHttpRequest());

try {
$targetUri = $nodeUriBuilder->uriFor(NodeUriSpecification::create(NodeAddress::fromNode($targetNode)));
$targetUri = $nodeUriBuilder->uriFor(NodeAddress::fromNode($targetNode));
} catch (NoMatchingRouteException $e) {
$this->systemLogger->info(sprintf(
'Failed to build URI for node "%s": %e',
Expand Down
17 changes: 9 additions & 8 deletions Neos.Neos/Classes/Fusion/NodeUriImplementation.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
use Neos\Flow\Mvc\ActionRequest;
use Neos\Flow\Mvc\Exception\NoMatchingRouteException;
use Neos\Fusion\FusionObjects\AbstractFusionObject;
use Neos\Neos\FrontendRouting\NodeUriBuilderFactory;
use Neos\Neos\FrontendRouting\NodeUriSpecification;
use Neos\Neos\FrontendRouting\NodeUri\NodeUriBuilderFactory;
use Neos\Neos\FrontendRouting\NodeUri\Options;
use Psr\Log\LoggerInterface;

/**
Expand Down Expand Up @@ -150,14 +150,15 @@ public function evaluate()
// https://github.com/neos/flow-development-collection/pull/2744
$nodeUriBuilder = $this->nodeUriBuilderFactory->forRequest(ServerRequest::fromGlobals());
}
$specification = NodeUriSpecification::create(NodeAddress::fromNode($node))
->withFormat($this->getFormat() ?: '')
->withRoutingArguments($this->getAdditionalParams());

$options = Options::create(
forceAbsolute: $this->isAbsolute(),
format: $this->getFormat(),
routingArguments: $this->getAdditionalParams()
);

try {
$resolvedUri = $this->isAbsolute()
? $nodeUriBuilder->absoluteUriFor($specification)
: $nodeUriBuilder->uriFor($specification);
$resolvedUri = $nodeUriBuilder->uriFor(NodeAddress::fromNode($node), $options);
} catch (NoMatchingRouteException) {
// todo log arguments?
$this->systemLogger->warning(sprintf('Could not resolve "%s" to a node uri.', $node->aggregateId->value), LogEnvironment::fromMethodName(__METHOD__));
Expand Down
19 changes: 10 additions & 9 deletions Neos.Neos/Classes/ViewHelpers/Link/NodeViewHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
use Neos\Neos\FrontendRouting\Exception\InvalidShortcutException;
use Neos\Neos\FrontendRouting\Exception\NodeNotFoundException;
use Neos\Neos\FrontendRouting\NodeShortcutResolver;
use Neos\Neos\FrontendRouting\NodeUriBuilderFactory;
use Neos\Neos\FrontendRouting\NodeUriSpecification;
use Neos\Neos\FrontendRouting\NodeUri\NodeUriBuilderFactory;
use Neos\Neos\FrontendRouting\NodeUri\Options;
use Neos\Neos\Utility\NodeTypeWithFallbackProvider;

/**
Expand Down Expand Up @@ -302,14 +302,15 @@ public function render(): string
$nodeUriBuilder = $this->nodeUriBuilderFactory->forRequest($this->controllerContext->getRequest()->getHttpRequest());

$uri = '';
$specification = NodeUriSpecification::create($nodeAddress)
->withFormat($this->arguments['format'] ?: '')
->withRoutingArguments($this->arguments['arguments']);

try {
$uri = $this->arguments['absolute']
? $nodeUriBuilder->absoluteUriFor($specification)
: $nodeUriBuilder->uriFor($specification);
$uri = $nodeUriBuilder->uriFor(
$nodeAddress,
Options::create(
forceAbsolute: $this->arguments['absolute'],
format: $this->arguments['format'],
routingArguments: $this->arguments['arguments']
)
);

if ($this->arguments['section'] !== '') {
$uri = $uri->withFragment($this->arguments['section']);
Expand Down
Loading

0 comments on commit 62e1dc0

Please sign in to comment.