Skip to content

Commit

Permalink
WIP: Adjust NodeViewHelper to node uri builder
Browse files Browse the repository at this point in the history
  • Loading branch information
mhsdesign committed May 11, 2024
1 parent 6dad902 commit d0cdf6f
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 76 deletions.
82 changes: 42 additions & 40 deletions Neos.Neos/Classes/ViewHelpers/Link/NodeViewHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,25 @@
use Neos\ContentRepository\Core\ContentRepository;
use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindClosestNodeFilter;
use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId;
use Neos\ContentRepository\Core\Projection\ContentGraph\NodePath;
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
use Neos\Neos\Domain\Service\NodeTypeNameFactory;
use Neos\Neos\FrontendRouting\NodeAddress;
use Neos\Neos\FrontendRouting\NodeAddressFactory;
use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId;
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Http\Exception as HttpException;
use Neos\Flow\Log\ThrowableStorageInterface;
use Neos\Flow\Mvc\Exception\NoMatchingRouteException;
use Neos\Flow\Mvc\Routing\Exception\MissingActionNameException;
use Neos\Flow\Mvc\Routing\UriBuilder;
use Neos\FluidAdaptor\Core\ViewHelper\AbstractTagBasedViewHelper;
use Neos\FluidAdaptor\Core\ViewHelper\Exception as ViewHelperException;
use Neos\Fusion\ViewHelpers\FusionContextTrait;
use Neos\Neos\Domain\Service\NodeTypeNameFactory;
use Neos\Neos\FrontendRouting\Exception\InvalidShortcutException;
use Neos\Neos\FrontendRouting\Exception\NodeNotFoundException;
use Neos\Neos\FrontendRouting\NodeAddress as LegacyNodeAddress;
use Neos\Neos\FrontendRouting\NodeAddressFactory as LegacyNodeAddressFactory;
use Neos\Neos\FrontendRouting\NodeShortcutResolver;
use Neos\Neos\FrontendRouting\NodeUriBuilder;
use Neos\Neos\FrontendRouting\NodeUriBuilderFactory;
use Neos\Neos\FrontendRouting\NodeUriSpecification;
use Neos\Neos\Utility\NodeTypeWithFallbackProvider;

/**
Expand Down Expand Up @@ -149,6 +148,12 @@ class NodeViewHelper extends AbstractTagBasedViewHelper
*/
protected $throwableStorage;

/**
* @Flow\Inject
* @var NodeUriBuilderFactory
*/
protected $nodeUriBuilderFactory;

/**
* Initialize arguments
*
Expand Down Expand Up @@ -255,18 +260,15 @@ public function render(): string
}

if ($node instanceof Node) {
$contentRepository = $this->contentRepositoryRegistry->get(
$node->subgraphIdentity->contentRepositoryId
);
$nodeAddressFactory = NodeAddressFactory::create($contentRepository);
$nodeAddress = $nodeAddressFactory->createFromNode($node);
$nodeAddress = $node->address;
} elseif (is_string($node)) {
$documentNode = $this->getContextVariable('documentNode');
assert($documentNode instanceof Node);
$contentRepository = $this->contentRepositoryRegistry->get(
$documentNode->subgraphIdentity->contentRepositoryId
);
$nodeAddress = $this->resolveNodeAddressFromString($node, $documentNode, $contentRepository);
$nodeAddress = $this->resolveNodeAddressFromString($node, $documentNode, $contentRepository)
->toNewAddress($documentNode->subgraphIdentity->contentRepositoryId);
$node = $documentNode;
} else {
throw new ViewHelperException(sprintf(
Expand All @@ -276,30 +278,29 @@ public function render(): string
), 1601372376);
}


$contentRepository = $this->contentRepositoryRegistry->get($nodeAddress->contentRepositoryId);
$subgraph = $contentRepository->getContentGraph($nodeAddress->workspaceName)
->getSubgraph(
$nodeAddress->dimensionSpacePoint,
$node->subgraphIdentity->visibilityConstraints
);

$resolvedNode = $subgraph->findNodeById($nodeAddress->nodeAggregateId);
$resolvedNode = $subgraph->findNodeById($nodeAddress->aggregateId);
if ($resolvedNode === null) {
$this->throwableStorage->logThrowable(new ViewHelperException(sprintf(
'Failed to resolve node "%s" on subgraph "%s"',
$nodeAddress->nodeAggregateId->value,
$nodeAddress->aggregateId->value,
json_encode($subgraph, JSON_PARTIAL_OUTPUT_ON_ERROR)
), 1601372444));
}
if ($resolvedNode && $this->getNodeType($resolvedNode)->isOfType(NodeTypeNameFactory::NAME_SHORTCUT)) {
try {
$shortcutNodeAddress = $this->nodeShortcutResolver->resolveShortcutTarget(
$nodeAddress,
$contentRepository
$nodeAddress
);
if ($shortcutNodeAddress instanceof NodeAddress) {
$resolvedNode = $subgraph
->findNodeById($shortcutNodeAddress->nodeAggregateId);
->findNodeById($shortcutNodeAddress->aggregateId);
}
} catch (NodeNotFoundException | InvalidShortcutException $e) {
$this->throwableStorage->logThrowable(new ViewHelperException(sprintf(
Expand All @@ -310,30 +311,32 @@ public function render(): string
}
}

$uriBuilder = new UriBuilder();
$uriBuilder->setRequest($this->controllerContext->getRequest()->getMainRequest());
$uriBuilder->setFormat($this->arguments['format'])
->setCreateAbsoluteUri($this->arguments['absolute'])
->setArguments($this->arguments['arguments'])
->setSection($this->arguments['section'])
->setAddQueryString($this->arguments['addQueryString'])
->setArgumentsToBeExcludedFromQueryString($this->arguments['argumentsToBeExcludedFromQueryString']);
$nodeUriBuilder = $this->nodeUriBuilderFactory->forRequest($this->controllerContext->getRequest()->getHttpRequest());

// todo ->setAddQueryString($this->arguments['addQueryString'])
// todo ->setArgumentsToBeExcludedFromQueryString($this->arguments['argumentsToBeExcludedFromQueryString']);

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

try {
$uri = (string)NodeUriBuilder::fromUriBuilder($uriBuilder)->uriFor($nodeAddress);
} catch (
HttpException
| NoMatchingRouteException
| MissingActionNameException $e
) {
$uri = $this->arguments['absolute']
? $nodeUriBuilder->absoluteUriFor($specification)
: $nodeUriBuilder->uriFor($specification);

if ($this->arguments['section'] !== '') {
$uri = $uri->withFragment($this->arguments['section']);
}
} catch (NoMatchingRouteException $e) {
$this->throwableStorage->logThrowable(new ViewHelperException(sprintf(
'Failed to build URI for node: %s: %s',
$nodeAddress,
$nodeAddress->toJson(),
$e->getMessage()
), 1601372594, $e));
}
$this->tag->addAttribute('href', $uri);
$this->tag->addAttribute('href', (string)$uri);

$this->templateVariableContainer->add($this->arguments['nodeVariableName'], $resolvedNode);
$content = $this->renderChildren();
Expand All @@ -353,16 +356,15 @@ public function render(): string
* and "~" to the corresponding NodeAddress
*
* @param string $path
* @return NodeAddress
* @throws ViewHelperException
*/
private function resolveNodeAddressFromString(
string $path,
Node $documentNode,
ContentRepository $contentRepository
): NodeAddress {
): LegacyNodeAddress {
/* @var Node $documentNode */
$nodeAddressFactory = NodeAddressFactory::create($contentRepository);
$nodeAddressFactory = LegacyNodeAddressFactory::create($contentRepository);
$documentNodeAddress = $nodeAddressFactory->createFromNode($documentNode);
if (strncmp($path, 'node://', 7) === 0) {
return $documentNodeAddress->withNodeAggregateId(
Expand Down
77 changes: 41 additions & 36 deletions Neos.Neos/Classes/ViewHelpers/Uri/NodeViewHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,21 @@

use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindClosestNodeFilter;
use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId;
use Neos\ContentRepository\Core\Projection\ContentGraph\NodePath;
use Neos\Neos\Domain\Service\NodeTypeNameFactory;
use Neos\Neos\FrontendRouting\NodeAddress;
use Neos\Neos\FrontendRouting\NodeAddressFactory;
use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId;
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Http\Exception as HttpException;
use Neos\Flow\Log\ThrowableStorageInterface;
use Neos\Flow\Mvc\Exception\NoMatchingRouteException;
use Neos\Flow\Mvc\Routing\Exception\MissingActionNameException;
use Neos\Flow\Mvc\Routing\UriBuilder;
use Neos\FluidAdaptor\Core\ViewHelper\AbstractViewHelper;
use Neos\FluidAdaptor\Core\ViewHelper\Exception as ViewHelperException;
use Neos\Fusion\ViewHelpers\FusionContextTrait;
use Neos\Neos\FrontendRouting\NodeUriBuilder;
use Neos\Neos\Domain\Service\NodeTypeNameFactory;
use Neos\Neos\FrontendRouting\NodeAddress;
use Neos\Neos\FrontendRouting\NodeAddressFactory;
use Neos\Neos\FrontendRouting\NodeUriBuilderFactory;
use Neos\Neos\FrontendRouting\NodeUriSpecification;

/**
* A view helper for creating URIs pointing to nodes.
Expand Down Expand Up @@ -118,6 +116,13 @@ class NodeViewHelper extends AbstractViewHelper
*/
protected $throwableStorage;

/**
* @Flow\Inject
* @var NodeUriBuilderFactory
*/
protected $nodeUriBuilderFactory;


/**
* Initialize arguments
*
Expand Down Expand Up @@ -206,14 +211,17 @@ public function render(): string
$node = $this->getContextVariable($this->arguments['baseNodeName']);
}

/* @var Node $documentNode */
$documentNode = $this->getContextVariable('documentNode');

if ($node instanceof Node) {
$contentRepository = $this->contentRepositoryRegistry->get(
$node->subgraphIdentity->contentRepositoryId
);
$nodeAddressFactory = NodeAddressFactory::create($contentRepository);
$nodeAddress = $nodeAddressFactory->createFromNode($node);
$nodeAddress = $node->address;
} elseif (is_string($node)) {
$nodeAddress = $this->resolveNodeAddressFromString($node);
$nodeAddress = $this->resolveNodeAddressFromString($node, $documentNode)
?->toNewAddress($documentNode->subgraphIdentity->contentRepositoryId);
if (!$nodeAddress) {
return '';
}
} else {
throw new ViewHelperException(sprintf(
'The "node" argument can only be a string or an instance of %s. Given: %s',
Expand All @@ -222,33 +230,32 @@ public function render(): string
), 1601372376);
}

$uriBuilder = new UriBuilder();
$uriBuilder->setRequest($this->controllerContext->getRequest());
$uriBuilder->setFormat($this->arguments['format'])
->setCreateAbsoluteUri($this->arguments['absolute'])
->setArguments($this->arguments['arguments'])
->setSection($this->arguments['section'])
->setAddQueryString($this->arguments['addQueryString'])
->setArgumentsToBeExcludedFromQueryString($this->arguments['argumentsToBeExcludedFromQueryString']);
$nodeUriBuilder = $this->nodeUriBuilderFactory->forRequest($this->controllerContext->getRequest()->getHttpRequest());

// todo ->setAddQueryString($this->arguments['addQueryString'])
// todo ->setArgumentsToBeExcludedFromQueryString($this->arguments['argumentsToBeExcludedFromQueryString']);

$uri = '';
if (!$nodeAddress) {
return '';
}
$specification = NodeUriSpecification::create($nodeAddress)
->withFormat($this->arguments['format'])
->withRoutingArguments($this->arguments['arguments']);

try {
$uri = (string)NodeUriBuilder::fromUriBuilder($uriBuilder)->uriFor($nodeAddress);
} catch (
HttpException
| NoMatchingRouteException
| MissingActionNameException $e
) {
$uri = $this->arguments['absolute']
? $nodeUriBuilder->absoluteUriFor($specification)
: $nodeUriBuilder->uriFor($specification);

if ($this->arguments['section'] !== '') {
$uri = $uri->withFragment($this->arguments['section']);
}
} catch (NoMatchingRouteException $e) {
$this->throwableStorage->logThrowable(new ViewHelperException(sprintf(
'Failed to build URI for node: %s: %s',
$nodeAddress,
$nodeAddress->toJson(),
$e->getMessage()
), 1601372594, $e));
}
return $uri;
return (string)$uri;
}

/**
Expand All @@ -259,10 +266,8 @@ public function render(): string
* @return \Neos\Neos\FrontendRouting\NodeAddress
* @throws ViewHelperException
*/
private function resolveNodeAddressFromString(string $path): ?NodeAddress
private function resolveNodeAddressFromString(string $path, Node $documentNode): ?NodeAddress
{
/* @var Node $documentNode */
$documentNode = $this->getContextVariable('documentNode');
$contentRepository = $this->contentRepositoryRegistry->get(
$documentNode->subgraphIdentity->contentRepositoryId
);
Expand Down

0 comments on commit d0cdf6f

Please sign in to comment.