Skip to content

Commit

Permalink
TASK: Adjust to introduction of Shared\NodeAddress and new NodeUriBui…
Browse files Browse the repository at this point in the history
…lder
  • Loading branch information
mhsdesign committed Jun 18, 2024
1 parent ee3533b commit 02e71d2
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 50 deletions.
39 changes: 13 additions & 26 deletions Classes/CatchUpHook/DocumentUriPathProjectionHook.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Neos\ContentRepository\Core\Projection\CatchUpHookInterface;
use Neos\ContentRepository\Core\ContentRepository;
use Neos\ContentRepository\Core\EventStore\EventInterface;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress;
use Neos\EventStore\Model\EventEnvelope;
use Neos\ContentRepository\Core\Feature\NodeModification\Event\NodePropertiesWereSet;
use Neos\ContentRepository\Core\Feature\NodeMove\Event\NodeAggregateWasMoved;
Expand All @@ -15,11 +16,7 @@
use Neos\ContentRepository\Core\Feature\NodeMove\Dto\CoverageNodeMoveMapping;
use Neos\Neos\FrontendRouting\Projection\DocumentNodeInfo;
use Neos\Neos\FrontendRouting\Exception\NodeNotFoundException;
use Neos\Neos\FrontendRouting\NodeAddress;
use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId;
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
use Neos\Neos\FrontendRouting\NodeAddressFactory;

final class DocumentUriPathProjectionHook implements CatchUpHookInterface
{
Expand Down Expand Up @@ -87,8 +84,7 @@ private function onBeforeNodeAggregateWasRemoved(NodeAggregateWasRemoved $event)

$this->nodeRedirectService->appendAffectedNode(
$node,
$this->getNodeAddress($event->contentStreamId, $dimensionSpacePoint, $node->getNodeAggregateId()),
$this->contentRepository->id
NodeAddress::create($this->contentRepository->id, $event->workspaceName, $dimensionSpacePoint, $node->getNodeAggregateId())
);
$this->documentNodeInfosBeforeRemoval[$dimensionSpacePoint->hash][] = $node;

Expand All @@ -97,8 +93,7 @@ private function onBeforeNodeAggregateWasRemoved(NodeAggregateWasRemoved $event)
function ($descendantOfNode) use ($event, $dimensionSpacePoint) {
$this->nodeRedirectService->appendAffectedNode(
$descendantOfNode,
$this->getNodeAddress($event->contentStreamId, $dimensionSpacePoint, $descendantOfNode->getNodeAggregateId()),
$this->contentRepository->id
NodeAddress::create($this->contentRepository->id, $event->workspaceName, $dimensionSpacePoint, $descendantOfNode->getNodeAggregateId())
);
$this->documentNodeInfosBeforeRemoval[$dimensionSpacePoint->hash][] = $descendantOfNode;
},
Expand Down Expand Up @@ -146,6 +141,9 @@ private function onAfterNodePropertiesWereSet(NodePropertiesWereSet $event): voi
);
}

/**
* @param \Closure(DocumentNodeInfo $nodeInfo, NodeAddress $nodeAddress):void $closure
*/
private function handleNodePropertiesWereSet(NodePropertiesWereSet $event, \Closure $closure): void
{
if (!$this->isLiveContentStream($event->contentStreamId)) {
Expand All @@ -164,13 +162,12 @@ private function handleNodePropertiesWereSet(NodePropertiesWereSet $event, \Clos
continue;
}

$closure($node, $this->getNodeAddress($event->contentStreamId, $affectedDimensionSpacePoint, $node->getNodeAggregateId()), $this->contentRepository->id);
$closure($node, NodeAddress::create($this->contentRepository->id, $event->workspaceName, $affectedDimensionSpacePoint, $node->getNodeAggregateId()));

$descendantsOfNode = $this->getState()->getDescendantsOfNode($node);
array_map(fn (DocumentNodeInfo $descendantOfNode) => $closure(
$descendantOfNode,
$this->getNodeAddress($event->contentStreamId, $affectedDimensionSpacePoint, $descendantOfNode->getNodeAggregateId()),
$this->contentRepository->id
NodeAddress::create($this->contentRepository->id, $event->workspaceName, $affectedDimensionSpacePoint, $descendantOfNode->getNodeAggregateId())
), iterator_to_array($descendantsOfNode));
}
}
Expand All @@ -191,6 +188,9 @@ private function onAfterNodeAggregateWasMoved(NodeAggregateWasMoved $event): voi
);
}

/**
* @param \Closure(DocumentNodeInfo $nodeInfo, NodeAddress $nodeAddress):void $closure
*/
private function handleNodeWasMoved(NodeAggregateWasMoved $event, \Closure $closure): void
{
if (!$this->isLiveContentStream($event->contentStreamId)) {
Expand All @@ -207,13 +207,12 @@ private function handleNodeWasMoved(NodeAggregateWasMoved $event, \Closure $clos
continue;
}

$closure($node, $this->getNodeAddress($event->contentStreamId, $newLocation->coveredDimensionSpacePoint, $node->getNodeAggregateId()), $this->contentRepository->id);
$closure($node, NodeAddress::create($this->contentRepository->id, $event->workspaceName, $newLocation->coveredDimensionSpacePoint, $node->getNodeAggregateId()));

$descendantsOfNode = $this->getState()->getDescendantsOfNode($node);
array_map(fn (DocumentNodeInfo $descendantOfNode) => $closure(
$descendantOfNode,
$this->getNodeAddress($event->contentStreamId, $newLocation->coveredDimensionSpacePoint, $descendantOfNode->getNodeAggregateId()),
$this->contentRepository->id
NodeAddress::create($this->contentRepository->id, $event->workspaceName, $newLocation->coveredDimensionSpacePoint, $descendantOfNode->getNodeAggregateId())
), iterator_to_array($descendantsOfNode));
}
}
Expand All @@ -237,16 +236,4 @@ private function findNodeByIdAndDimensionSpacePointHash(NodeAggregateId $nodeAgg
return null;
}
}

protected function getNodeAddress(
ContentStreamId $contentStreamId,
DimensionSpacePoint $dimensionSpacePoint,
NodeAggregateId $nodeAggregateId,
): NodeAddress {
return NodeAddressFactory::create($this->contentRepository)->createFromContentStreamIdAndDimensionSpacePointAndNodeAggregateId(
$contentStreamId,
$dimensionSpacePoint,
$nodeAggregateId
);
}
}
48 changes: 24 additions & 24 deletions Classes/Service/NodeRedirectService.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@
* source code.
*/

use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Persistence\PersistenceManagerInterface;
use Neos\Neos\Domain\Model\Domain;
use Neos\Neos\Domain\Model\SiteNodeName;
use Neos\Neos\Domain\Repository\SiteRepository;
use Neos\Neos\FrontendRouting\NodeUriBuilderFactory;
use Neos\RedirectHandler\Storage\RedirectStorageInterface;
use Psr\Http\Message\UriInterface;
use Psr\Log\LoggerInterface;
use Neos\ContentRepository\Core\NodeType\NodeType;
use Neos\Neos\FrontendRouting\NodeUriBuilder;
Expand All @@ -27,7 +30,6 @@
use Neos\Neos\FrontendRouting\SiteDetection\SiteDetectionResult;
use Neos\Flow\Mvc\ActionRequest;
use Neos\Neos\FrontendRouting\Projection\DocumentNodeInfo;
use Neos\Neos\FrontendRouting\NodeAddress;
use Neos\ContentRepository\Core\NodeType\NodeTypeName;
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
use GuzzleHttp\Psr7\Uri;
Expand All @@ -45,7 +47,13 @@ final class NodeRedirectService
const STATUS_CODE_TYPE_REDIRECT = 'redirect';
const STATUS_CODE_TYPE_GONE = 'gone';

/**
* @var array<string,array{node:DocumentNodeInfo,url:UriInterface}|null>
*/
private array $affectedNodes = [];
/**
* @var array<string,list<string>>
*/
private array $hostnamesRuntimeCache = [];

#[Flow\Inject]
Expand Down Expand Up @@ -76,57 +84,52 @@ final class NodeRedirectService
protected array $restrictByNodeType = [];

public function __construct(
protected RedirectStorageInterface $redirectStorage,
protected PersistenceManagerInterface $persistenceManager,
protected ContentRepositoryRegistry $contentRepositoryRegistry,
protected SiteRepository $siteRepository,
private readonly RedirectStorageInterface $redirectStorage,
private readonly PersistenceManagerInterface $persistenceManager,
private readonly ContentRepositoryRegistry $contentRepositoryRegistry,
private readonly SiteRepository $siteRepository,
private readonly NodeUriBuilderFactory $nodeUriBuilderFactory
) {
}

/**
* Collects affected nodes before they got moved or removed.
*
* @throws \Neos\Flow\Http\Exception
* @throws \Neos\Flow\Mvc\Routing\Exception\MissingActionNameException
*/
public function appendAffectedNode(DocumentNodeInfo $nodeInfo, NodeAddress $nodeAddress, ContentRepositoryId $contentRepositoryId): void
public function appendAffectedNode(DocumentNodeInfo $nodeInfo, NodeAddress $nodeAddress): void
{
try {
$this->affectedNodes[$this->createAffectedNodesKey($nodeInfo, $contentRepositoryId)] = [
$this->affectedNodes[$this->createAffectedNodesKey($nodeInfo, $nodeAddress->contentRepositoryId)] = [
'node' => $nodeInfo,
'url' => $this->getNodeUriBuilder($nodeInfo->getSiteNodeName(), $contentRepositoryId)->uriFor($nodeAddress),
'url' => $this->getNodeUriBuilder($nodeInfo->getSiteNodeName(), $nodeAddress->contentRepositoryId)->uriFor($nodeAddress),
];
} catch (NoMatchingRouteException $exception) {
}
}

/**
* Creates redirects for given node and uses the collected affected nodes to determine the source of the new redirect target.
*
* @throws \Neos\Flow\Http\Exception
* @throws \Neos\Flow\Mvc\Routing\Exception\MissingActionNameException
*/
public function createRedirectForAffectedNode(DocumentNodeInfo $nodeInfo, NodeAddress $nodeAddress, ContentRepositoryId $contentRepositoryId): void
public function createRedirectForAffectedNode(DocumentNodeInfo $nodeInfo, NodeAddress $nodeAddress): void
{
if (!$this->enableAutomaticRedirects) {
return;
}

$affectedNode = $this->affectedNodes[$this->createAffectedNodesKey($nodeInfo, $contentRepositoryId)] ?? null;
$affectedNode = $this->affectedNodes[$this->createAffectedNodesKey($nodeInfo, $nodeAddress->contentRepositoryId)] ?? null;
if ($affectedNode === null) {
return;
}
unset($this->affectedNodes[$this->createAffectedNodesKey($nodeInfo, $contentRepositoryId)]);
unset($this->affectedNodes[$this->createAffectedNodesKey($nodeInfo, $nodeAddress->contentRepositoryId)]);

/** @var Uri $oldUri */
$oldUri = $affectedNode['url'];
$nodeType = $this->getNodeType($contentRepositoryId, $nodeInfo->getNodeTypeName());
$nodeType = $this->getNodeType($nodeAddress->contentRepositoryId, $nodeInfo->getNodeTypeName());

if ($this->isRestrictedByNodeType($nodeType) || $this->isRestrictedByOldUri($oldUri->getPath())) {
return;
}
try {
$newUri = $this->getNodeUriBuilder($nodeInfo->getSiteNodeName(), $contentRepositoryId)->uriFor($nodeAddress);
$newUri = $this->getNodeUriBuilder($nodeInfo->getSiteNodeName(), $nodeAddress->contentRepositoryId)->uriFor($nodeAddress);
} catch (NoMatchingRouteException $exception) {
// We can't build an uri for given node, so we can't create any redirect. E.g.: Node is disabled.
return;
Expand Down Expand Up @@ -179,15 +182,12 @@ protected function getNodeUriBuilder(SiteNodeName $siteNodeName, ContentReposito
// Generate a custom request when the current request was triggered from CLI
$baseUri = 'http://localhost';

// Prevent `index.php` appearing in generated redirects
putenv('FLOW_REWRITEURLS=1');

$httpRequest = new ServerRequest('POST', $baseUri);

$httpRequest = (SiteDetectionResult::create($siteNodeName, $contentRepositoryId))->storeInRequest($httpRequest);
$actionRequest = ActionRequest::fromHttpRequest($httpRequest);

return NodeUriBuilder::fromRequest($actionRequest);
return $this->nodeUriBuilderFactory->forActionRequest($actionRequest);
}

/**
Expand Down Expand Up @@ -283,7 +283,7 @@ protected function isRestrictedByOldUri(string $oldUriPath): bool

/**
* Collects all hostnames from the Domain entries attached to the current site.
* @return array<string, array<string>>
* @return list<string>
*/
protected function getHostnames(SiteNodeName $siteNodeName): array
{
Expand Down

0 comments on commit 02e71d2

Please sign in to comment.