From 5bee4722cea91d7789a7779a723f6f6c675f6a48 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 24 Sep 2024 15:24:26 +0200 Subject: [PATCH 1/7] TASK: Make `::map` operation on value objects generic --- .../Classes/EventStore/Events.php | 5 +++-- .../Feature/SubtreeTagging/Dto/SubtreeTags.php | 5 +++-- .../Classes/NodeType/NodeTypeNames.php | 14 ++++++++++++-- .../Classes/Projection/ContentGraph/NodeTags.php | 5 +++-- .../Classes/Projection/ContentGraph/Nodes.php | 5 +++-- .../Classes/SharedModel/Node/NodeAggregateIds.php | 10 ++++++++++ 6 files changed, 34 insertions(+), 10 deletions(-) diff --git a/Neos.ContentRepository.Core/Classes/EventStore/Events.php b/Neos.ContentRepository.Core/Classes/EventStore/Events.php index 05826f0d1cb..5bd6713c623 100644 --- a/Neos.ContentRepository.Core/Classes/EventStore/Events.php +++ b/Neos.ContentRepository.Core/Classes/EventStore/Events.php @@ -45,8 +45,9 @@ public function getIterator(): \Traversable } /** - * @param \Closure $callback - * @return array + * @template T + * @param \Closure(EventInterface|DecoratedEvent $event): T $callback + * @return list */ public function map(\Closure $callback): array { diff --git a/Neos.ContentRepository.Core/Classes/Feature/SubtreeTagging/Dto/SubtreeTags.php b/Neos.ContentRepository.Core/Classes/Feature/SubtreeTagging/Dto/SubtreeTags.php index 0cdafd7cad7..95a826ed52a 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/SubtreeTagging/Dto/SubtreeTags.php +++ b/Neos.ContentRepository.Core/Classes/Feature/SubtreeTagging/Dto/SubtreeTags.php @@ -89,8 +89,9 @@ public function merge(self $other): self } /** - * @param \Closure(SubtreeTag): mixed $callback - * @return array + * @template T + * @param \Closure(SubtreeTag $tag): T $callback + * @return list */ public function map(\Closure $callback): array { diff --git a/Neos.ContentRepository.Core/Classes/NodeType/NodeTypeNames.php b/Neos.ContentRepository.Core/Classes/NodeType/NodeTypeNames.php index df9afdd9467..86fba431f5f 100644 --- a/Neos.ContentRepository.Core/Classes/NodeType/NodeTypeNames.php +++ b/Neos.ContentRepository.Core/Classes/NodeType/NodeTypeNames.php @@ -49,7 +49,7 @@ public static function fromArray(array $array): self */ public static function fromStringArray(array $array): self { - return new self(... array_map( + return new self(...array_map( fn(string $serializedNodeTypeName): NodeTypeName => NodeTypeName::fromString($serializedNodeTypeName), $array )); @@ -79,12 +79,22 @@ public function getIterator(): \Traversable yield from $this->nodeTypeNames; } + /** + * @template T + * @param \Closure(NodeTypeName $nodeTypeName): T $callback + * @return list + */ + public function map(\Closure $callback): array + { + return array_map($callback, $this->nodeTypeNames); + } + /** * @return array */ public function toStringArray(): array { - return array_map(fn(NodeTypeName $nodeTypeName) => $nodeTypeName->value, $this->nodeTypeNames); + return $this->map(fn(NodeTypeName $nodeTypeName) => $nodeTypeName->value); } public function isEmpty(): bool diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/NodeTags.php b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/NodeTags.php index 06794251a50..c22faebd7f4 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/NodeTags.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/NodeTags.php @@ -97,8 +97,9 @@ public function all(): SubtreeTags } /** - * @param \Closure(SubtreeTag $tag, bool $inherited): mixed $callback - * @return array + * @template T + * @param \Closure(SubtreeTag $tag, bool $inherited): T $callback + * @return list */ public function map(\Closure $callback): array { diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/Nodes.php b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/Nodes.php index ef55a5f8afe..3e011714e4a 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/Nodes.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/Nodes.php @@ -209,8 +209,9 @@ public function nextAll(Node $referenceNode): self } /** - * @param \Closure(Node $node): mixed $callback - * @return array + * @template T + * @param \Closure(Node $node): T $callback + * @return list */ public function map(\Closure $callback): array { diff --git a/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php b/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php index f8abbbcc3d7..897f6b7a4d1 100644 --- a/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php +++ b/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php @@ -116,4 +116,14 @@ public function getIterator(): \Traversable { yield from $this->nodeAggregateIds; } + + /** + * @template T + * @param \Closure(NodeAggregateId $nodeAggregateId): T $callback + * @return list + */ + public function map(\Closure $callback): array + { + return array_map($callback, $this->nodeAggregateIds); + } } From 3a8178bc070061a5afa7a354cc8df039302a7442 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 24 Sep 2024 15:25:16 +0200 Subject: [PATCH 2/7] TASK: Simplify `CacheTagSet::toStringArray` The uniqueness is already ensured in the constructor. --- Neos.Neos/Classes/Fusion/Cache/CacheTagSet.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Neos.Neos/Classes/Fusion/Cache/CacheTagSet.php b/Neos.Neos/Classes/Fusion/Cache/CacheTagSet.php index 7a1a8142d75..7c58ec8a4b6 100644 --- a/Neos.Neos/Classes/Fusion/Cache/CacheTagSet.php +++ b/Neos.Neos/Classes/Fusion/Cache/CacheTagSet.php @@ -117,12 +117,7 @@ public function add(CacheTag $cacheTag): self */ public function toStringArray(): array { - return array_unique( - array_map( - static fn (CacheTag $tag): string => $tag->value, - array_values($this->tags) - ) - ); + return array_keys($this->tags); } public function union(self $other): self From 0dc2a58f5fb275c010c9019eb338bdcf0c5e63fa Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 24 Sep 2024 15:33:38 +0200 Subject: [PATCH 3/7] TASK: Use `Nodes::map` instead of manual `iterator_to_array` and `array_map` in `CacheTagSet` --- .../Classes/Fusion/Cache/CacheTagSet.php | 30 +++++++------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/Neos.Neos/Classes/Fusion/Cache/CacheTagSet.php b/Neos.Neos/Classes/Fusion/Cache/CacheTagSet.php index 7c58ec8a4b6..5af4befda4f 100644 --- a/Neos.Neos/Classes/Fusion/Cache/CacheTagSet.php +++ b/Neos.Neos/Classes/Fusion/Cache/CacheTagSet.php @@ -37,44 +37,38 @@ public function __construct(CacheTag ...$tags) public static function forDescendantOfNodesFromNodes( Nodes $nodes ): self { - return new self(...array_map( - CacheTag::forDescendantOfNodeFromNode(...), - iterator_to_array($nodes), - )); + return new self(...$nodes->map(CacheTag::forDescendantOfNodeFromNode(...))); } public static function forDescendantOfNodesFromNodesWithoutWorkspace( Nodes $nodes, ): self { - return new self(...array_map( + return new self(...$nodes->map( static fn (Node $node) => CacheTag::forDescendantOfNode( $node->contentRepositoryId, CacheTagWorkspaceName::ANY, $node->aggregateId, - ), - iterator_to_array($nodes) + ) )); } public static function forNodeAggregatesFromNodes( Nodes $nodes ): self { - return new self(...array_map( - CacheTag::forNodeAggregateFromNode(...), - iterator_to_array($nodes) + return new self(...$nodes->map( + CacheTag::forNodeAggregateFromNode(...) )); } public static function forNodeAggregatesFromNodesWithoutWorkspace( Nodes $nodes ): self { - return new self(...array_map( + return new self(...$nodes->map( static fn (Node $node) => CacheTag::forNodeAggregate( $node->contentRepositoryId, CacheTagWorkspaceName::ANY, $node->aggregateId - ), - iterator_to_array($nodes), + ) )); } @@ -83,24 +77,22 @@ public static function forNodeTypeNames( WorkspaceName|CacheTagWorkspaceName $workspaceName, NodeTypeNames $nodeTypeNames ): self { - return new self(...array_map( + return new self(...$nodeTypeNames->map( static fn (NodeTypeName $nodeTypeName): CacheTag => CacheTag::forNodeTypeName( $contentRepositoryId, $workspaceName, $nodeTypeName - ), - iterator_to_array($nodeTypeNames) + ) )); } public static function forWorkspaceNameFromNodes(Nodes $nodes): self { - return new self(...array_map( + return new self(...$nodes->map( static fn (Node $node): CacheTag => CacheTag::forWorkspaceName( $node->contentRepositoryId, $node->workspaceName, - ), - iterator_to_array($nodes) + ) )); } From 970f2071a1cb990eb94eb9fb72921cf6005231d7 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 24 Sep 2024 15:36:24 +0200 Subject: [PATCH 4/7] TASK: Simplify `NodeAggregateIds::fromNodes` --- .../Classes/SharedModel/Node/NodeAggregateIds.php | 4 +--- Neos.Neos/Classes/Fusion/MenuItemsImplementation.php | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php b/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php index 897f6b7a4d1..2f82ab604b5 100644 --- a/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php +++ b/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php @@ -70,9 +70,7 @@ public static function fromJsonString(string $jsonString): self public static function fromNodes(Nodes $nodes): self { - return self::fromArray( - array_map(fn(Node $node) => $node->aggregateId, iterator_to_array($nodes)) - ); + return $nodes->toNodeAggregateIds(); } public function merge(self $other): self diff --git a/Neos.Neos/Classes/Fusion/MenuItemsImplementation.php b/Neos.Neos/Classes/Fusion/MenuItemsImplementation.php index 6df043d367d..9b10e77ba93 100644 --- a/Neos.Neos/Classes/Fusion/MenuItemsImplementation.php +++ b/Neos.Neos/Classes/Fusion/MenuItemsImplementation.php @@ -311,7 +311,7 @@ protected function getCurrentNodeRootlineAggregateIds(): NodeAggregateIds ); $this->currentNodeRootlineAggregateIds = NodeAggregateIds::create($this->currentNode->aggregateId) - ->merge(NodeAggregateIds::fromNodes($currentNodeAncestors)); + ->merge($currentNodeAncestors->toNodeAggregateIds()); return $this->currentNodeRootlineAggregateIds; } From 7331e4016a9eee78e945252f6e4cd5e4f56043af Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 24 Sep 2024 15:40:47 +0200 Subject: [PATCH 5/7] TASK: Make `NodeAggregateIds` countable --- .../Classes/SharedModel/Node/NodeAggregateIds.php | 8 ++++++-- Neos.Neos/Classes/Fusion/MenuItemsImplementation.php | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php b/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php index 2f82ab604b5..896edfec6bd 100644 --- a/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php +++ b/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php @@ -14,7 +14,6 @@ namespace Neos\ContentRepository\Core\SharedModel\Node; -use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\ContentGraph\Nodes; /** @@ -23,7 +22,7 @@ * @implements \IteratorAggregate * @api */ -final class NodeAggregateIds implements \IteratorAggregate, \JsonSerializable +final class NodeAggregateIds implements \IteratorAggregate, \Countable, \JsonSerializable { /** * @var array @@ -124,4 +123,9 @@ public function map(\Closure $callback): array { return array_map($callback, $this->nodeAggregateIds); } + + public function count(): int + { + return count($this->nodeAggregateIds); + } } diff --git a/Neos.Neos/Classes/Fusion/MenuItemsImplementation.php b/Neos.Neos/Classes/Fusion/MenuItemsImplementation.php index 9b10e77ba93..12bb91be2bb 100644 --- a/Neos.Neos/Classes/Fusion/MenuItemsImplementation.php +++ b/Neos.Neos/Classes/Fusion/MenuItemsImplementation.php @@ -196,7 +196,7 @@ protected function buildItems(): array $maximumLevels = min($maximumLevels, $maxLevelsBasedOnLastLevel); } elseif ($lastLevels < 0) { $currentNodeAncestorAggregateIds = $this->getCurrentNodeRootlineAggregateIds(); - $depthOfCurrentDocument = count(iterator_to_array($currentNodeAncestorAggregateIds)) - 1; + $depthOfCurrentDocument = count($currentNodeAncestorAggregateIds) - 1; $maxLevelsBasedOnLastLevel = max($depthOfCurrentDocument + $lastLevels - $depthOfEntryParentNodeAggregateId + 1, 0); $maximumLevels = min($maximumLevels, $maxLevelsBasedOnLastLevel); } From e40ba25ded874b8b4ff454346e29d862b6dc9fb9 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 24 Sep 2024 19:17:04 +0200 Subject: [PATCH 6/7] TASK: Adjust NodeAggregateIds::map to return a list --- .../Classes/SharedModel/Node/NodeAggregateIds.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php b/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php index 896edfec6bd..90a1f1aa0c9 100644 --- a/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php +++ b/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php @@ -121,7 +121,7 @@ public function getIterator(): \Traversable */ public function map(\Closure $callback): array { - return array_map($callback, $this->nodeAggregateIds); + return array_map($callback, array_values($this->nodeAggregateIds)); } public function count(): int From c3a2349b57bd3cc75e9d237d74ef421a0631a640 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Wed, 25 Sep 2024 19:18:26 +0200 Subject: [PATCH 7/7] TASK: Make `NodeAggregateIds::fromNodes` contain the `toNodeAggregateIds` logic This is the proper composition, if we already have the two --- .../Classes/Projection/ContentGraph/Nodes.php | 4 +--- .../Classes/SharedModel/Node/NodeAggregateIds.php | 7 +++++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/Nodes.php b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/Nodes.php index 3e011714e4a..c4f224f583e 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/Nodes.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/Nodes.php @@ -220,8 +220,6 @@ public function map(\Closure $callback): array public function toNodeAggregateIds(): NodeAggregateIds { - return NodeAggregateIds::create(...$this->map( - fn (Node $node): NodeAggregateId => $node->aggregateId, - )); + return NodeAggregateIds::fromNodes($this); } } diff --git a/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php b/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php index 90a1f1aa0c9..d837e8f1da1 100644 --- a/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php +++ b/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php @@ -14,6 +14,7 @@ namespace Neos\ContentRepository\Core\SharedModel\Node; +use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\ContentGraph\Nodes; /** @@ -37,7 +38,7 @@ private function __construct(NodeAggregateId ...$nodeAggregateIds) public static function createEmpty(): self { - return new self(...[]); + return new self(); } public static function create(NodeAggregateId ...$nodeAggregateIds): self @@ -69,7 +70,9 @@ public static function fromJsonString(string $jsonString): self public static function fromNodes(Nodes $nodes): self { - return $nodes->toNodeAggregateIds(); + return self::fromArray($nodes->map( + fn (Node $node): NodeAggregateId => $node->aggregateId, + )); } public function merge(self $other): self