diff --git a/Classes/Application/ChangeTargetWorkspace.php b/Classes/Application/ChangeTargetWorkspace.php index 18f34e5301..07fd682fe7 100644 --- a/Classes/Application/ChangeTargetWorkspace.php +++ b/Classes/Application/ChangeTargetWorkspace.php @@ -15,9 +15,9 @@ namespace Neos\Neos\Ui\Application; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; use Neos\Flow\Annotations as Flow; -use Neos\Neos\FrontendRouting\NodeAddress; /** * The application layer level command DTO to communicate the change of the selected target workspace for publication diff --git a/Classes/Application/ReloadNodes/NodeMap.php b/Classes/Application/ReloadNodes/NodeMap.php index 60285ffed8..38b08093ce 100644 --- a/Classes/Application/ReloadNodes/NodeMap.php +++ b/Classes/Application/ReloadNodes/NodeMap.php @@ -14,10 +14,8 @@ namespace Neos\Neos\Ui\Application\ReloadNodes; -use Neos\ContentRepository\Core\ContentRepository; use Neos\Flow\Annotations as Flow; use Neos\Flow\Mvc\ActionRequest; -use Neos\Neos\FrontendRouting\NodeAddress; use Neos\Neos\Ui\Fusion\Helper\NodeInfoHelper; /** diff --git a/Classes/Application/ReloadNodes/ReloadNodesQueryHandler.php b/Classes/Application/ReloadNodes/ReloadNodesQueryHandler.php index b53287e2d5..2b05c6903d 100644 --- a/Classes/Application/ReloadNodes/ReloadNodesQueryHandler.php +++ b/Classes/Application/ReloadNodes/ReloadNodesQueryHandler.php @@ -19,11 +19,11 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\NodeType\NodeTypeCriteria; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; use Neos\Flow\Mvc\ActionRequest; use Neos\Neos\Domain\Service\NodeTypeNameFactory; -use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\Neos\Ui\Fusion\Helper\NodeInfoHelper; /** @@ -148,10 +148,8 @@ public function handle(ReloadNodesQuery $query, ActionRequest $actionRequest): R - but the logic above mirrors the old behavior better. https://github.com/neos/neos-ui/issues/3517#issuecomment-2070274053 */ - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); - return new ReloadNodesQueryResult( - documentId: $nodeAddressFactory->createFromNode($documentNode), + documentId: NodeAddress::fromNode($documentNode), nodes: $nodeMapBuilder->build() ); } diff --git a/Classes/Application/ReloadNodes/ReloadNodesQueryResult.php b/Classes/Application/ReloadNodes/ReloadNodesQueryResult.php index 0775bb03f9..69fa39cc3f 100644 --- a/Classes/Application/ReloadNodes/ReloadNodesQueryResult.php +++ b/Classes/Application/ReloadNodes/ReloadNodesQueryResult.php @@ -14,8 +14,8 @@ namespace Neos\Neos\Ui\Application\ReloadNodes; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\Flow\Annotations as Flow; -use Neos\Neos\FrontendRouting\NodeAddress; /** * The application layer level query result containing all nodes the UI needs @@ -38,7 +38,7 @@ public function __construct( public function jsonSerialize(): array { return [ - 'documentId' => $this->documentId->serializeForUri(), + 'documentId' => $this->documentId->toJson(), 'nodes' => $this->nodes ]; } diff --git a/Classes/ContentRepository/Service/NeosUiNodeService.php b/Classes/ContentRepository/Service/NeosUiNodeService.php index b0185b7cb1..07d0b8ee35 100644 --- a/Classes/ContentRepository/Service/NeosUiNodeService.php +++ b/Classes/ContentRepository/Service/NeosUiNodeService.php @@ -12,14 +12,11 @@ */ -use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; -use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; -use Neos\Neos\FrontendRouting\NodeAddress; -use Neos\Neos\Utility\NodeTypeWithFallbackProvider; /** * @internal @@ -27,26 +24,18 @@ */ class NeosUiNodeService { - use NodeTypeWithFallbackProvider; - #[Flow\Inject] protected ContentRepositoryRegistry $contentRepositoryRegistry; - public function findNodeBySerializedNodeAddress(string $serializedNodeAddress, ContentRepositoryId $contentRepositoryId): ?Node + public function findNodeBySerializedNodeAddress(string $serializedNodeAddress): ?Node { - $contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId); - $nodeAddress = NodeAddressFactory::create($contentRepository)->createFromUriString($serializedNodeAddress); + $nodeAddress = NodeAddress::fromJsonString($serializedNodeAddress); + $contentRepository = $this->contentRepositoryRegistry->get($nodeAddress->contentRepositoryId); $subgraph = $contentRepository->getContentGraph($nodeAddress->workspaceName)->getSubgraph( $nodeAddress->dimensionSpacePoint, VisibilityConstraints::withoutRestrictions() ); - return $subgraph->findNodeById($nodeAddress->nodeAggregateId); - } - - public function deserializeNodeAddress(string $serializedNodeAddress, ContentRepositoryId $contentRepositoryId): NodeAddress - { - $contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId); - return NodeAddressFactory::create($contentRepository)->createFromUriString($serializedNodeAddress); + return $subgraph->findNodeById($nodeAddress->aggregateId); } } diff --git a/Classes/ContentRepository/Service/WorkspaceService.php b/Classes/ContentRepository/Service/WorkspaceService.php index 479d2f077f..43cb89155f 100644 --- a/Classes/ContentRepository/Service/WorkspaceService.php +++ b/Classes/ContentRepository/Service/WorkspaceService.php @@ -14,14 +14,13 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindClosestNodeFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; use Neos\Neos\Domain\Service\NodeTypeNameFactory; use Neos\Neos\Domain\Service\WorkspacePublishingService; -use Neos\Neos\FrontendRouting\NodeAddress; -use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\Neos\PendingChangesProjection\Change; use Neos\Neos\Utility\NodeTypeWithFallbackProvider; @@ -57,26 +56,26 @@ public function getPublishableNodeInfo(WorkspaceName $workspaceName, ContentRepo $unpublishedNodes = []; foreach ($pendingChanges as $change) { if ($change->removalAttachmentPoint) { - $nodeAddress = new NodeAddress( - $change->contentStreamId, + $nodeAddress = NodeAddress::create( + $contentRepositoryId, + $workspaceName, $change->originDimensionSpacePoint->toDimensionSpacePoint(), - $change->nodeAggregateId, - $workspaceName + $change->nodeAggregateId ); /** * See {@see Remove::apply} -> Removal Attachment Point == closest document node. */ - $documentNodeAddress = new NodeAddress( - $change->contentStreamId, + $documentNodeAddress = NodeAddress::create( + $contentRepositoryId, + $workspaceName, $change->originDimensionSpacePoint->toDimensionSpacePoint(), - $change->removalAttachmentPoint, - $workspaceName + $change->removalAttachmentPoint ); $unpublishedNodes[] = [ - 'contextPath' => $nodeAddress->serializeForUri(), - 'documentContextPath' => $documentNodeAddress->serializeForUri(), + 'contextPath' => $nodeAddress->toJson(), + 'documentContextPath' => $documentNodeAddress->toJson(), 'typeOfChange' => $this->getTypeOfChange($change) ]; } else { @@ -89,11 +88,9 @@ public function getPublishableNodeInfo(WorkspaceName $workspaceName, ContentRepo if ($node instanceof Node) { $documentNode = $subgraph->findClosestNode($node->aggregateId, FindClosestNodeFilter::create(nodeTypes: NodeTypeNameFactory::NAME_DOCUMENT)); if ($documentNode instanceof Node) { - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); $unpublishedNodes[] = [ - 'contextPath' => $nodeAddressFactory->createFromNode($node)->serializeForUri(), - 'documentContextPath' => $nodeAddressFactory->createFromNode($documentNode) - ->serializeForUri(), + 'contextPath' => NodeAddress::fromNode($node)->toJson(), + 'documentContextPath' => NodeAddress::fromNode($documentNode)->toJson(), 'typeOfChange' => $this->getTypeOfChange($change) ]; } diff --git a/Classes/Controller/BackendController.php b/Classes/Controller/BackendController.php index 60dfb5b8dc..0be2b353f2 100644 --- a/Classes/Controller/BackendController.php +++ b/Classes/Controller/BackendController.php @@ -23,7 +23,6 @@ use Neos\Neos\Domain\Repository\SiteRepository; use Neos\Neos\Domain\Service\NodeTypeNameFactory; use Neos\Neos\Domain\Service\WorkspaceService; -use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\Neos\FrontendRouting\NodeUriBuilderFactory; use Neos\Neos\FrontendRouting\SiteDetection\SiteDetectionResult; use Neos\Neos\Service\UserService; @@ -136,7 +135,7 @@ public function indexAction(string $node = null) $siteDetectionResult = SiteDetectionResult::fromRequest($this->request->getHttpRequest()); $contentRepository = $this->contentRepositoryRegistry->get($siteDetectionResult->contentRepositoryId); - $nodeAddress = $node !== null ? NodeAddressFactory::create($contentRepository)->createFromUriString($node) : null; + $nodeAddress = $node !== null ? NodeAddress::fromJsonString($node) : null; $user = $this->userService->getBackendUser(); if ($user === null) { @@ -180,7 +179,7 @@ public function indexAction(string $node = null) if (!$nodeAddress) { $node = $siteNode; } else { - $node = $subgraph->findNodeById($nodeAddress->nodeAggregateId); + $node = $subgraph->findNodeById($nodeAddress->aggregateId); } $this->view->setOption('title', 'Neos CMS'); diff --git a/Classes/Controller/BackendServiceController.php b/Classes/Controller/BackendServiceController.php index faa6f7217f..a346851e46 100644 --- a/Classes/Controller/BackendServiceController.php +++ b/Classes/Controller/BackendServiceController.php @@ -20,6 +20,7 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; use Neos\ContentRepository\Core\SharedModel\Exception\NodeAggregateCurrentlyDoesNotExist; use Neos\ContentRepository\Core\SharedModel\Exception\NodeAggregateDoesCurrentlyNotCoverDimensionSpacePoint; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Eel\FlowQuery\FlowQuery; @@ -33,8 +34,6 @@ use Neos\Flow\Security\Context; use Neos\Neos\Domain\Service\WorkspacePublishingService; use Neos\Neos\Domain\Service\WorkspaceService; -use Neos\Neos\FrontendRouting\NodeAddress; -use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\Neos\FrontendRouting\SiteDetection\SiteDetectionResult; use Neos\Neos\Service\UserService; use Neos\Neos\Ui\Application\ChangeTargetWorkspace; @@ -207,10 +206,9 @@ public function publishChangesInSiteAction(array $command): void /** @todo send from UI */ $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; $command['contentRepositoryId'] = $contentRepositoryId->value; - $command['siteId'] = $this->nodeService->deserializeNodeAddress( - $command['siteId'], - $contentRepositoryId - )->nodeAggregateId->value; + $command['siteId'] = NodeAddress::fromJsonString( + $command['siteId'] + )->aggregateId->value; $command = PublishChangesInSite::fromArray($command); $publishingResult = $this->workspacePublishingService->publishChangesInSite( $command->contentRepositoryId, @@ -246,10 +244,9 @@ public function publishChangesInDocumentAction(array $command): void /** @todo send from UI */ $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; $command['contentRepositoryId'] = $contentRepositoryId->value; - $command['documentId'] = $this->nodeService->deserializeNodeAddress( - $command['documentId'], - $contentRepositoryId - )->nodeAggregateId->value; + $command['documentId'] = NodeAddress::fromJsonString( + $command['documentId'] + )->aggregateId->value; $command = PublishChangesInDocument::fromArray($command); try { @@ -336,10 +333,9 @@ public function discardChangesInSiteAction(array $command): void /** @todo send from UI */ $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; $command['contentRepositoryId'] = $contentRepositoryId->value; - $command['siteId'] = $this->nodeService->deserializeNodeAddress( - $command['siteId'], - $contentRepositoryId - )->nodeAggregateId->value; + $command['siteId'] = NodeAddress::fromJsonString( + $command['siteId'] + )->aggregateId->value; $command = DiscardChangesInSite::fromArray($command); $discardingResult = $this->workspacePublishingService->discardChangesInSite( @@ -376,10 +372,9 @@ public function discardChangesInDocumentAction(array $command): void /** @todo send from UI */ $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; $command['contentRepositoryId'] = $contentRepositoryId->value; - $command['documentId'] = $this->nodeService->deserializeNodeAddress( - $command['documentId'], - $contentRepositoryId - )->nodeAggregateId->value; + $command['documentId'] = NodeAddress::fromJsonString( + $command['documentId'] + )->aggregateId->value; $command = DiscardChangesInDocument::fromArray($command); $discardingResult = $this->workspacePublishingService->discardChangesInDocument( @@ -415,10 +410,7 @@ public function discardChangesInDocumentAction(array $command): void */ public function changeBaseWorkspaceAction(string $targetWorkspaceName, string $documentNode): void { - $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; - $contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId); - - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); + $documentNodeAddress = NodeAddress::fromJsonString($documentNode); $user = $this->userService->getBackendUser(); if ($user === null) { @@ -428,18 +420,18 @@ public function changeBaseWorkspaceAction(string $targetWorkspaceName, string $d $this->view->assign('value', $this->feedbackCollection); return; } - $userWorkspace = $this->workspaceService->getPersonalWorkspaceForUser($contentRepositoryId, $user->getId()); + $userWorkspace = $this->workspaceService->getPersonalWorkspaceForUser($documentNodeAddress->contentRepositoryId, $user->getId()); /** @todo send from UI */ $command = new ChangeTargetWorkspace( - $contentRepositoryId, + $documentNodeAddress->contentRepositoryId, $userWorkspace->workspaceName, WorkspaceName::fromString($targetWorkspaceName), - $nodeAddressFactory->createFromUriString($documentNode) + $documentNodeAddress ); try { - $this->workspacePublishingService->changeBaseWorkspace($contentRepositoryId, $userWorkspace->workspaceName, WorkspaceName::fromString($targetWorkspaceName)); + $this->workspacePublishingService->changeBaseWorkspace($documentNodeAddress->contentRepositoryId, $userWorkspace->workspaceName, WorkspaceName::fromString($targetWorkspaceName)); } catch (WorkspaceIsNotEmptyException $exception) { $error = new Error(); $error->setMessage( @@ -458,13 +450,14 @@ public function changeBaseWorkspaceAction(string $targetWorkspaceName, string $d return; } + $contentRepository = $this->contentRepositoryRegistry->get($documentNodeAddress->contentRepositoryId); $subgraph = $contentRepository->getContentGraph($userWorkspace->workspaceName) ->getSubgraph( $command->documentNode->dimensionSpacePoint, VisibilityConstraints::withoutRestrictions() ); - $documentNodeInstance = $subgraph->findNodeById($command->documentNode->nodeAggregateId); + $documentNodeInstance = $subgraph->findNodeById($command->documentNode->aggregateId); assert($documentNodeInstance !== null); $success = new Success(); @@ -473,7 +466,7 @@ public function changeBaseWorkspaceAction(string $targetWorkspaceName, string $d ); $this->feedbackCollection->add($success); - $updateWorkspaceInfo = new UpdateWorkspaceInfo($contentRepositoryId, $userWorkspace->workspaceName); + $updateWorkspaceInfo = new UpdateWorkspaceInfo($command->contentRepositoryId, $userWorkspace->workspaceName); $this->feedbackCollection->add($updateWorkspaceInfo); // If current document node doesn't exist in the base workspace, @@ -524,13 +517,9 @@ public function changeBaseWorkspaceAction(string $targetWorkspaceName, string $d */ public function copyNodesAction(array $nodes): void { - $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; - $contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId); - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); - /** @var array $nodeAddresses */ $nodeAddresses = array_map( - fn (string $serializedNodeAddress) => $nodeAddressFactory->createFromUriString($serializedNodeAddress), + NodeAddress::fromJsonString(...), $nodes ); $this->clipboard->copyNodes($nodeAddresses); @@ -555,13 +544,9 @@ public function clearClipboardAction() */ public function cutNodesAction(array $nodes): void { - $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; - $contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId); - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); - - /** @var array $nodeAddresses */ + /** @var array $nodeAddresses */ $nodeAddresses = array_map( - fn (string $serializedNodeAddress) => $nodeAddressFactory->createFromUriString($serializedNodeAddress), + NodeAddress::fromJsonString(...), $nodes ); @@ -590,25 +575,22 @@ public function initializeGetAdditionalNodeMetadataAction(): void */ public function getAdditionalNodeMetadataAction(array $nodes): void { - $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; - $contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId); - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); - $result = []; foreach ($nodes as $nodeAddressString) { - $nodeAddress = $nodeAddressFactory->createFromUriString($nodeAddressString); + $nodeAddress = NodeAddress::fromJsonString($nodeAddressString); + $contentRepository = $this->contentRepositoryRegistry->get($nodeAddress->contentRepositoryId); $subgraph = $contentRepository->getContentGraph($nodeAddress->workspaceName)->getSubgraph( $nodeAddress->dimensionSpacePoint, VisibilityConstraints::withoutRestrictions() ); - $node = $subgraph->findNodeById($nodeAddress->nodeAggregateId); + $node = $subgraph->findNodeById($nodeAddress->aggregateId); // TODO finish implementation /*$otherNodeVariants = array_values(array_filter(array_map(function ($node) { return $this->getCurrentDimensionPresetIdentifiersForNode($node); }, $node->getOtherNodeVariants())));*/ if (!is_null($node)) { - $result[$nodeAddress->serializeForUri()] = [ + $result[$nodeAddress->toJson()] = [ // todo reimplement nodePolicyService 'policy' => [ 'disallowedNodeTypes' => [], @@ -638,18 +620,16 @@ public function initializeGetPolicyInformationAction(): void */ public function getPolicyInformationAction(array $nodes): void { - $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; - $contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId); - $result = []; foreach ($nodes as $nodeAddress) { + $contentRepository = $this->contentRepositoryRegistry->get($nodeAddress->contentRepositoryId); $subgraph = $contentRepository->getContentGraph($nodeAddress->workspaceName)->getSubgraph( $nodeAddress->dimensionSpacePoint, VisibilityConstraints::withoutRestrictions() ); - $node = $subgraph->findNodeById($nodeAddress->nodeAggregateId); + $node = $subgraph->findNodeById($nodeAddress->aggregateId); if (!is_null($node)) { - $result[$nodeAddress->serializeForUri()] = [ + $result[$nodeAddress->toJson()] = [ // todo reimplement nodePolicyService 'policy' => [ 'disallowedNodeTypes' => [], @@ -682,8 +662,7 @@ public function flowQueryAction(array $chain): string $flowQuery = new FlowQuery( array_map( fn ($nodeContextPath) => $this->nodeService->findNodeBySerializedNodeAddress( - $nodeContextPath, - $contentRepositoryId + $nodeContextPath ), $nodeContextPaths ) @@ -723,16 +702,13 @@ public function flowQueryAction(array $chain): string */ public function generateUriPathSegmentAction(string $contextNode, string $text): void { - $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; - $contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId); - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); - - $contextNodeAddress = $nodeAddressFactory->createFromUriString($contextNode); + $contextNodeAddress = NodeAddress::fromJsonString($contextNode); + $contentRepository = $this->contentRepositoryRegistry->get($contextNodeAddress->contentRepositoryId); $subgraph = $contentRepository->getContentGraph($contextNodeAddress->workspaceName)->getSubgraph( $contextNodeAddress->dimensionSpacePoint, VisibilityConstraints::withoutRestrictions() ); - $contextNode = $subgraph->findNodeById($contextNodeAddress->nodeAggregateId); + $contextNode = $subgraph->findNodeById($contextNodeAddress->aggregateId); $slug = $this->nodeUriPathSegmentGenerator->generateUriPathSegment($contextNode, $text); $this->view->assign('value', $slug); @@ -795,36 +771,31 @@ public function reloadNodesAction(array $query): void /** @todo send from UI */ $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; $query['contentRepositoryId'] = $contentRepositoryId->value; - $query['siteId'] = $this->nodeService->deserializeNodeAddress( - $query['siteId'], - $contentRepositoryId - )->nodeAggregateId->value; - $query['documentId'] = $this->nodeService->deserializeNodeAddress( - $query['documentId'], - $contentRepositoryId - )->nodeAggregateId->value; + $query['siteId'] = NodeAddress::fromJsonString( + $query['siteId'] + )->aggregateId->value; + $query['documentId'] = NodeAddress::fromJsonString( + $query['documentId'] + )->aggregateId->value; $query['ancestorsOfDocumentIds'] = array_map( fn (string $nodeAddress) => - $this->nodeService->deserializeNodeAddress( - $nodeAddress, - $contentRepositoryId - )->nodeAggregateId->value, + NodeAddress::fromJsonString( + $nodeAddress + )->aggregateId->value, $query['ancestorsOfDocumentIds'] ); $query['toggledNodesIds'] = array_map( fn (string $nodeAddress) => - $this->nodeService->deserializeNodeAddress( - $nodeAddress, - $contentRepositoryId - )->nodeAggregateId->value, + NodeAddress::fromJsonString( + $nodeAddress + )->aggregateId->value, $query['toggledNodesIds'] ); $query['clipboardNodesIds'] = array_map( fn (string $nodeAddress) => - $this->nodeService->deserializeNodeAddress( - $nodeAddress, - $contentRepositoryId - )->nodeAggregateId->value, + NodeAddress::fromJsonString( + $nodeAddress + )->aggregateId->value, $query['clipboardNodesIds'] ); $query = ReloadNodesQuery::fromArray($query); diff --git a/Classes/Domain/Model/Changes/AbstractStructuralChange.php b/Classes/Domain/Model/Changes/AbstractStructuralChange.php index f3dafdb559..1293f58c3e 100644 --- a/Classes/Domain/Model/Changes/AbstractStructuralChange.php +++ b/Classes/Domain/Model/Changes/AbstractStructuralChange.php @@ -16,9 +16,9 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindChildNodesFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\ContentGraph\Nodes; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateClassification; use Neos\Flow\Annotations as Flow; -use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\Neos\Ui\ContentRepository\Service\NeosUiNodeService; use Neos\Neos\Ui\Domain\Model\AbstractChange; use Neos\Neos\Ui\Domain\Model\Feedback\Operations\ReloadDocument; @@ -108,8 +108,7 @@ public function getSiblingNode(): ?Node if ($this->cachedSiblingNode === null) { $this->cachedSiblingNode = $this->nodeService->findNodeBySerializedNodeAddress( - $this->siblingDomAddress->getContextPath(), - $this->getSubject()->contentRepositoryId + $this->siblingDomAddress->getContextPath() ); } @@ -148,14 +147,13 @@ protected function finish(Node $node) // 1) the parent of our new (or copied or moved) node is a ContentCollection; // so we can directly update an element of this content collection - $contentRepository = $this->contentRepositoryRegistry->get($node->contentRepositoryId); if ($parentNode && $this->getNodeType($parentNode)?->isOfType('Neos.Neos:ContentCollection') && // 2) the parent DOM address (i.e. the closest RENDERED node in DOM is actually the ContentCollection; // and no other node in between $this->getParentDomAddress() && $this->getParentDomAddress()->getFusionPath() && $this->getParentDomAddress()->getContextPath() === - NodeAddressFactory::create($contentRepository)->createFromNode($parentNode)->serializeForUri() + NodeAddress::fromNode($parentNode)->toJson() ) { $renderContentOutOfBand = new RenderContentOutOfBand(); $renderContentOutOfBand->setNode($node); diff --git a/Classes/Domain/Model/Changes/CopyInto.php b/Classes/Domain/Model/Changes/CopyInto.php index 8940173219..bdd1188b7a 100644 --- a/Classes/Domain/Model/Changes/CopyInto.php +++ b/Classes/Domain/Model/Changes/CopyInto.php @@ -15,7 +15,6 @@ use Neos\ContentRepository\Core\DimensionSpace\OriginDimensionSpacePoint; use Neos\ContentRepository\Core\Feature\NodeDuplication\Command\CopyNodesRecursively; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; -use Neos\ContentRepository\Core\SharedModel\Node\NodeName; /** * @internal These objects internally reflect possible operations made by the Neos.Ui. @@ -37,7 +36,7 @@ public function getParentNode(): ?Node { if (!isset($this->cachedParentNode)) { $this->cachedParentNode = $this->parentContextPath - ? $this->nodeService->findNodeBySerializedNodeAddress($this->parentContextPath, $this->getSubject()->contentRepositoryId) + ? $this->nodeService->findNodeBySerializedNodeAddress($this->parentContextPath) : null; } diff --git a/Classes/Domain/Model/Changes/MoveInto.php b/Classes/Domain/Model/Changes/MoveInto.php index 74dbc07956..75474d0563 100644 --- a/Classes/Domain/Model/Changes/MoveInto.php +++ b/Classes/Domain/Model/Changes/MoveInto.php @@ -13,8 +13,8 @@ */ use Neos\ContentRepository\Core\Feature\NodeMove\Command\MoveNodeAggregate; -use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Feature\NodeMove\Dto\RelationDistributionStrategy; +use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\Neos\Ui\Domain\Model\Feedback\Operations\UpdateNodeInfo; /** @@ -38,8 +38,7 @@ public function getParentNode(): ?Node } return $this->nodeService->findNodeBySerializedNodeAddress( - $this->parentContextPath, - $this->getSubject()->contentRepositoryId + $this->parentContextPath ); } diff --git a/Classes/Domain/Model/Feedback/Operations/NodeCreated.php b/Classes/Domain/Model/Feedback/Operations/NodeCreated.php index d5a13fe77c..f79d75b208 100644 --- a/Classes/Domain/Model/Feedback/Operations/NodeCreated.php +++ b/Classes/Domain/Model/Feedback/Operations/NodeCreated.php @@ -11,10 +11,10 @@ * source code. */ +use Neos\ContentRepository\Core\Projection\ContentGraph\Node; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; -use Neos\Neos\FrontendRouting\NodeAddressFactory; -use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\Flow\Mvc\Controller\ControllerContext; use Neos\Neos\Domain\Service\NodeTypeNameFactory; use Neos\Neos\Ui\Domain\Model\AbstractFeedback; @@ -91,9 +91,9 @@ public function serializePayload(ControllerContext $controllerContext) $node = $this->getNode(); $contentRepository = $this->contentRepositoryRegistry->get($node->contentRepositoryId); $nodeType = $contentRepository->getNodeTypeManager()->getNodeType($node->nodeTypeName); - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); + return [ - 'contextPath' => $nodeAddressFactory->createFromNode($node)->serializeForUri(), + 'contextPath' => NodeAddress::fromNode($node)->toJson(), 'identifier' => $node->aggregateId->value, 'isDocument' => $nodeType?->isOfType(NodeTypeNameFactory::NAME_DOCUMENT) ]; diff --git a/Classes/Domain/Model/Feedback/Operations/Redirect.php b/Classes/Domain/Model/Feedback/Operations/Redirect.php index 43e25d3f3c..3e3b303630 100644 --- a/Classes/Domain/Model/Feedback/Operations/Redirect.php +++ b/Classes/Domain/Model/Feedback/Operations/Redirect.php @@ -7,7 +7,6 @@ use Neos\Flow\Annotations as Flow; use Neos\Flow\Mvc\Controller\ControllerContext; use Neos\Neos\Domain\NodeLabel\NodeLabelGeneratorInterface; -use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\Neos\FrontendRouting\NodeUriBuilderFactory; use Neos\Neos\FrontendRouting\Options; use Neos\Neos\Ui\Domain\Model\AbstractFeedback; @@ -114,11 +113,10 @@ public function serializePayload(ControllerContext $controllerContext): array ); $contentRepository = $this->contentRepositoryRegistry->get($node->contentRepositoryId); - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); return [ 'redirectUri' => (string)$redirectUri, - 'redirectContextPath' => $nodeAddressFactory->createFromNode($node)->serializeForUri(), + 'redirectContextPath' => NodeAddress::fromNode($node)->toJson(), ]; } } diff --git a/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php b/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php index ac9ba7e918..084d5726bf 100644 --- a/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php +++ b/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php @@ -11,14 +11,14 @@ * source code. */ -use Neos\Neos\Domain\Service\RenderingModeService; -use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; use Neos\Flow\Mvc\Controller\ControllerContext; use Neos\Fusion\Core\Cache\ContentCache; use Neos\Fusion\Exception as FusionException; +use Neos\Neos\Domain\Service\RenderingModeService; use Neos\Neos\Fusion\Helper\CachingHelper; use Neos\Neos\Ui\Domain\Model\AbstractFeedback; use Neos\Neos\Ui\Domain\Model\FeedbackInterface; @@ -110,10 +110,8 @@ public function isSimilarTo(FeedbackInterface $feedback): bool public function serializePayload(ControllerContext $controllerContext): array { if (!is_null($this->nodeDomAddress)) { - $contentRepository = $this->contentRepositoryRegistry->get($this->node->contentRepositoryId); - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); return [ - 'contextPath' => $nodeAddressFactory->createFromNode($this->node)->serializeForUri(), + 'contextPath' => NodeAddress::fromNode($this->node)->toJson(), 'nodeDomAddress' => $this->nodeDomAddress, 'renderedContent' => $this->renderContent($controllerContext) ]; diff --git a/Classes/Domain/Model/Feedback/Operations/RemoveNode.php b/Classes/Domain/Model/Feedback/Operations/RemoveNode.php index 437e349b2a..826da07d67 100644 --- a/Classes/Domain/Model/Feedback/Operations/RemoveNode.php +++ b/Classes/Domain/Model/Feedback/Operations/RemoveNode.php @@ -11,13 +11,12 @@ * source code. */ +use Neos\ContentRepository\Core\Projection\ContentGraph\Node; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; -use Neos\Neos\Domain\NodeLabel\NodeLabelGeneratorInterface; -use Neos\Neos\FrontendRouting\NodeAddressFactory; -use Neos\Neos\FrontendRouting\NodeAddress; -use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\Flow\Mvc\Controller\ControllerContext; +use Neos\Neos\Domain\NodeLabel\NodeLabelGeneratorInterface; use Neos\Neos\Ui\Domain\Model\AbstractFeedback; use Neos\Neos\Ui\Domain\Model\FeedbackInterface; @@ -54,11 +53,8 @@ public function __construct(Node $node, Node $parentNode) protected function initializeObject(): void { - $contentRepository = $this->contentRepositoryRegistry->get($this->node->contentRepositoryId); - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); - - $this->nodeAddress = $nodeAddressFactory->createFromNode($this->node); - $this->parentNodeAddress = $nodeAddressFactory->createFromNode($this->parentNode); + $this->nodeAddress = NodeAddress::fromNode($this->node); + $this->parentNodeAddress = NodeAddress::fromNode($this->parentNode); } public function getNode(): Node @@ -110,8 +106,8 @@ public function isSimilarTo(FeedbackInterface $feedback) public function serializePayload(ControllerContext $controllerContext) { return [ - 'contextPath' => $this->nodeAddress->serializeForUri(), - 'parentContextPath' => $this->parentNodeAddress->serializeForUri() + 'contextPath' => $this->nodeAddress->toJson(), + 'parentContextPath' => $this->parentNodeAddress->toJson() ]; } } diff --git a/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php b/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php index d270fb33c6..ec58a6c417 100644 --- a/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php +++ b/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php @@ -15,13 +15,13 @@ namespace Neos\Neos\Ui\Domain\Model\Feedback\Operations; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; -use Neos\Neos\Domain\Service\RenderingModeService; -use Neos\Neos\FrontendRouting\NodeAddressFactory; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; use Neos\Flow\Mvc\Controller\ControllerContext; use Neos\Fusion\Core\Cache\ContentCache; use Neos\Fusion\Exception as FusionException; +use Neos\Neos\Domain\Service\RenderingModeService; use Neos\Neos\Fusion\Helper\CachingHelper; use Neos\Neos\Ui\Domain\Model\AbstractFeedback; use Neos\Neos\Ui\Domain\Model\FeedbackInterface; @@ -156,10 +156,8 @@ public function isSimilarTo(FeedbackInterface $feedback): bool public function serializePayload(ControllerContext $controllerContext): array { if (!is_null($this->node)) { - $contentRepository = $this->contentRepositoryRegistry->get($this->node->contentRepositoryId); - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); return [ - 'contextPath' => $nodeAddressFactory->createFromNode($this->node)->serializeForUri(), + 'contextPath' => NodeAddress::fromNode($this->node)->toJson(), 'parentDomAddress' => $this->getParentDomAddress(), 'siblingDomAddress' => $this->getSiblingDomAddress(), 'mode' => $this->getMode(), diff --git a/Classes/Domain/Model/Feedback/Operations/UpdateNodeInfo.php b/Classes/Domain/Model/Feedback/Operations/UpdateNodeInfo.php index 46b80d8b48..5d1dbd9ae4 100644 --- a/Classes/Domain/Model/Feedback/Operations/UpdateNodeInfo.php +++ b/Classes/Domain/Model/Feedback/Operations/UpdateNodeInfo.php @@ -13,10 +13,10 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindChildNodesFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; -use Neos\Flow\Mvc\ActionRequest; -use Neos\Neos\FrontendRouting\NodeAddressFactory; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; +use Neos\Flow\Mvc\ActionRequest; use Neos\Flow\Mvc\Controller\ControllerContext; use Neos\Neos\Ui\Domain\Model\AbstractFeedback; use Neos\Neos\Ui\Domain\Model\FeedbackInterface; @@ -115,10 +115,9 @@ public function serializePayload(ControllerContext $controllerContext): array private function serializeNodeRecursively(Node $node, ActionRequest $actionRequest): array { $contentRepository = $this->contentRepositoryRegistry->get($node->contentRepositoryId); - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); $result = [ - $nodeAddressFactory->createFromNode($node)->serializeForUri() + NodeAddress::fromNode($node)->toJson() => $this->nodeInfoHelper->renderNodeWithPropertiesAndChildrenInformation( $node, $actionRequest diff --git a/Classes/Domain/Model/Feedback/Operations/UpdateNodePreviewUrl.php b/Classes/Domain/Model/Feedback/Operations/UpdateNodePreviewUrl.php index 4322d130b3..5e136e3ec4 100644 --- a/Classes/Domain/Model/Feedback/Operations/UpdateNodePreviewUrl.php +++ b/Classes/Domain/Model/Feedback/Operations/UpdateNodePreviewUrl.php @@ -12,11 +12,11 @@ */ use Neos\ContentRepository\Core\Projection\ContentGraph\Node; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; use Neos\Flow\Mvc\Controller\ControllerContext; use Neos\Neos\Domain\NodeLabel\NodeLabelGeneratorInterface; -use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\Neos\Ui\Domain\Model\AbstractFeedback; use Neos\Neos\Ui\Domain\Model\FeedbackInterface; use Neos\Neos\Ui\Fusion\Helper\NodeInfoHelper; @@ -111,10 +111,8 @@ public function serializePayload(ControllerContext $controllerContext): array $contextPath = ''; } else { $nodeInfoHelper = new NodeInfoHelper(); - $contentRepository = $this->contentRepositoryRegistry->get($this->node->contentRepositoryId); - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); $newPreviewUrl = $nodeInfoHelper->createRedirectToNode($this->node, $controllerContext->getRequest()); - $contextPath = $nodeAddressFactory->createFromNode($this->node)->serializeForUri(); + $contextPath = NodeAddress::fromNode($this->node)->toJson(); } return [ 'newPreviewUrl' => $newPreviewUrl, diff --git a/Classes/FlowQueryOperations/NeosUiDefaultNodesOperation.php b/Classes/FlowQueryOperations/NeosUiDefaultNodesOperation.php index c941c8bef9..5123e8f616 100644 --- a/Classes/FlowQueryOperations/NeosUiDefaultNodesOperation.php +++ b/Classes/FlowQueryOperations/NeosUiDefaultNodesOperation.php @@ -14,12 +14,12 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindAncestorNodesFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindChildNodesFilter; -use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\NodeType\NodeTypeCriteria; +use Neos\ContentRepository\Core\Projection\ContentGraph\Node; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Eel\FlowQuery\FlowQuery; use Neos\Eel\FlowQuery\Operations\AbstractOperation; -use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\Flow\Annotations as Flow; /** @@ -78,7 +78,6 @@ public function evaluate(FlowQuery $flowQuery, array $arguments) list($baseNodeType, $loadingDepth, $toggledNodes, $clipboardNodesContextPaths) = $arguments; $contentRepository = $this->contentRepositoryRegistry->get($documentNode->contentRepositoryId); - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); $baseNodeTypeConstraints = NodeTypeCriteria::fromFilterString($baseNodeType); @@ -105,15 +104,14 @@ public function evaluate(FlowQuery $flowQuery, array $arguments) $loadingDepth, $toggledNodes, $ancestors, - $subgraph, - $nodeAddressFactory + $subgraph ) { - $baseNodeAddress = $nodeAddressFactory->createFromNode($baseNode); + $baseNodeAddress = NodeAddress::fromNode($baseNode); if ($level < $loadingDepth || // load all nodes within loadingDepth $loadingDepth === 0 || // unlimited loadingDepth // load toggled nodes - in_array($baseNodeAddress->serializeForUri(), $toggledNodes) || + in_array($baseNodeAddress->toJson(), $toggledNodes) || // load children of all parents of documentNode in_array($baseNode->aggregateId->value, array_map( fn (Node $node): string => $node->aggregateId->value, @@ -136,9 +134,9 @@ public function evaluate(FlowQuery $flowQuery, array $arguments) } foreach ($clipboardNodesContextPaths as $clipboardNodeContextPath) { - // TODO: does not work across multiple CRs yet. - $clipboardNodeAddress = $nodeAddressFactory->createFromUriString($clipboardNodeContextPath); - $clipboardNode = $subgraph->findNodeById($clipboardNodeAddress->nodeAggregateId); + // TODO: might not work across multiple CRs yet. + $clipboardNodeAddress = NodeAddress::fromJsonString($clipboardNodeContextPath); + $clipboardNode = $subgraph->findNodeById($clipboardNodeAddress->aggregateId); if ($clipboardNode && !array_key_exists($clipboardNode->aggregateId->value, $nodes)) { $nodes[$clipboardNode->aggregateId->value] = $clipboardNode; } diff --git a/Classes/Fusion/Helper/NodeInfoHelper.php b/Classes/Fusion/Helper/NodeInfoHelper.php index dc254bad4b..d4300d9f71 100644 --- a/Classes/Fusion/Helper/NodeInfoHelper.php +++ b/Classes/Fusion/Helper/NodeInfoHelper.php @@ -25,7 +25,6 @@ use Neos\Flow\Mvc\Routing\UriBuilder; use Neos\Flow\Persistence\PersistenceManagerInterface; use Neos\Neos\Domain\NodeLabel\NodeLabelGeneratorInterface; -use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\Neos\FrontendRouting\NodeUriBuilderFactory; use Neos\Neos\Ui\Domain\Service\NodePropertyConverterService; use Neos\Neos\Ui\Domain\Service\UserLocaleService; @@ -186,13 +185,11 @@ protected function getBasicNodeInformation(Node $node): array $subgraph = $this->contentRepositoryRegistry->subgraphForNode($node); $parentNode = $subgraph->findParentNode($node->aggregateId); - $contentRepository = $this->contentRepositoryRegistry->get($node->contentRepositoryId); - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); - $nodeAddress = $nodeAddressFactory->createFromNode($node); + $nodeAddress = NodeAddress::fromNode($node); return [ - 'contextPath' => $nodeAddress->serializeForUri(), - 'nodeAddress' => $nodeAddress->serializeForUri(), + 'contextPath' => $nodeAddress->toJson(), + 'nodeAddress' => $nodeAddress->toJson(), 'name' => $node->name?->value ?? '', 'identifier' => $node->aggregateId->jsonSerialize(), 'nodeType' => $node->nodeTypeName->value, @@ -204,7 +201,7 @@ protected function getBasicNodeInformation(Node $node): array CountAncestorNodesFilter::create() ), 'children' => [], - 'parent' => $parentNode ? $nodeAddressFactory->createFromNode($parentNode)->serializeForUri() : null, + 'parent' => $parentNode ? NodeAddress::fromNode($parentNode)->toJson() : null, 'matchesCurrentDimensions' => $node->dimensionSpacePoint->equals($node->originDimensionSpacePoint), 'lastModificationDateTime' => $node->timestamps->lastModified?->format(\DateTime::ATOM), 'creationDateTime' => $node->timestamps->created->format(\DateTime::ATOM), @@ -240,9 +237,8 @@ protected function renderChildrenInformation(Node $node, string $nodeTypeFilterS $infos = []; foreach ($childNodes as $childNode) { $contentRepository = $this->contentRepositoryRegistry->get($childNode->contentRepositoryId); - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); $infos[] = [ - 'contextPath' => $nodeAddressFactory->createFromNode($childNode)->serializeForUri(), + 'contextPath' => NodeAddress::fromNode($childNode)->toJson(), 'nodeType' => $childNode->nodeTypeName->value ]; }; @@ -336,12 +332,11 @@ public function defaultNodesForBackend( ): array { // does not support multiple CRs here yet $contentRepository = $this->contentRepositoryRegistry->get($site->contentRepositoryId); - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); return [ - ($nodeAddressFactory->createFromNode($site)->serializeForUri()) + (NodeAddress::fromNode($site)->toJson()) => $this->renderNodeWithPropertiesAndChildrenInformation($site, $actionRequest), - ($nodeAddressFactory->createFromNode($documentNode)->serializeForUri()) + (NodeAddress::fromNode($documentNode)->toJson()) => $this->renderNodeWithPropertiesAndChildrenInformation($documentNode, $actionRequest) ]; } @@ -420,8 +415,7 @@ protected function buildContentChildNodeFilterString(): string public function serializedNodeAddress(Node $node): string { $contentRepository = $this->contentRepositoryRegistry->get($node->contentRepositoryId); - $nodeAddressFactory = NodeAddressFactory::create($contentRepository); - return $nodeAddressFactory->createFromNode($node)->serializeForUri(); + return NodeAddress::fromNode($node)->toJson(); } /** diff --git a/Classes/Service/NodeClipboard.php b/Classes/Service/NodeClipboard.php index ad802b7be3..2f009b6795 100644 --- a/Classes/Service/NodeClipboard.php +++ b/Classes/Service/NodeClipboard.php @@ -11,7 +11,7 @@ * source code. */ -use Neos\Neos\FrontendRouting\NodeAddress; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; use Neos\Flow\Annotations as Flow; /** @@ -44,7 +44,7 @@ class NodeClipboard public function copyNodes(array $nodeAddresses): void { $this->serializedNodeAddresses = array_map( - fn (NodeAddress $nodeAddress) => $nodeAddress->serializeForUri(), + fn (NodeAddress $nodeAddress) => $nodeAddress->toJson(), $nodeAddresses ); $this->mode = self::MODE_COPY; @@ -53,13 +53,13 @@ public function copyNodes(array $nodeAddresses): void /** * Save cut node to clipboard. * - * @param array $nodeAddresses + * @param array $nodeAddresses * @Flow\Session(autoStart=true) */ public function cutNodes(array $nodeAddresses): void { $this->serializedNodeAddresses = array_map( - fn (NodeAddress $nodeAddress) => $nodeAddress->serializeForUri(), + fn (NodeAddress $nodeAddress) => $nodeAddress->toJson(), $nodeAddresses ); $this->mode = self::MODE_MOVE; diff --git a/Classes/TypeConverter/ChangeCollectionConverter.php b/Classes/TypeConverter/ChangeCollectionConverter.php index a452640d63..9c438db681 100644 --- a/Classes/TypeConverter/ChangeCollectionConverter.php +++ b/Classes/TypeConverter/ChangeCollectionConverter.php @@ -12,13 +12,10 @@ */ use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; -use Neos\Error\Messages\Error; use Neos\Flow\Annotations as Flow; use Neos\Flow\ObjectManagement\ObjectManagerInterface; use Neos\Flow\Persistence\PersistenceManagerInterface; use Neos\Flow\Property\PropertyMapper; -use Neos\Flow\Property\PropertyMappingConfigurationInterface; -use Neos\Flow\Property\TypeConverter\AbstractTypeConverter; use Neos\Flow\Reflection\ReflectionService; use Neos\Neos\Ui\ContentRepository\Service\NeosUiNodeService; use Neos\Neos\Ui\Domain\Model\ChangeCollection; @@ -133,7 +130,7 @@ protected function convertChangeData(array $changeData, ContentRepositoryId $con $subjectContextPath = $changeData['subject']; - $subject = $this->nodeService->findNodeBySerializedNodeAddress($subjectContextPath, $contentRepositoryId); + $subject = $this->nodeService->findNodeBySerializedNodeAddress($subjectContextPath); // we guard that `setSubject` gets a Node! if (is_null($subject)) { throw new \RuntimeException('Could not find node for subject "' . $subjectContextPath . '"', 1645657340); @@ -143,7 +140,7 @@ protected function convertChangeData(array $changeData, ContentRepositoryId $con if (isset($changeData['reference']) && method_exists($changeClassInstance, 'setReference')) { $referenceContextPath = $changeData['reference']; - $reference = $this->nodeService->findNodeBySerializedNodeAddress($referenceContextPath, $contentRepositoryId); + $reference = $this->nodeService->findNodeBySerializedNodeAddress($referenceContextPath); $changeClassInstance->setReference($reference); } diff --git a/Tests/IntegrationTests/Fixtures/1Dimension/discarding.e2e.js b/Tests/IntegrationTests/Fixtures/1Dimension/discarding.e2e.js index f7ed4606a3..36a7c54bd6 100644 --- a/Tests/IntegrationTests/Fixtures/1Dimension/discarding.e2e.js +++ b/Tests/IntegrationTests/Fixtures/1Dimension/discarding.e2e.js @@ -38,7 +38,7 @@ test('Discarding: create multiple nodes nested within each other and then discar .expect(ReactSelector('Provider').getReact(({props}) => { const reduxState = props.store.getState(); return reduxState.cr.nodes.documentNode; - })).eql('admin-admington__eyJsYW5ndWFnZSI6ImVuX1VTIn0=__f676459d-ca77-44bc-aeea-44114814c279', 'After discarding we are back to the main page'); + })).eql(JSON.stringify({contentRepositoryId:"onedimension",workspaceName:"admin-admington",dimensionSpacePoint:{"language":"en_US"},aggregateId:"f676459d-ca77-44bc-aeea-44114814c279"}), 'After discarding we are back to the main page'); }); test('Discarding: create a document node and then discard it', async t => { diff --git a/Tests/IntegrationTests/Fixtures/1Dimension/treeMultiselect.e2e.js b/Tests/IntegrationTests/Fixtures/1Dimension/treeMultiselect.e2e.js index 0bf502bb50..a06f967e2e 100644 --- a/Tests/IntegrationTests/Fixtures/1Dimension/treeMultiselect.e2e.js +++ b/Tests/IntegrationTests/Fixtures/1Dimension/treeMultiselect.e2e.js @@ -26,7 +26,7 @@ test('Move multiple nodes via toolbar', async t => { .expect(ReactSelector('Provider').getReact(({props}) => { const reduxState = props.store.getState(); return reduxState.cr.nodes.documentNode; - })).eql('admin-admington__eyJsYW5ndWFnZSI6ImVuX1VTIn0=__5b0d6ac0-40ab-47e8-b79e-39de6c0700df', 'Node B\'s node address changed'); + })).eql(JSON.stringify({contentRepositoryId:"onedimension",workspaceName:"admin-admington",dimensionSpacePoint:{"language":"en_US"},aggregateId:"5b0d6ac0-40ab-47e8-b79e-39de6c0700df"}), 'Node B\'s node address changed'); await t.click(Page.getTreeNodeButton('Home')) }); @@ -43,7 +43,7 @@ test('Move multiple nodes via DND, CMD-click', async t => { .expect(ReactSelector('Provider').getReact(({props}) => { const reduxState = props.store.getState(); return reduxState.cr.nodes.documentNode; - })).eql('admin-admington__eyJsYW5ndWFnZSI6ImVuX1VTIn0=__5b0d6ac0-40ab-47e8-b79e-39de6c0700df', 'Node B\'s node address changed'); + })).eql(JSON.stringify({contentRepositoryId:"onedimension",workspaceName:"admin-admington",dimensionSpacePoint:{"language":"en_US"},aggregateId:"5b0d6ac0-40ab-47e8-b79e-39de6c0700df"}), 'Node B\'s node address changed'); await t.click(Page.getTreeNodeButton('Home')) }); @@ -60,6 +60,6 @@ test('Move multiple nodes via DND, SHIFT-click', async t => { .expect(ReactSelector('Provider').getReact(({props}) => { const reduxState = props.store.getState(); return reduxState.cr.nodes.documentNode; - })).eql('admin-admington__eyJsYW5ndWFnZSI6ImVuX1VTIn0=__84eb0340-ba34-4fdb-98b1-da503f967121', 'Node C\'s node address changed'); + })).eql(JSON.stringify({contentRepositoryId:"onedimension",workspaceName:"admin-admington",dimensionSpacePoint:{"language":"en_US"},aggregateId:"84eb0340-ba34-4fdb-98b1-da503f967121"}), 'Node C\'s node address changed'); await t.click(Page.getTreeNodeButton('Home')) }); diff --git a/packages/neos-ui-guest-frame/src/dom.js b/packages/neos-ui-guest-frame/src/dom.js index 381eb0f0bc..33eb768352 100644 --- a/packages/neos-ui-guest-frame/src/dom.js +++ b/packages/neos-ui-guest-frame/src/dom.js @@ -54,14 +54,14 @@ export const findAllPropertiesInGuestFrame = () => // // Find all DOM nodes that represent a particular node property in the guest frame // -export const findAllOccurrencesOfNodePropertyInGuestFrame = (contextPath, propertyName) => findAllInGuestFrame(`[data-__neos-editable-node-contextpath="${contextPath}"][data-__neos-property="${propertyName}"]`); +export const findAllOccurrencesOfNodePropertyInGuestFrame = (contextPath, propertyName) => findAllInGuestFrame(`[data-__neos-editable-node-contextpath="${CSS.escape(contextPath)}"][data-__neos-property="${CSS.escape(propertyName)}"]`); // // Find all DOM nodes that represent CR node properties in the guest frame // export const findRelativePropertiesInGuestFrame = contentDomNode => [].slice.call(contentDomNode.querySelectorAll( - `[data-__neos-property][data-__neos-editable-node-contextpath="${contentDomNode.getAttribute('data-__neos-node-contextpath')}"]` + `[data-__neos-property][data-__neos-editable-node-contextpath="${CSS.escape(contentDomNode.getAttribute('data-__neos-node-contextpath'))}"]` )).concat(...( contentDomNode.hasAttribute('data-__neos-property') ? [contentDomNode] : [] @@ -71,9 +71,9 @@ export const findRelativePropertiesInGuestFrame = contentDomNode => // Find a specific DOM node that represents a CR node in the guest frame // export const findNodeInGuestFrame = (contextPath, fusionPath) => fusionPath ? findInGuestFrame( - `[data-__neos-node-contextpath="${contextPath}"][data-__neos-fusion-path="${fusionPath}"]` + `[data-__neos-node-contextpath="${CSS.escape(contextPath)}"][data-__neos-fusion-path="${CSS.escape(fusionPath)}"]` ) : findInGuestFrame( - `[data-__neos-node-contextpath="${contextPath}"]` + `[data-__neos-node-contextpath="${CSS.escape(contextPath)}"]` ); // @@ -81,9 +81,9 @@ export const findNodeInGuestFrame = (contextPath, fusionPath) => fusionPath ? fi // fusion path in the guest frame // export const findAllOccurrencesOfNodeInGuestFrame = (contextPath, fusionPath) => fusionPath ? findAllInGuestFrame( - `[data-__neos-node-contextpath="${contextPath}"][data-__neos-fusion-path="${fusionPath}"]` + `[data-__neos-node-contextpath="${CSS.escape(contextPath)}"][data-__neos-fusion-path="${CSS.escape(fusionPath)}"]` ) : findAllInGuestFrame( - `[data-__neos-node-contextpath="${contextPath}"]` + `[data-__neos-node-contextpath="${CSS.escape(contextPath)}"]` ); // diff --git a/packages/neos-ui/src/manifest.js b/packages/neos-ui/src/manifest.js index 22cb23bb6e..749a16240e 100644 --- a/packages/neos-ui/src/manifest.js +++ b/packages/neos-ui/src/manifest.js @@ -422,7 +422,7 @@ manifest('main', {}, (globalRegistry, {routes}) => { const tempNodeInGuest = getGuestFrameDocument().createElement(wrapTagName); tempNodeInGuest.innerHTML = renderedContent; const contentElement = tempNodeInGuest - .querySelector(`[data-__neos-node-contextpath="${contextPath}"]`); + .querySelector(`[data-__neos-node-contextpath="${CSS.escape(contextPath)}"]`); if (!contentElement) { console.error(`!!! Content Element (rendered out-of-band) with context path "${contextPath}" not found in returned HTML from server (which you see below) - Reloading the full page!`); @@ -527,7 +527,7 @@ manifest('main', {}, (globalRegistry, {routes}) => { const tempNodeInGuest = getGuestFrameDocument().createElement('div'); tempNodeInGuest.innerHTML = renderedContent; const contentElement = tempNodeInGuest - .querySelector(`[data-__neos-node-contextpath="${contextPath}"]`); + .querySelector(`[data-__neos-node-contextpath="${CSS.escape(contextPath)}"]`); if (!contentElement) { console.error(`!!! Content Element (reloaded out-of-band) with context path "${contextPath}" not found in returned HTML from server (which you see below) - Reloading the full page!`);