From ffbf67e405852c50eff8d85f0573b644cf7e1095 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Fri, 17 May 2024 17:32:27 +0200 Subject: [PATCH 1/3] TASK: Add workspaceName to nodeAggregate --- .../src/Domain/Repository/NodeFactory.php | 10 +-- .../src/Domain/Repository/NodeFactory.php | 8 ++- .../Projection/ContentGraph/NodeAggregate.php | 69 ++++++++++++++++--- 3 files changed, 71 insertions(+), 16 deletions(-) diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/NodeFactory.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/NodeFactory.php index 5609db207f6..d769d239f2a 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/NodeFactory.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/NodeFactory.php @@ -220,10 +220,10 @@ public function mapNodeRowsToNodeAggregate( // a nodeAggregate only exists if it at least contains one node assert($nodesByOccupiedDimensionSpacePoint !== []); - $primaryNode = current($nodesByOccupiedDimensionSpacePoint); return new NodeAggregate( - $primaryNode->subgraphIdentity->contentStreamId, + $this->contentRepositoryId, + $workspaceName, NodeAggregateId::fromString($rawNodeAggregateId), NodeAggregateClassification::from($rawNodeAggregateClassification), NodeTypeName::fromString($rawNodeTypeName), @@ -235,6 +235,7 @@ public function mapNodeRowsToNodeAggregate( $nodesByCoveredDimensionSpacePoints, OriginByCoverage::fromArray($occupationByCovering), $dimensionSpacePointsBySubtreeTags, + $contentStreamId, ); } @@ -315,8 +316,8 @@ public function mapNodeRowsToNodeAggregates( foreach ($nodesByOccupiedDimensionSpacePointsByNodeAggregate as $rawNodeAggregateId => $nodes) { /** @var string $rawNodeAggregateId */ yield new NodeAggregate( - // this line is safe because a nodeAggregate only exists if it at least contains one node. - current($nodes)->subgraphIdentity->contentStreamId, + $this->contentRepositoryId, + $workspaceName, NodeAggregateId::fromString($rawNodeAggregateId), $classificationByNodeAggregate[$rawNodeAggregateId], $nodeTypeNames[$rawNodeAggregateId], @@ -337,6 +338,7 @@ public function mapNodeRowsToNodeAggregates( $occupationByCoveringByNodeAggregate[$rawNodeAggregateId] ), $dimensionSpacePointsBySubtreeTagsByNodeAggregate[$rawNodeAggregateId], + $contentStreamId, ); } } diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/NodeFactory.php b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/NodeFactory.php index dbd29ff6642..923bbfdaa4e 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/NodeFactory.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/NodeFactory.php @@ -244,7 +244,8 @@ public function mapNodeRowsToNodeAggregate( } return new NodeAggregate( - $contentStreamId, + $this->contentRepositoryId, + WorkspaceName::fromString('missing'), // todo $nodeAggregateId, $nodeAggregateClassification, $nodeTypeName, @@ -257,6 +258,7 @@ public function mapNodeRowsToNodeAggregate( OriginByCoverage::fromArray($occupationByCovered), // TODO implement (see \Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\NodeFactory::mapNodeRowsToNodeAggregate()) DimensionSpacePointsBySubtreeTags::create(), + $contentStreamId, ); } @@ -341,7 +343,8 @@ public function mapNodeRowsToNodeAggregates(array $nodeRows, VisibilityConstrain foreach ($nodeAggregateIds as $key => $nodeAggregateId) { yield new NodeAggregate( - $contentStreamId, + $this->contentRepositoryId, + WorkspaceName::fromString('missing'), // todo $nodeAggregateId, $nodeAggregateClassifications[$key], $nodeTypeNames[$key], @@ -354,6 +357,7 @@ public function mapNodeRowsToNodeAggregates(array $nodeRows, VisibilityConstrain OriginByCoverage::fromArray($occupationByCovered[$key]), // TODO implement (see \Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\NodeFactory::mapNodeRowsToNodeAggregates()) DimensionSpacePointsBySubtreeTags::create(), + $contentStreamId, ); } } diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/NodeAggregate.php b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/NodeAggregate.php index 3cc7f298ab4..abb806d2451 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/NodeAggregate.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/NodeAggregate.php @@ -20,12 +20,14 @@ use Neos\ContentRepository\Core\DimensionSpace\OriginDimensionSpacePointSet; use Neos\ContentRepository\Core\Feature\SubtreeTagging\Dto\SubtreeTag; use Neos\ContentRepository\Core\NodeType\NodeTypeName; +use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepository\Core\SharedModel\Exception\NodeAggregateDoesCurrentlyNotCoverDimensionSpacePoint; use Neos\ContentRepository\Core\SharedModel\Exception\NodeAggregateDoesCurrentlyNotOccupyDimensionSpacePoint; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateClassification; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Node\NodeName; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; +use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; /** * Node aggregate read model. Returned mainly from {@see ContentGraphInterface}. @@ -47,28 +49,34 @@ * This interface is called *Readable* because it exposes read operations on the set of nodes inside * a single NodeAggregate; often used for constraint checks (in command handlers). * - * @api except its constructor. + * @api Note: The constructor is not part of the public API */ final readonly class NodeAggregate { /** - * @internal - * @param ContentStreamId $contentStreamId ID of the content stream of this node aggregate + * This was intermediate part of the node aggregate. Please use {@see $workspaceName} instead. + * @deprecated will be removed before the final 9.0 release + */ + public ContentStreamId $contentStreamId; + + /** + * @param ContentRepositoryId $contentRepositoryId The content-repository this node aggregate belongs to + * @param WorkspaceName $workspaceName The workspace of this node aggregate * @param NodeAggregateId $nodeAggregateId ID of this node aggregate - * @param NodeAggregateClassification $classification whether this aggregate represents a root, regular or tethered node - * @param NodeTypeName $nodeTypeName name of the node type of this aggregate - * @param NodeName|null $nodeName optional name of this aggregate - * @param OriginDimensionSpacePointSet $occupiedDimensionSpacePoints dimension space points this aggregate occupies + * @param NodeAggregateClassification $classification whether this node aggregate represents a root, regular or tethered node + * @param NodeTypeName $nodeTypeName name of the node type of this node aggregate + * @param NodeName|null $nodeName optional name of this node aggregate + * @param OriginDimensionSpacePointSet $occupiedDimensionSpacePoints dimension space points this node aggregate occupies * @param non-empty-array $nodesByOccupiedDimensionSpacePoint At least one node will be occupied. * @param CoverageByOrigin $coverageByOccupant * @param DimensionSpacePointSet $coveredDimensionSpacePoints This node aggregate will cover at least one dimension space. * @param non-empty-array $nodesByCoveredDimensionSpacePoint At least one node will be covered. * @param OriginByCoverage $occupationByCovered - * @param DimensionSpacePointsBySubtreeTags $dimensionSpacePointsBySubtreeTags dimension space points for every subtree tag this aggregate is *explicitly* tagged with (excluding inherited tags) + * @param DimensionSpacePointsBySubtreeTags $dimensionSpacePointsBySubtreeTags dimension space points for every subtree tag this node aggregate is *explicitly* tagged with (excluding inherited tags) */ - // todo add workspace name and content repository id and remove cs id public function __construct( - public ContentStreamId $contentStreamId, + public ContentRepositoryId $contentRepositoryId, + public WorkspaceName $workspaceName, public NodeAggregateId $nodeAggregateId, public NodeAggregateClassification $classification, public NodeTypeName $nodeTypeName, @@ -80,7 +88,48 @@ public function __construct( private array $nodesByCoveredDimensionSpacePoint, private OriginByCoverage $occupationByCovered, private DimensionSpacePointsBySubtreeTags $dimensionSpacePointsBySubtreeTags, + ContentStreamId $contentStreamId, ) { + $this->contentStreamId = $contentStreamId; + } + + /** + * @internal The signature of this method can change in the future! + * @param non-empty-array $nodesByOccupiedDimensionSpacePoint + * @param non-empty-array $nodesByCoveredDimensionSpacePoint + */ + public static function create( + ContentRepositoryId $contentRepositoryId, + WorkspaceName $workspaceName, + NodeAggregateId $nodeAggregateId, + NodeAggregateClassification $classification, + NodeTypeName $nodeTypeName, + ?NodeName $nodeName, + OriginDimensionSpacePointSet $occupiedDimensionSpacePoints, + array $nodesByOccupiedDimensionSpacePoint, + CoverageByOrigin $coverageByOccupant, + DimensionSpacePointSet $coveredDimensionSpacePoints, + array $nodesByCoveredDimensionSpacePoint, + OriginByCoverage $occupationByCovered, + DimensionSpacePointsBySubtreeTags $dimensionSpacePointsBySubtreeTags, + ContentStreamId $contentStreamId, + ): self { + return new self( + $contentRepositoryId, + $workspaceName, + $nodeAggregateId, + $classification, + $nodeTypeName, + $nodeName, + $occupiedDimensionSpacePoints, + $nodesByOccupiedDimensionSpacePoint, + $coverageByOccupant, + $coveredDimensionSpacePoints, + $nodesByCoveredDimensionSpacePoint, + $occupationByCovered, + $dimensionSpacePointsBySubtreeTags, + $contentStreamId, + ); } public function occupiesDimensionSpacePoint(OriginDimensionSpacePoint $originDimensionSpacePoint): bool From 6149abfc3503ae99cc1056ae443e1a5890e18f36 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Fri, 17 May 2024 21:21:46 +0200 Subject: [PATCH 2/3] TASK: Prefer `NodeAggregate::$workspaceName` over `NodeAggregate::$contentStreamId` Adjust tests to assert on workspace name as well: > And I expect this node aggregate to have the parent node aggregates ["lady-eleonode-rootford"] --- .../src/Adjustment/StructureAdjustment.php | 14 +++++++------- .../src/Adjustment/TetheredNodeAdjustments.php | 9 ++------- .../Bootstrap/ProjectedNodeAggregateTrait.php | 8 ++++---- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/Neos.ContentRepository.StructureAdjustment/src/Adjustment/StructureAdjustment.php b/Neos.ContentRepository.StructureAdjustment/src/Adjustment/StructureAdjustment.php index b2ba0668007..5c180032cc3 100644 --- a/Neos.ContentRepository.StructureAdjustment/src/Adjustment/StructureAdjustment.php +++ b/Neos.ContentRepository.StructureAdjustment/src/Adjustment/StructureAdjustment.php @@ -8,7 +8,7 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\ContentGraph\NodeAggregate; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; -use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; +use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; use Neos\Error\Messages\Message; final class StructureAdjustment extends Message @@ -45,7 +45,7 @@ private function __construct( } public static function createForNodeIdentity( - ContentStreamId $contentStreamId, + WorkspaceName $workspaceName, OriginDimensionSpacePoint $originDimensionSpacePoint, NodeAggregateId $nodeAggregateId, string $type, @@ -57,7 +57,7 @@ public static function createForNodeIdentity( . ($remediation ? '' : '!!!NOT AUTO-FIXABLE YET!!! ') . $errorMessage, null, [ - 'contentStream' => $contentStreamId->value, + 'workspaceName' => $workspaceName->value, 'dimensionSpacePoint' => $originDimensionSpacePoint->toJson(), 'nodeAggregateId' => $nodeAggregateId->value, 'isAutoFixable' => ($remediation !== null) @@ -74,9 +74,9 @@ public static function createForNode( ?\Closure $remediation = null ): self { return self::createForNodeIdentity( - $node->subgraphIdentity->contentStreamId, + $node->workspaceName, $node->originDimensionSpacePoint, - $node->nodeAggregateId, + $node->aggregateId, $type, $errorMessage, $remediation @@ -90,11 +90,11 @@ public static function createForNodeAggregate( ?\Closure $remediation = null ): self { return new self( - 'Content Stream: %s; Dimension Space Point: %s, Node Aggregate: %s --- ' + 'Workspace: %s; Dimension Space Point: %s, Node Aggregate: %s --- ' . ($remediation ? '' : '!!!NOT AUTO-FIXABLE YET!!! ') . $errorMessage, null, [ - 'contentStream' => $nodeAggregate->contentStreamId->value, + 'workspaceName' => $nodeAggregate->workspaceName->value, 'nodeAggregateId' => $nodeAggregate->nodeAggregateId->value, 'isAutoFixable' => ($remediation !== null) ], diff --git a/Neos.ContentRepository.StructureAdjustment/src/Adjustment/TetheredNodeAdjustments.php b/Neos.ContentRepository.StructureAdjustment/src/Adjustment/TetheredNodeAdjustments.php index c3ce45a2aae..6e0d3b1c6e5 100644 --- a/Neos.ContentRepository.StructureAdjustment/src/Adjustment/TetheredNodeAdjustments.php +++ b/Neos.ContentRepository.StructureAdjustment/src/Adjustment/TetheredNodeAdjustments.php @@ -4,7 +4,6 @@ namespace Neos\ContentRepository\StructureAdjustment\Adjustment; -use Neos\ContentRepository\Core\ContentRepository; use Neos\ContentRepository\Core\DimensionSpace; use Neos\ContentRepository\Core\EventStore\Events; use Neos\ContentRepository\Core\EventStore\EventsToPublish; @@ -15,16 +14,12 @@ use Neos\ContentRepository\Core\Feature\ContentStreamEventStreamName; use Neos\ContentRepository\Core\Feature\NodeMove\Event\NodeAggregateWasMoved; use Neos\ContentRepository\Core\Infrastructure\Property\PropertyConverter; -use Neos\ContentRepository\Core\NodeType\NodeType; use Neos\ContentRepository\Core\NodeType\NodeTypeManager; use Neos\ContentRepository\Core\NodeType\NodeTypeName; -use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindChildNodesFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; -use Neos\ContentRepository\Core\SharedModel\Node\NodeName; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; -use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; use Neos\EventStore\Model\EventStream\ExpectedVersion; class TetheredNodeAdjustments @@ -74,7 +69,7 @@ public function findAdjustmentsForNodeType(NodeTypeName $nodeTypeName): \Generat // $nestedNode not found // - so a tethered node is missing in the OriginDimensionSpacePoint of the $node yield StructureAdjustment::createForNodeIdentity( - $nodeAggregate->contentStreamId, + $nodeAggregate->workspaceName, $originDimensionSpacePoint, $nodeAggregate->nodeAggregateId, StructureAdjustment::TETHERED_NODE_MISSING, @@ -140,7 +135,7 @@ function () use ($tetheredNodeAggregate) { if (array_keys($actualTetheredChildNodes) !== array_keys($nodeType->tetheredNodeTypeDefinitions->toArray())) { // we need to re-order: We go from the last to the first yield StructureAdjustment::createForNodeIdentity( - $nodeAggregate->contentStreamId, + $nodeAggregate->workspaceName, $originDimensionSpacePoint, $nodeAggregate->nodeAggregateId, StructureAdjustment::TETHERED_NODE_WRONGLY_ORDERED, diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/ProjectedNodeAggregateTrait.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/ProjectedNodeAggregateTrait.php index 6b0c428e5dc..13abb0cf731 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/ProjectedNodeAggregateTrait.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/ProjectedNodeAggregateTrait.php @@ -175,11 +175,11 @@ public function iExpectThisNodeAggregateToHaveTheParentNodeAggregates(string $se $expectedNodeAggregateIds = NodeAggregateIds::fromJsonString($serializedExpectedNodeAggregateIds); $this->assertOnCurrentNodeAggregate(function (NodeAggregate $nodeAggregate) use ($expectedNodeAggregateIds) { $expectedDiscriminators = array_values(array_map(function (NodeAggregateId $nodeAggregateId) { - return $this->currentContentStreamId->value . ';' . $nodeAggregateId->value; + return $this->currentWorkspaceName->value . ';' . $nodeAggregateId->value; }, iterator_to_array($expectedNodeAggregateIds))); $actualDiscriminators = array_values(array_map( fn (NodeAggregate $parentNodeAggregate): string - => $parentNodeAggregate->contentStreamId->value . ';' . $parentNodeAggregate->nodeAggregateId->value, + => $parentNodeAggregate->workspaceName->value . ';' . $parentNodeAggregate->nodeAggregateId->value, iterator_to_array( $this->currentContentRepository->getContentGraph($this->currentWorkspaceName)->findParentNodeAggregates( $nodeAggregate->nodeAggregateId @@ -218,12 +218,12 @@ public function iExpectThisNodeAggregateToHaveTheChildNodeAggregates(string $ser $expectedNodeAggregateIds = NodeAggregateIds::fromJsonString($serializedExpectedNodeAggregateIds); $this->assertOnCurrentNodeAggregate(function (NodeAggregate $nodeAggregate) use ($expectedNodeAggregateIds) { $expectedDiscriminators = array_values(array_map( - fn (NodeAggregateId $nodeAggregateId): string => $this->currentContentStreamId->value . ':' . $nodeAggregateId->value, + fn (NodeAggregateId $nodeAggregateId): string => $this->currentWorkspaceName->value . ':' . $nodeAggregateId->value, iterator_to_array($expectedNodeAggregateIds) )); $actualDiscriminators = array_values(array_map( fn (NodeAggregate $parentNodeAggregate): string - => $parentNodeAggregate->contentStreamId->value . ':' . $parentNodeAggregate->nodeAggregateId->value, + => $parentNodeAggregate->workspaceName->value . ':' . $parentNodeAggregate->nodeAggregateId->value, iterator_to_array($this->currentContentRepository->getContentGraph($this->currentWorkspaceName)->findChildNodeAggregates( $nodeAggregate->nodeAggregateId )) From 16d17b2d43664a07356a907370eaaf60f7578a3f Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Sat, 18 May 2024 09:18:56 +0200 Subject: [PATCH 3/3] TASK: Make NodeAggregate __construct private --- .../src/Domain/Repository/NodeFactory.php | 4 ++-- .../src/Domain/Repository/NodeFactory.php | 4 ++-- .../Classes/Projection/ContentGraph/NodeAggregate.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/NodeFactory.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/NodeFactory.php index d769d239f2a..288e472cc41 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/NodeFactory.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/NodeFactory.php @@ -221,7 +221,7 @@ public function mapNodeRowsToNodeAggregate( // a nodeAggregate only exists if it at least contains one node assert($nodesByOccupiedDimensionSpacePoint !== []); - return new NodeAggregate( + return NodeAggregate::create( $this->contentRepositoryId, $workspaceName, NodeAggregateId::fromString($rawNodeAggregateId), @@ -315,7 +315,7 @@ public function mapNodeRowsToNodeAggregates( foreach ($nodesByOccupiedDimensionSpacePointsByNodeAggregate as $rawNodeAggregateId => $nodes) { /** @var string $rawNodeAggregateId */ - yield new NodeAggregate( + yield NodeAggregate::create( $this->contentRepositoryId, $workspaceName, NodeAggregateId::fromString($rawNodeAggregateId), diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/NodeFactory.php b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/NodeFactory.php index 923bbfdaa4e..52a0b7b080b 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/NodeFactory.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/NodeFactory.php @@ -243,7 +243,7 @@ public function mapNodeRowsToNodeAggregate( } } - return new NodeAggregate( + return NodeAggregate::create( $this->contentRepositoryId, WorkspaceName::fromString('missing'), // todo $nodeAggregateId, @@ -342,7 +342,7 @@ public function mapNodeRowsToNodeAggregates(array $nodeRows, VisibilityConstrain } foreach ($nodeAggregateIds as $key => $nodeAggregateId) { - yield new NodeAggregate( + yield NodeAggregate::create( $this->contentRepositoryId, WorkspaceName::fromString('missing'), // todo $nodeAggregateId, diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/NodeAggregate.php b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/NodeAggregate.php index abb806d2451..73f078fac2c 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/NodeAggregate.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/NodeAggregate.php @@ -74,7 +74,7 @@ * @param OriginByCoverage $occupationByCovered * @param DimensionSpacePointsBySubtreeTags $dimensionSpacePointsBySubtreeTags dimension space points for every subtree tag this node aggregate is *explicitly* tagged with (excluding inherited tags) */ - public function __construct( + private function __construct( public ContentRepositoryId $contentRepositoryId, public WorkspaceName $workspaceName, public NodeAggregateId $nodeAggregateId, @@ -94,9 +94,9 @@ public function __construct( } /** - * @internal The signature of this method can change in the future! * @param non-empty-array $nodesByOccupiedDimensionSpacePoint * @param non-empty-array $nodesByCoveredDimensionSpacePoint + * @internal The signature of this method can change in the future! */ public static function create( ContentRepositoryId $contentRepositoryId,