diff --git a/.editorconfig b/.editorconfig index 83969142f7..a5da92207d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,7 +6,7 @@ trim_trailing_whitespace = true indent_style = space indent_size = 4 -[*.{yml,yaml,json,xlf}] +[*.{feature,yml,yaml,json,xlf}] indent_size = 2 [*.md] diff --git a/Classes/LinkEditor/Application/GetTree/GetTreeQueryHandler.php b/Classes/LinkEditor/Application/GetTree/GetTreeQueryHandler.php index 113ef65240..2ad41ccaee 100644 --- a/Classes/LinkEditor/Application/GetTree/GetTreeQueryHandler.php +++ b/Classes/LinkEditor/Application/GetTree/GetTreeQueryHandler.php @@ -83,7 +83,7 @@ private function performSearch( $matchingNodes = $nodeService->search( rootNode: $rootNode, searchTerm: $query->searchTerm, - nodeTypeFilter: $narrowNodeTypeFilter, + nodeTypeFilter: $narrowNodeTypeFilter->isEmpty() ? $baseNodeTypeFilter : $narrowNodeTypeFilter, ); $treeBuilder = $nodeService->createTreeBuilderForRootNode( diff --git a/Classes/LinkEditor/Infrastructure/ESCR/NodeService.php b/Classes/LinkEditor/Infrastructure/ESCR/NodeService.php index ca0f4b693e..f5e3e56ee3 100644 --- a/Classes/LinkEditor/Infrastructure/ESCR/NodeService.php +++ b/Classes/LinkEditor/Infrastructure/ESCR/NodeService.php @@ -90,16 +90,20 @@ public function findParentNode(Node $node): ?Node return $this->subgraph->findParentNode($node->aggregateId); } - public function findPrecedingSiblingNodes(Node $node): Nodes + public function findPrecedingSiblingNodes(Node $node, NodeTypeFilter $nodeTypeFilter): Nodes { - $filter = FindPrecedingSiblingNodesFilter::create(); + $filter = FindPrecedingSiblingNodesFilter::create( + nodeTypes: $nodeTypeFilter->nodeTypeCriteria, + ); return $this->subgraph->findPrecedingSiblingNodes($node->aggregateId, $filter); } - public function findSucceedingSiblingNodes(Node $node): Nodes + public function findSucceedingSiblingNodes(Node $node, NodeTypeFilter $nodeTypeFilter): Nodes { - $filter = FindSucceedingSiblingNodesFilter::create(); + $filter = FindSucceedingSiblingNodesFilter::create( + nodeTypes: $nodeTypeFilter->nodeTypeCriteria, + ); return $this->subgraph->findSucceedingSiblingNodes($node->aggregateId, $filter); } diff --git a/Classes/LinkEditor/Infrastructure/ESCR/NodeTypeFilter.php b/Classes/LinkEditor/Infrastructure/ESCR/NodeTypeFilter.php index 2b7be07cca..24ab01fbec 100644 --- a/Classes/LinkEditor/Infrastructure/ESCR/NodeTypeFilter.php +++ b/Classes/LinkEditor/Infrastructure/ESCR/NodeTypeFilter.php @@ -38,9 +38,9 @@ public function getAllowedNodeTypeNames(): NodeTypeNames return $this->allowedNodeTypeNames; } - public function toFilterString(): string + public function isEmpty(): bool { - throw new \Exception(__METHOD__ . ' is not implemented yet!'); + return $this->nodeTypeCriteria->explicitlyAllowedNodeTypeNames->isEmpty() && $this->nodeTypeCriteria->explicitlyDisallowedNodeTypeNames->isEmpty(); } public function isSatisfiedByNode(Node $node): bool diff --git a/Classes/LinkEditor/Infrastructure/ESCR/TreeBuilder.php b/Classes/LinkEditor/Infrastructure/ESCR/TreeBuilder.php index 2f61329407..66de49b693 100644 --- a/Classes/LinkEditor/Infrastructure/ESCR/TreeBuilder.php +++ b/Classes/LinkEditor/Infrastructure/ESCR/TreeBuilder.php @@ -95,30 +95,24 @@ public function addNodeWithSiblingsAndAncestors(Node $node): self /** @var Node $parentNode */ $parentTreeNodeBuilder = $addNodeWithSiblingsAndParentRecursively($parentNode); - foreach ($this->nodeService->findPrecedingSiblingNodes($node) as $siblingNode) { - /** @var Node $siblingNode */ - if ($this->nodeSearchSpecification->baseNodeTypeFilter->isSatisfiedByNode($siblingNode)) { - $siblingTreeNodeBuilder = $this->addNode($siblingNode); - $siblingTreeNodeBuilder->setHasUnloadedChildren( - $this->nodeService->getNumberOfChildNodes($siblingNode, $this->nodeSearchSpecification->baseNodeTypeFilter->nodeTypeCriteria) > 0, - ); - - $parentTreeNodeBuilder->addChild($siblingTreeNodeBuilder); - } + foreach ($this->nodeService->findPrecedingSiblingNodes($node, $this->nodeSearchSpecification->baseNodeTypeFilter) as $siblingNode) { + $siblingTreeNodeBuilder = $this->addNode($siblingNode); + $siblingTreeNodeBuilder->setHasUnloadedChildren( + $this->nodeService->getNumberOfChildNodes($siblingNode, $this->nodeSearchSpecification->baseNodeTypeFilter->nodeTypeCriteria) > 0, + ); + + $parentTreeNodeBuilder->addChild($siblingTreeNodeBuilder); } $parentTreeNodeBuilder->addChild($treeNodeBuilder); - foreach ($this->nodeService->findSucceedingSiblingNodes($node) as $siblingNode) { - /** @var Node $siblingNode */ - if ($this->nodeSearchSpecification->baseNodeTypeFilter->isSatisfiedByNode($siblingNode)) { - $siblingTreeNodeBuilder = $this->addNode($siblingNode); - $siblingTreeNodeBuilder->setHasUnloadedChildren( - $this->nodeService->getNumberOfChildNodes($siblingNode, $this->nodeSearchSpecification->baseNodeTypeFilter->nodeTypeCriteria) > 0, - ); + foreach ($this->nodeService->findSucceedingSiblingNodes($node, $this->nodeSearchSpecification->baseNodeTypeFilter) as $siblingNode) { + $siblingTreeNodeBuilder = $this->addNode($siblingNode); + $siblingTreeNodeBuilder->setHasUnloadedChildren( + $this->nodeService->getNumberOfChildNodes($siblingNode, $this->nodeSearchSpecification->baseNodeTypeFilter->nodeTypeCriteria) > 0, + ); - $parentTreeNodeBuilder->addChild($siblingTreeNodeBuilder); - } + $parentTreeNodeBuilder->addChild($siblingTreeNodeBuilder); } $parentTreeNodeBuilder->setHasUnloadedChildren(false); diff --git a/Tests/Behavior/Features/LinkEditor/04-GetChildrenForTreeNode.feature b/Tests/Behavior/Features/LinkEditor/04-GetChildrenForTreeNode.feature index 32dcf0f353..3ba462609e 100644 --- a/Tests/Behavior/Features/LinkEditor/04-GetChildrenForTreeNode.feature +++ b/Tests/Behavior/Features/LinkEditor/04-GetChildrenForTreeNode.feature @@ -13,6 +13,9 @@ Feature: GetChildrenForTreeNode 'Neos.Neos:Content': abstract: true + 'Neos.Neos:ContentCollection': + abstract: true + 'Neos.Neos:Document': abstract: true properties: @@ -30,6 +33,9 @@ Feature: GetChildrenForTreeNode ui: icon: "my-icon" label: "My Document Type" + childNodes: + main: + type: "Neos.Neos:ContentCollection" 'Vendor.Site:OtherDocument': label: "My Other Node" @@ -38,6 +44,9 @@ Feature: GetChildrenForTreeNode ui: icon: "my-other-icon" label: "My Other Document Type" + childNodes: + main: + type: "Neos.Neos:ContentCollection" 'Vendor.Site:Content': superTypes: @@ -176,7 +185,7 @@ Feature: GetChildrenForTreeNode | workspaceName | "live" | | dimensionValues | {"language": ["en"]} | | treeNodeId | "feature-a-multi-dsp" | - | nodeTypeFilter | "" | + | nodeTypeFilter | "Neos.Neos:Document" | | linkableNodeTypes | [] | Then I expect the following query response: """json @@ -284,7 +293,7 @@ Feature: GetChildrenForTreeNode | workspaceName | "live" | | dimensionValues | {"language": ["de"]} | | treeNodeId | "features" | - | nodeTypeFilter | "" | + | nodeTypeFilter | "Neos.Neos:Document" | | linkableNodeTypes | [] | Then I expect the following query response: """json diff --git a/Tests/Behavior/Features/LinkEditor/06-GetTreeQuery.feature b/Tests/Behavior/Features/LinkEditor/06-GetTreeQuery.feature index 19ee1d148c..32798598f0 100644 --- a/Tests/Behavior/Features/LinkEditor/06-GetTreeQuery.feature +++ b/Tests/Behavior/Features/LinkEditor/06-GetTreeQuery.feature @@ -13,6 +13,9 @@ Feature: GetTreeQuery 'Neos.Neos:Content': abstract: true + 'Neos.Neos:ContentCollection': + abstract: true + 'Neos.Neos:Document': abstract: true properties: @@ -34,6 +37,9 @@ Feature: GetTreeQuery ui: icon: "my-icon" label: "My Document Type" + childNodes: + main: + type: "Neos.Neos:ContentCollection" 'Vendor.Site:OtherDocument': label: "My Other Node" @@ -42,6 +48,9 @@ Feature: GetTreeQuery ui: icon: "my-other-icon" label: "My Other Document Type" + childNodes: + main: + type: "Neos.Neos:ContentCollection" 'Vendor.Site:Content': superTypes: @@ -49,6 +58,9 @@ Feature: GetTreeQuery ui: icon: "my-content" label: "My Content" + properties: + text: + type: string 'Vendor.Site:SpecialLinkable': abstract: true @@ -85,6 +97,7 @@ Feature: GetTreeQuery | features | homepage | Vendor.Site:Document | {"title": "features"} | {"language": "en"} | features | | features-content | features | Vendor.Site:Content | {} | {"language": "en"} | | | feature-a-default | features | Vendor.Site:Document | {"title": "a"} | {"language": "en"} | a | + | feature-a-content | feature-a-default | Vendor.Site:Content | {} | {"language": "en"} | | | feature-a1-default | feature-a-default | Vendor.Site:Document | {"title": "a1"} | {"language": "en"} | leaf | | feature-a2-default | feature-a-default | Vendor.Site:Document | {"title": "a2"} | {"language": "en"} | | | feature-b-disabled | features | Vendor.Site:Document | {"title": "b"} | {"language": "en"} | | @@ -102,6 +115,7 @@ Feature: GetTreeQuery | search-a2-other-type | search-a-default | Vendor.Site:OtherDocument | {"title": "a2"} | {"language": "en"} | | | search-a3-other-text | search-a-default | Vendor.Site:OtherDocument | {"title": "a3 special text"} | {"language": "en"} | | | search-b-with-text | search | Vendor.Site:Document | {"title": "b special text"} | {"language": "en"} | | + | search-b-content | search-b-with-text | Vendor.Site:Content | {"text": "b' special text"} | {"language": "en"} | | | search-c-other-type | search | Vendor.Site:OtherDocument | {"title": "c"} | {"language": "en"} | | And the command CreateNodeVariant is executed with payload: @@ -309,7 +323,7 @@ Feature: GetTreeQuery | dimensionValues | {"language": ["en"]} | | startingPoint | "//site-a/features/a/leaf" | | loadingDepth | 8 | - | baseNodeTypeFilter | "" | + | baseNodeTypeFilter | "Neos.Neos:Document" | | linkableNodeTypes | [] | | narrowNodeTypeFilter | "" | | searchTerm | "" | @@ -884,7 +898,7 @@ Feature: GetTreeQuery | dimensionValues | {"language": ["en"]} | | startingPoint | "//site-a/features/a/leaf" | | loadingDepth | 8 | - | baseNodeTypeFilter | "" | + | baseNodeTypeFilter | "Neos.Neos:Document" | | linkableNodeTypes | [] | | narrowNodeTypeFilter | "" | | searchTerm | "" | @@ -1034,7 +1048,7 @@ Feature: GetTreeQuery } """ - Examples: - | selectedNodeId | - | "feature-a1-default" | - | "feature-a2-default" | + Examples: + | selectedNodeId | + | "feature-a1-default" | + | "feature-a2-default" |