From c464d6831a8e59dfa6c1901007cf3d882ddc4864 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 1 Jun 2023 21:26:47 +0200 Subject: [PATCH 01/43] BUGFIX: NodeInfoHelper::isAutoCreated handle nodeName == null --- Classes/Fusion/Helper/NodeInfoHelper.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Classes/Fusion/Helper/NodeInfoHelper.php b/Classes/Fusion/Helper/NodeInfoHelper.php index d85ac50063..7c9b924d60 100644 --- a/Classes/Fusion/Helper/NodeInfoHelper.php +++ b/Classes/Fusion/Helper/NodeInfoHelper.php @@ -253,6 +253,9 @@ protected function getBasicNodeInformation(Node $node): array public static function isAutoCreated(Node $node, ContentSubgraphInterface $subgraph): bool { + if (!$node->nodeName) { + return false; + } $parent = $subgraph->findParentNode($node->nodeAggregateId); if ($parent) { if (array_key_exists($node->nodeName->value, $parent->nodeType->getAutoCreatedChildNodes())) { From ec3ef24e06a1831dc64f7f304dbd0605c920e402 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Fri, 1 Sep 2023 22:30:45 +0200 Subject: [PATCH 02/43] !!! TASK: Remove `NodeInfoHelper::isAutoCreated` for `$node->classification === Classification::CLASSIFICATION_TETHERED` --- .../Model/Changes/AbstractStructuralChange.php | 4 ++-- Classes/Fusion/Helper/NodeInfoHelper.php | 17 ++--------------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/Classes/Domain/Model/Changes/AbstractStructuralChange.php b/Classes/Domain/Model/Changes/AbstractStructuralChange.php index 32cdfde7d7..b1a18ad614 100644 --- a/Classes/Domain/Model/Changes/AbstractStructuralChange.php +++ b/Classes/Domain/Model/Changes/AbstractStructuralChange.php @@ -15,6 +15,7 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindChildNodesFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\NodeType\NodeType; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateClassification; use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\ContentRepository\Core\Projection\ContentGraph\Nodes; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; @@ -25,7 +26,6 @@ use Neos\Neos\Ui\Domain\Model\Feedback\Operations\RenderContentOutOfBand; use Neos\Neos\Ui\Domain\Model\Feedback\Operations\UpdateNodeInfo; use Neos\Neos\Ui\Domain\Model\RenderedNodeDomAddress; -use Neos\Neos\Ui\Fusion\Helper\NodeInfoHelper; /** * A change that performs structural actions like moving or creating nodes @@ -187,7 +187,7 @@ protected function findChildNodes(Node $node): Nodes protected function isNodeTypeAllowedAsChildNode(Node $node, NodeType $nodeType): bool { $subgraph = $this->contentRepositoryRegistry->subgraphForNode($node); - if (NodeInfoHelper::isAutoCreated($node, $subgraph)) { + if ($node->classification === NodeAggregateClassification::CLASSIFICATION_TETHERED) { $parentNode = $subgraph->findParentNode($node->nodeAggregateId); return !$parentNode || $parentNode->nodeType->allowsGrandchildNodeType( $node->nodeName->value, diff --git a/Classes/Fusion/Helper/NodeInfoHelper.php b/Classes/Fusion/Helper/NodeInfoHelper.php index 7c9b924d60..0f93e9b853 100644 --- a/Classes/Fusion/Helper/NodeInfoHelper.php +++ b/Classes/Fusion/Helper/NodeInfoHelper.php @@ -17,6 +17,7 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\ContentGraph\Nodes; use Neos\ContentRepository\Core\Projection\NodeHiddenState\NodeHiddenStateFinder; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateClassification; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Eel\ProtectedContextAwareInterface; use Neos\Flow\Annotations as Flow; @@ -236,7 +237,7 @@ protected function getBasicNodeInformation(Node $node): array 'identifier' => $node->nodeAggregateId->jsonSerialize(), 'nodeType' => $node->nodeType->getName(), 'label' => $node->getLabel(), - 'isAutoCreated' => self::isAutoCreated($node, $subgraph), + 'isAutoCreated' => $node->classification === NodeAggregateClassification::CLASSIFICATION_TETHERED, // TODO: depth is expensive to calculate; maybe let's get rid of this? 'depth' => $subgraph->countAncestorNodes( $node->nodeAggregateId, @@ -251,20 +252,6 @@ protected function getBasicNodeInformation(Node $node): array ]; } - public static function isAutoCreated(Node $node, ContentSubgraphInterface $subgraph): bool - { - if (!$node->nodeName) { - return false; - } - $parent = $subgraph->findParentNode($node->nodeAggregateId); - if ($parent) { - if (array_key_exists($node->nodeName->value, $parent->nodeType->getAutoCreatedChildNodes())) { - return true; - } - } - return false; - } - /** * Get information for all children of the given parent node. * From c85c2412c7e0a299368ca93ed4cc404e3bde2188 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Fri, 1 Sep 2023 22:32:31 +0200 Subject: [PATCH 03/43] !!! TASK: Let UI create nodes without nodeName by default --- Classes/Domain/Model/Changes/AbstractCreate.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Classes/Domain/Model/Changes/AbstractCreate.php b/Classes/Domain/Model/Changes/AbstractCreate.php index a8aa6a5bcb..fe949a2715 100644 --- a/Classes/Domain/Model/Changes/AbstractCreate.php +++ b/Classes/Domain/Model/Changes/AbstractCreate.php @@ -97,9 +97,9 @@ protected function createNode( if (is_null($nodeTypeName)) { throw new \RuntimeException('Cannot run createNode without a set node type.', 1645577794); } - // TODO: the $name=... line should be as expressed below - // $name = $this->getName() ?: $this->nodeService->generateUniqueNodeName($parent->findParentNode()); - $nodeName = NodeName::fromString($this->getName() ?: uniqid('node-', false)); + $nodeName = $this->getName() + ? NodeName::fromString($this->getName()) + : null; $nodeAggregateId = NodeAggregateId::create(); // generate a new NodeAggregateId From f3210a0d84b51dc54074218b9cad22737833015a Mon Sep 17 00:00:00 2001 From: bwaidelich Date: Fri, 22 Sep 2023 18:56:13 +0200 Subject: [PATCH 04/43] TASK: Adjust to renamed `NodeTypeConstraints` See https://github.com/neos/neos-development-collection/pull/4551 Related: https://github.com/neos/neos-development-collection/issues/4522 --- .../FlowQueryOperations/NeosUiDefaultNodesOperation.php | 8 ++++---- .../NeosUiFilteredChildrenOperation.php | 4 ++-- Classes/FlowQueryOperations/SearchOperation.php | 4 ++-- Classes/Fusion/Helper/NodeInfoHelper.php | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Classes/FlowQueryOperations/NeosUiDefaultNodesOperation.php b/Classes/FlowQueryOperations/NeosUiDefaultNodesOperation.php index 4d80cd82b4..732862e982 100644 --- a/Classes/FlowQueryOperations/NeosUiDefaultNodesOperation.php +++ b/Classes/FlowQueryOperations/NeosUiDefaultNodesOperation.php @@ -15,7 +15,7 @@ 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\NodeTypeConstraints; +use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\NodeType\NodeTypeCriteria; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Eel\FlowQuery\FlowQuery; use Neos\Eel\FlowQuery\Operations\AbstractOperation; @@ -75,14 +75,14 @@ public function evaluate(FlowQuery $flowQuery, array $arguments) $contentRepository = $this->contentRepositoryRegistry->get($documentNode->subgraphIdentity->contentRepositoryId); $nodeAddressFactory = NodeAddressFactory::create($contentRepository); - $baseNodeTypeConstraints = NodeTypeConstraints::fromFilterString($baseNodeType); + $baseNodeTypeConstraints = NodeTypeCriteria::fromFilterString($baseNodeType); $subgraph = $this->contentRepositoryRegistry->subgraphForNode($documentNode); $ancestors = $subgraph->findAncestorNodes( $documentNode->nodeAggregateId, FindAncestorNodesFilter::create( - NodeTypeConstraints::fromFilterString('Neos.Neos:Document') + NodeTypeCriteria::fromFilterString('Neos.Neos:Document') ) ); @@ -118,7 +118,7 @@ public function evaluate(FlowQuery $flowQuery, array $arguments) ) { foreach ($subgraph->findChildNodes( $baseNode->nodeAggregateId, - FindChildNodesFilter::create(nodeTypeConstraints: $baseNodeTypeConstraints) + FindChildNodesFilter::create(nodeTypes: $baseNodeTypeConstraints) ) as $childNode) { $nodes[$childNode->nodeAggregateId->value] = $childNode; $gatherNodesRecursively($nodes, $childNode, $level + 1); diff --git a/Classes/FlowQueryOperations/NeosUiFilteredChildrenOperation.php b/Classes/FlowQueryOperations/NeosUiFilteredChildrenOperation.php index 61efadd222..56cb578f34 100644 --- a/Classes/FlowQueryOperations/NeosUiFilteredChildrenOperation.php +++ b/Classes/FlowQueryOperations/NeosUiFilteredChildrenOperation.php @@ -14,7 +14,7 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindChildNodesFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\NodeType\NodeTypeConstraintParser; -use Neos\ContentRepository\Core\Projection\ContentGraph\NodeTypeConstraints; +use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\NodeType\NodeTypeCriteria; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Eel\FlowQuery\FlowQuery; use Neos\Eel\FlowQuery\Operations\AbstractOperation; @@ -76,7 +76,7 @@ public function evaluate(FlowQuery $flowQuery, array $arguments) foreach ($subgraph->findChildNodes( $contextNode->nodeAggregateId, - FindChildNodesFilter::create(nodeTypeConstraints: $arguments[0] ?? null) + FindChildNodesFilter::create(nodeTypes: $arguments[0] ?? null) ) as $childNode) { if (!isset($outputNodeIdentifiers[$childNode->nodeAggregateId->value])) { $output[] = $childNode; diff --git a/Classes/FlowQueryOperations/SearchOperation.php b/Classes/FlowQueryOperations/SearchOperation.php index 0b31e9934c..e4af117f9f 100644 --- a/Classes/FlowQueryOperations/SearchOperation.php +++ b/Classes/FlowQueryOperations/SearchOperation.php @@ -15,7 +15,7 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\ContentGraph\SearchTerm; use Neos\ContentRepository\Core\NodeType\NodeTypeConstraintParser; -use Neos\ContentRepository\Core\Projection\ContentGraph\NodeTypeConstraints; +use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\NodeType\NodeTypeCriteria; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateIds; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Eel\FlowQuery\FlowQuery; @@ -80,7 +80,7 @@ public function evaluate(FlowQuery $flowQuery, array $arguments): void $filter = $filter->with(searchTerm: $arguments[0]); } if (isset($arguments[1]) && $arguments[1] !== '') { - $filter = $filter->with(nodeTypeConstraints: $arguments[1]); + $filter = $filter->with(nodeTypes: $arguments[1]); } $nodes = $subgraph->findDescendantNodes( $contextNode->nodeAggregateId, diff --git a/Classes/Fusion/Helper/NodeInfoHelper.php b/Classes/Fusion/Helper/NodeInfoHelper.php index 99242bd3de..b2e4d4c340 100644 --- a/Classes/Fusion/Helper/NodeInfoHelper.php +++ b/Classes/Fusion/Helper/NodeInfoHelper.php @@ -276,13 +276,13 @@ protected function renderChildrenInformation(Node $node, string $nodeTypeFilterS $documentChildNodes = $subgraph->findChildNodes( $node->nodeAggregateId, - FindChildNodesFilter::create(nodeTypeConstraints: $nodeTypeFilterString) + FindChildNodesFilter::create(nodeTypes: $nodeTypeFilterString) ); // child nodes for content tree, must not include those nodes filtered out by `baseNodeType` $contentChildNodes = $subgraph->findChildNodes( $node->nodeAggregateId, FindChildNodesFilter::create( - nodeTypeConstraints: $this->buildContentChildNodeFilterString() + nodeTypes: $this->buildContentChildNodeFilterString() ) ); $childNodes = $documentChildNodes->merge($contentChildNodes); @@ -511,7 +511,7 @@ private function getChildNodes(Node $node, string $nodeTypeFilterString): Nodes return $this->contentRepositoryRegistry->subgraphForNode($node) ->findChildNodes( $node->nodeAggregateId, - FindChildNodesFilter::create(nodeTypeConstraints: $nodeTypeFilterString) + FindChildNodesFilter::create(nodeTypes: $nodeTypeFilterString) ); } From 24bf63fdb281b5d3d03fdd701a8dfa1c6951c30d Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 26 Sep 2023 23:56:58 +0200 Subject: [PATCH 05/43] TASK: Use new `Neos.Neos:Site` abstract NodeType --- .../Resources/Private/Content/events.jsonl | 2 +- .../Resources/Private/Content/events.jsonl | 2 +- .../Neos.TestNodeTypes/NodeTypes/Document/HomePage.yaml | 4 ++++ .../Resources/Private/Fusion/Document/Page/HomePage.fusion | 1 + 4 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.TestNodeTypes/NodeTypes/Document/HomePage.yaml create mode 100644 Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.TestNodeTypes/Resources/Private/Fusion/Document/Page/HomePage.fusion diff --git a/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.Test.OneDimension/Resources/Private/Content/events.jsonl b/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.Test.OneDimension/Resources/Private/Content/events.jsonl index 89cd67b6e6..6bd38fbfeb 100644 --- a/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.Test.OneDimension/Resources/Private/Content/events.jsonl +++ b/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.Test.OneDimension/Resources/Private/Content/events.jsonl @@ -1,6 +1,6 @@ {"identifier":"d08644be-70fd-4f47-9078-f676bbe13544","type":"ContentStreamWasCreated","payload":{"contentStreamId":"7ebcc393-4120-4d29-a0d8-8bc708ecb3f8"},"metadata":[]} {"identifier":"152f7ffe-b2a5-4237-beab-c4db9fa15587","type":"RootNodeAggregateWithNodeWasCreated","payload":{"contentStreamId":"7ebcc393-4120-4d29-a0d8-8bc708ecb3f8","nodeAggregateId":"2fdbb3ea-1270-49bc-8f8b-cbfc563ef9a6","nodeTypeName":"Neos.Neos:Sites","coveredDimensionSpacePoints":[{"language":"en_US"},{"language":"en_UK"},{"language":"de"},{"language":"nl"},{"language":"fr"},{"language":"da"},{"language":"lv"}],"nodeAggregateClassification":"root"},"metadata":[]} -{"identifier":"c977a059-ba63-4132-a190-baa6ced4f614","type":"NodeAggregateWithNodeWasCreated","payload":{"contentStreamId":"7ebcc393-4120-4d29-a0d8-8bc708ecb3f8","nodeAggregateId":"f676459d-ca77-44bc-aeea-44114814c279","nodeTypeName":"Neos.TestNodeTypes:Document.Page","originDimensionSpacePoint":{"language":"fr"},"coveredDimensionSpacePoints":[{"language":"fr"}],"parentNodeAggregateId":"2fdbb3ea-1270-49bc-8f8b-cbfc563ef9a6","nodeName":"neos-test-onedimension","initialPropertyValues":{"title":{"value":"Accueil","type":"string"},"uriPathSegment":{"value":"home","type":"string"}},"nodeAggregateClassification":"regular","succeedingNodeAggregateId":null},"metadata":[]} +{"identifier":"c977a059-ba63-4132-a190-baa6ced4f614","type":"NodeAggregateWithNodeWasCreated","payload":{"contentStreamId":"7ebcc393-4120-4d29-a0d8-8bc708ecb3f8","nodeAggregateId":"f676459d-ca77-44bc-aeea-44114814c279","nodeTypeName":"Neos.TestNodeTypes:Document.HomePage","originDimensionSpacePoint":{"language":"fr"},"coveredDimensionSpacePoints":[{"language":"fr"}],"parentNodeAggregateId":"2fdbb3ea-1270-49bc-8f8b-cbfc563ef9a6","nodeName":"neos-test-onedimension","initialPropertyValues":{"title":{"value":"Accueil","type":"string"},"uriPathSegment":{"value":"home","type":"string"}},"nodeAggregateClassification":"regular","succeedingNodeAggregateId":null},"metadata":[]} {"identifier":"7e1e6a07-b80f-4cad-8fe6-519d34b86cad","type":"NodePeerVariantWasCreated","payload":{"contentStreamId":"7ebcc393-4120-4d29-a0d8-8bc708ecb3f8","nodeAggregateId":"f676459d-ca77-44bc-aeea-44114814c279","sourceOrigin":{"language":"fr"},"peerOrigin":{"language":"en_UK"},"peerCoverage":[{"language":"en_UK"}]},"metadata":[]} {"identifier":"37c01008-80f0-4252-8ff5-d44154cec8e7","type":"NodePropertiesWereSet","payload":{"contentStreamId":"7ebcc393-4120-4d29-a0d8-8bc708ecb3f8","nodeAggregateId":"f676459d-ca77-44bc-aeea-44114814c279","originDimensionSpacePoint":{"language":"en_UK"},"affectedDimensionSpacePoints":[{"language":"en_UK"}],"propertyValues":{"title":{"value":"Home","type":"string"},"uriPathSegment":{"value":"home","type":"string"},"image":{"value":{"__flow_object_type":"Neos\\Media\\Domain\\Model\\ImageVariant","__identifier":"50cd4a3e-1cc3-4bbb-b2ab-919abb4011f1"},"type":"Neos\\Media\\Domain\\Model\\ImageInterface"}}},"metadata":[]} {"identifier":"c30068ba-258b-4393-b0de-aaf37d43fe69","type":"NodeGeneralizationVariantWasCreated","payload":{"contentStreamId":"7ebcc393-4120-4d29-a0d8-8bc708ecb3f8","nodeAggregateId":"f676459d-ca77-44bc-aeea-44114814c279","sourceOrigin":{"language":"en_UK"},"generalizationOrigin":{"language":"en_US"},"generalizationCoverage":[{"language":"en_US"}]},"metadata":[]} diff --git a/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.Test.TwoDimensions/Resources/Private/Content/events.jsonl b/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.Test.TwoDimensions/Resources/Private/Content/events.jsonl index eb5e838523..6892581208 100644 --- a/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.Test.TwoDimensions/Resources/Private/Content/events.jsonl +++ b/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.Test.TwoDimensions/Resources/Private/Content/events.jsonl @@ -1,6 +1,6 @@ {"identifier":"0ebdfc06-3698-4ddb-83f5-109023213b84","type":"ContentStreamWasCreated","payload":{"contentStreamId":"ead48ed5-f915-44bd-8df8-29475c8b145b"},"metadata":[]} {"identifier":"55ea0055-eda8-4077-b3b0-2c2d599a8f27","type":"RootNodeAggregateWithNodeWasCreated","payload":{"contentStreamId":"ead48ed5-f915-44bd-8df8-29475c8b145b","nodeAggregateId":"2fbc3faf-663a-4ef0-b586-7b2c1c7fd342","nodeTypeName":"Neos.Neos:Sites","coveredDimensionSpacePoints":[{"country":"deu","language":"en_US"},{"country":"deu","language":"en_UK"},{"country":"deu","language":"de"},{"country":"deu","language":"fr"},{"country":"deu","language":"nl"},{"country":"deu","language":"lv"},{"country":"aut","language":"en_US"},{"country":"aut","language":"en_UK"},{"country":"aut","language":"de"},{"country":"aut","language":"fr"},{"country":"aut","language":"nl"},{"country":"aut","language":"lv"},{"country":"lux","language":"en_UK"},{"country":"lux","language":"de"},{"country":"dnk","language":"en_UK"},{"country":"dnk","language":"da"}],"nodeAggregateClassification":"root"},"metadata":[]} -{"identifier":"a9fdb629-97ce-4321-bbec-a1dbf27530fd","type":"NodeAggregateWithNodeWasCreated","payload":{"contentStreamId":"ead48ed5-f915-44bd-8df8-29475c8b145b","nodeAggregateId":"f676459d-ca77-44bc-aeea-44114814c279","nodeTypeName":"Neos.TestNodeTypes:Document.Page","originDimensionSpacePoint":{"country":"dnk","language":"da"},"coveredDimensionSpacePoints":[{"country":"dnk","language":"da"}],"parentNodeAggregateId":"2fbc3faf-663a-4ef0-b586-7b2c1c7fd342","nodeName":"neos-test-twodimensions","initialPropertyValues":{"title":{"value":"Home","type":"string"},"uriPathSegment":{"value":"home","type":"string"},"image":{"value":{"__flow_object_type":"Neos\\Media\\Domain\\Model\\ImageVariant","__identifier":"50cd4a3e-1cc3-4bbb-b2ab-919abb4011f1"},"type":"Neos\\Media\\Domain\\Model\\ImageInterface"}},"nodeAggregateClassification":"regular","succeedingNodeAggregateId":null},"metadata":[]} +{"identifier":"a9fdb629-97ce-4321-bbec-a1dbf27530fd","type":"NodeAggregateWithNodeWasCreated","payload":{"contentStreamId":"ead48ed5-f915-44bd-8df8-29475c8b145b","nodeAggregateId":"f676459d-ca77-44bc-aeea-44114814c279","nodeTypeName":"Neos.TestNodeTypes:Document.HomePage","originDimensionSpacePoint":{"country":"dnk","language":"da"},"coveredDimensionSpacePoints":[{"country":"dnk","language":"da"}],"parentNodeAggregateId":"2fbc3faf-663a-4ef0-b586-7b2c1c7fd342","nodeName":"neos-test-twodimensions","initialPropertyValues":{"title":{"value":"Home","type":"string"},"uriPathSegment":{"value":"home","type":"string"},"image":{"value":{"__flow_object_type":"Neos\\Media\\Domain\\Model\\ImageVariant","__identifier":"50cd4a3e-1cc3-4bbb-b2ab-919abb4011f1"},"type":"Neos\\Media\\Domain\\Model\\ImageInterface"}},"nodeAggregateClassification":"regular","succeedingNodeAggregateId":null},"metadata":[]} {"identifier":"06ce4e00-bede-4d76-a6b9-02c646ce933b","type":"NodePeerVariantWasCreated","payload":{"contentStreamId":"ead48ed5-f915-44bd-8df8-29475c8b145b","nodeAggregateId":"f676459d-ca77-44bc-aeea-44114814c279","sourceOrigin":{"country":"dnk","language":"da"},"peerOrigin":{"country":"deu","language":"lv"},"peerCoverage":[{"country":"deu","language":"lv"},{"country":"aut","language":"lv"}]},"metadata":[]} {"identifier":"c8b2be8f-fd74-4ea5-b2f8-35a3876d11a9","type":"NodePropertiesWereSet","payload":{"contentStreamId":"ead48ed5-f915-44bd-8df8-29475c8b145b","nodeAggregateId":"f676459d-ca77-44bc-aeea-44114814c279","originDimensionSpacePoint":{"country":"deu","language":"lv"},"affectedDimensionSpacePoints":[{"country":"deu","language":"lv"},{"country":"aut","language":"lv"}],"propertyValues":{"title":{"value":"M\u0101jas","type":"string"},"uriPathSegment":{"value":"home","type":"string"}}},"metadata":[]} {"identifier":"c2c89695-2e12-41ac-bc4a-9b197b67a6f8","type":"NodePeerVariantWasCreated","payload":{"contentStreamId":"ead48ed5-f915-44bd-8df8-29475c8b145b","nodeAggregateId":"f676459d-ca77-44bc-aeea-44114814c279","sourceOrigin":{"country":"deu","language":"lv"},"peerOrigin":{"country":"deu","language":"en_US"},"peerCoverage":[{"country":"deu","language":"en_US"},{"country":"aut","language":"en_US"},{"country":"deu","language":"en_UK"},{"country":"aut","language":"en_UK"},{"country":"lux","language":"en_UK"}]},"metadata":[]} diff --git a/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.TestNodeTypes/NodeTypes/Document/HomePage.yaml b/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.TestNodeTypes/NodeTypes/Document/HomePage.yaml new file mode 100644 index 0000000000..c0009c69eb --- /dev/null +++ b/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.TestNodeTypes/NodeTypes/Document/HomePage.yaml @@ -0,0 +1,4 @@ +'Neos.TestNodeTypes:Document.HomePage': + superTypes: + 'Neos.Neos:Site': true + 'Neos.TestNodeTypes:Document.Page': true diff --git a/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.TestNodeTypes/Resources/Private/Fusion/Document/Page/HomePage.fusion b/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.TestNodeTypes/Resources/Private/Fusion/Document/Page/HomePage.fusion new file mode 100644 index 0000000000..f55a6eecac --- /dev/null +++ b/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.TestNodeTypes/Resources/Private/Fusion/Document/Page/HomePage.fusion @@ -0,0 +1 @@ +prototype(Neos.TestNodeTypes:Document.HomePage) < prototype(Neos.TestNodeTypes:Document.Page) From 508865c5d86f6f72620117f3f72dbf3405483348 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Fri, 29 Sep 2023 14:38:10 +0200 Subject: [PATCH 06/43] TASK: Adjust to removed NodeTypeFallback --- .../ContentRepository/Service/NodeService.php | 14 ++++++------- .../Service/WorkspaceService.php | 14 ++++++------- Classes/Domain/Model/AbstractChange.php | 14 ++++++------- .../Changes/AbstractStructuralChange.php | 20 +++++++++---------- Classes/Domain/Model/Changes/Property.php | 17 +++++++++++----- .../Model/Feedback/Operations/NodeCreated.php | 14 ++++++------- .../Service/NodePropertyConverterService.php | 19 +++++++++--------- Classes/Fusion/Helper/NodeInfoHelper.php | 16 +++++++-------- Classes/Service/NodePolicyService.php | 14 ++++++------- 9 files changed, 74 insertions(+), 68 deletions(-) diff --git a/Classes/ContentRepository/Service/NodeService.php b/Classes/ContentRepository/Service/NodeService.php index afecaf9cd0..cad0b5c744 100644 --- a/Classes/ContentRepository/Service/NodeService.php +++ b/Classes/ContentRepository/Service/NodeService.php @@ -18,31 +18,31 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; +use Neos\Neos\Utility\NodeTypeWithFallbackProvider; /** * @Flow\Scope("singleton") */ class NodeService { - /** - * @Flow\Inject - * @var ContentRepositoryRegistry - */ - protected $contentRepositoryRegistry; + use NodeTypeWithFallbackProvider; + + #[Flow\Inject] + protected ContentRepositoryRegistry $contentRepositoryRegistry; /** * Helper method to retrieve the closest document for a node */ public function getClosestDocument(Node $node): ?Node { - if ($node->nodeType->isOfType('Neos.Neos:Document')) { + if ($this->getNodeType($node)->isOfType('Neos.Neos:Document')) { return $node; } $subgraph = $this->contentRepositoryRegistry->subgraphForNode($node); while ($node instanceof Node) { - if ($node->nodeType->isOfType('Neos.Neos:Document')) { + if ($this->getNodeType($node)->isOfType('Neos.Neos:Document')) { return $node; } $node = $subgraph->findParentNode($node->nodeAggregateId); diff --git a/Classes/ContentRepository/Service/WorkspaceService.php b/Classes/ContentRepository/Service/WorkspaceService.php index a66162966e..9ae80ff464 100644 --- a/Classes/ContentRepository/Service/WorkspaceService.php +++ b/Classes/ContentRepository/Service/WorkspaceService.php @@ -26,12 +26,18 @@ use Neos\Neos\PendingChangesProjection\ChangeFinder; use Neos\Neos\Service\UserService; use Neos\Neos\Ui\Domain\Model\Feedback\Operations\RemoveNode; +use Neos\Neos\Utility\NodeTypeWithFallbackProvider; /** * @Flow\Scope("singleton") */ class WorkspaceService { + use NodeTypeWithFallbackProvider; + + #[Flow\Inject] + protected ContentRepositoryRegistry $contentRepositoryRegistry; + /** * @Flow\Inject * @var UserService @@ -44,12 +50,6 @@ class WorkspaceService */ protected $domainUserService; - /** - * @Flow\Inject - * @var ContentRepositoryRegistry - */ - protected $contentRepositoryRegistry; - /** * Get all publishable node context paths for a workspace * @@ -207,7 +207,7 @@ private function getClosestDocumentNode(Node $node): ?Node $subgraph = $this->contentRepositoryRegistry->subgraphForNode($node); while ($node instanceof Node) { - if ($node->nodeType->isOfType('Neos.Neos:Document')) { + if ($this->getNodeType($node)->isOfType('Neos.Neos:Document')) { return $node; } $node = $subgraph->findParentNode($node->nodeAggregateId); diff --git a/Classes/Domain/Model/AbstractChange.php b/Classes/Domain/Model/AbstractChange.php index 5761289f45..9edfac63f3 100644 --- a/Classes/Domain/Model/AbstractChange.php +++ b/Classes/Domain/Model/AbstractChange.php @@ -19,11 +19,17 @@ use Neos\Neos\Ui\Domain\Model\Feedback\Operations\NodeCreated; use Neos\Neos\Ui\Domain\Model\Feedback\Operations\ReloadDocument; use Neos\Neos\Ui\Domain\Model\Feedback\Operations\UpdateWorkspaceInfo; +use Neos\Neos\Utility\NodeTypeWithFallbackProvider; abstract class AbstractChange implements ChangeInterface { + use NodeTypeWithFallbackProvider; + protected ?Node $subject; + #[Flow\Inject] + protected ContentRepositoryRegistry $contentRepositoryRegistry; + /** * @Flow\Inject * @var FeedbackCollection @@ -42,12 +48,6 @@ abstract class AbstractChange implements ChangeInterface */ protected $persistenceManager; - /** - * @Flow\Inject - * @var ContentRepositoryRegistry - */ - protected $contentRepositoryRegistry; - public function setSubject(Node $subject): void { $this->subject = $subject; @@ -81,7 +81,7 @@ protected function updateWorkspaceInfo(): void final protected function findClosestDocumentNode(Node $node): ?Node { while ($node instanceof Node) { - if ($node->nodeType->isOfType('Neos.Neos:Document')) { + if ($this->getNodeType($node)->isOfType('Neos.Neos:Document')) { return $node; } $node = $this->findParentNode($node); diff --git a/Classes/Domain/Model/Changes/AbstractStructuralChange.php b/Classes/Domain/Model/Changes/AbstractStructuralChange.php index b1a18ad614..f4eb59d5a1 100644 --- a/Classes/Domain/Model/Changes/AbstractStructuralChange.php +++ b/Classes/Domain/Model/Changes/AbstractStructuralChange.php @@ -26,12 +26,18 @@ use Neos\Neos\Ui\Domain\Model\Feedback\Operations\RenderContentOutOfBand; use Neos\Neos\Ui\Domain\Model\Feedback\Operations\UpdateNodeInfo; use Neos\Neos\Ui\Domain\Model\RenderedNodeDomAddress; +use Neos\Neos\Utility\NodeTypeWithFallbackProvider; /** * A change that performs structural actions like moving or creating nodes */ abstract class AbstractStructuralChange extends AbstractChange { + use NodeTypeWithFallbackProvider; + + #[Flow\Inject] + protected ContentRepositoryRegistry $contentRepositoryRegistry; + /** * The node dom address for the parent node of the created node */ @@ -48,12 +54,6 @@ abstract class AbstractStructuralChange extends AbstractChange */ protected $nodeService; - /** - * @Flow\Inject - * @var ContentRepositoryRegistry - */ - protected $contentRepositoryRegistry; - protected ?Node $cachedSiblingNode = null; /** @@ -146,14 +146,14 @@ protected function finish(Node $node) $this->updateWorkspaceInfo(); - if ($node->nodeType->isOfType('Neos.Neos:Content') + if ($this->getNodeType($node)->isOfType('Neos.Neos:Content') && ($this->getParentDomAddress() || $this->getSiblingDomAddress())) { // we can ONLY render out of band if: // 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($parentNode->subgraphIdentity->contentRepositoryId); - if ($parentNode && $parentNode->nodeType->isOfType('Neos.Neos:ContentCollection') && + 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() && @@ -189,12 +189,12 @@ protected function isNodeTypeAllowedAsChildNode(Node $node, NodeType $nodeType): $subgraph = $this->contentRepositoryRegistry->subgraphForNode($node); if ($node->classification === NodeAggregateClassification::CLASSIFICATION_TETHERED) { $parentNode = $subgraph->findParentNode($node->nodeAggregateId); - return !$parentNode || $parentNode->nodeType->allowsGrandchildNodeType( + return !$parentNode || $this->getNodeType($parentNode)->allowsGrandchildNodeType( $node->nodeName->value, $nodeType ); } else { - return $node->nodeType->allowsChildNodeType($nodeType); + return $this->getNodeType($node)->allowsChildNodeType($nodeType); } } } diff --git a/Classes/Domain/Model/Changes/Property.php b/Classes/Domain/Model/Changes/Property.php index 86985767bd..2afbc0687b 100644 --- a/Classes/Domain/Model/Changes/Property.php +++ b/Classes/Domain/Model/Changes/Property.php @@ -29,12 +29,14 @@ use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateIds; use Neos\ContentRepository\Core\SharedModel\Node\NodeVariantSelectionStrategy; use Neos\ContentRepository\Core\SharedModel\Node\ReferenceName; +use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; use Neos\Neos\Ui\Domain\Model\AbstractChange; use Neos\Neos\Ui\Domain\Model\Feedback\Operations\ReloadContentOutOfBand; use Neos\Neos\Ui\Domain\Model\Feedback\Operations\UpdateNodeInfo; use Neos\Neos\Ui\Domain\Model\RenderedNodeDomAddress; use Neos\Neos\Ui\Domain\Service\NodePropertyConversionService; +use Neos\Neos\Utility\NodeTypeWithFallbackProvider; /** @codingStandardsIgnoreStart */ /** @codingStandardsIgnoreEnd */ @@ -44,6 +46,11 @@ */ class Property extends AbstractChange { + use NodeTypeWithFallbackProvider; + + #[Flow\Inject] + protected ContentRepositoryRegistry $contentRepositoryRegistry; + /** * @Flow\Inject * @var NodePropertyConversionService @@ -147,7 +154,7 @@ public function apply(): void if ($this->canApply() && !is_null($subject) && !is_null($propertyName)) { $contentRepository = $this->contentRepositoryRegistry->get($subject->subgraphIdentity->contentRepositoryId); - $propertyType = $subject->nodeType->getPropertyType($propertyName); + $propertyType = $this->getNodeType($subject)->getPropertyType($propertyName); // Use extra commands for reference handling if ($propertyType === 'reference' || $propertyType === 'references') { @@ -180,7 +187,7 @@ public function apply(): void ); } else { $value = $this->nodePropertyConversionService->convert( - $subject->nodeType, + $this->getNodeType($subject), $propertyName, $this->getValue() ); @@ -273,10 +280,10 @@ public function apply(): void $this->feedbackCollection->add($updateNodeInfo); $reloadIfChangedConfigurationPath = sprintf('properties.%s.ui.reloadIfChanged', $propertyName); - if (!$this->getIsInline() && $node->nodeType->getConfiguration($reloadIfChangedConfigurationPath)) { + if (!$this->getIsInline() && $this->getNodeType($node)->getConfiguration($reloadIfChangedConfigurationPath)) { if ($this->getNodeDomAddress() && $this->getNodeDomAddress()->getFusionPath() && $parentNode - && $parentNode->nodeType->isOfType('Neos.Neos:ContentCollection')) { + && $this->getNodeType($parentNode)->isOfType('Neos.Neos:ContentCollection')) { $reloadContentOutOfBand = new ReloadContentOutOfBand(); $reloadContentOutOfBand->setNode($node); $reloadContentOutOfBand->setNodeDomAddress($this->getNodeDomAddress()); @@ -288,7 +295,7 @@ public function apply(): void $reloadPageIfChangedConfigurationPath = sprintf('properties.%s.ui.reloadPageIfChanged', $propertyName); if (!$this->getIsInline() - && $node->nodeType->getConfiguration($reloadPageIfChangedConfigurationPath)) { + && $this->getNodeType($node)->getConfiguration($reloadPageIfChangedConfigurationPath)) { $this->reloadDocument($node); } } diff --git a/Classes/Domain/Model/Feedback/Operations/NodeCreated.php b/Classes/Domain/Model/Feedback/Operations/NodeCreated.php index bbd8a4bcfd..cf76c19a25 100644 --- a/Classes/Domain/Model/Feedback/Operations/NodeCreated.php +++ b/Classes/Domain/Model/Feedback/Operations/NodeCreated.php @@ -19,20 +19,20 @@ use Neos\Neos\Domain\Service\NodeTypeNameFactory; use Neos\Neos\Ui\Domain\Model\AbstractFeedback; use Neos\Neos\Ui\Domain\Model\FeedbackInterface; +use Neos\Neos\Utility\NodeTypeWithFallbackProvider; class NodeCreated extends AbstractFeedback { + use NodeTypeWithFallbackProvider; + + #[Flow\Inject] + protected ContentRepositoryRegistry $contentRepositoryRegistry; + /** * @var Node */ protected $node; - /** - * @Flow\Inject - * @var ContentRepositoryRegistry - */ - protected $contentRepositoryRegistry; - /** * Set the node */ @@ -97,7 +97,7 @@ public function serializePayload(ControllerContext $controllerContext) return [ 'contextPath' => $nodeAddressFactory->createFromNode($node)->serializeForUri(), 'identifier' => $node->nodeAggregateId->value, - 'isDocument' => $node->nodeType->isOfType(NodeTypeNameFactory::NAME_DOCUMENT) + 'isDocument' => $this->getNodeType($node)->isOfType(NodeTypeNameFactory::NAME_DOCUMENT) ]; } } diff --git a/Classes/Domain/Service/NodePropertyConverterService.php b/Classes/Domain/Service/NodePropertyConverterService.php index 90a71e41dd..ad098a8ad0 100644 --- a/Classes/Domain/Service/NodePropertyConverterService.php +++ b/Classes/Domain/Service/NodePropertyConverterService.php @@ -17,7 +17,6 @@ use Neos\ContentRepository\Core\NodeType\NodeType; use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindReferencesFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; -use Neos\ContentRepository\Core\Projection\ContentGraph\Reference; use Neos\ContentRepository\Core\Projection\ContentGraph\References; use Neos\ContentRepository\Core\Projection\NodeHiddenState\NodeHiddenStateFinder; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; @@ -30,6 +29,7 @@ use Neos\Flow\Property\PropertyMappingConfiguration; use Neos\Flow\Property\PropertyMappingConfigurationInterface; use Neos\Flow\Property\TypeConverterInterface; +use Neos\Neos\Utility\NodeTypeWithFallbackProvider; use Neos\Utility\ObjectAccess; use Neos\Utility\TypeHandling; use Psr\Log\LoggerInterface; @@ -44,6 +44,11 @@ */ class NodePropertyConverterService { + use NodeTypeWithFallbackProvider; + + #[Flow\Inject] + protected ContentRepositoryRegistry $contentRepositoryRegistry; + /** * @Flow\InjectConfiguration(package="Neos.Neos", path="userInterface.inspector.dataTypes") * @var array> @@ -78,12 +83,6 @@ class NodePropertyConverterService */ private $throwableStorage; - /** - * @Flow\Inject - * @var ContentRepositoryRegistry - */ - protected $contentRepositoryRegistry; - /** * @param LoggerInterface $logger */ @@ -119,7 +118,7 @@ public function getProperty(Node $node, $propertyName) $node->nodeAggregateId )->isHidden; } - $propertyType = $node->nodeType->getPropertyType($propertyName); + $propertyType = $this->getNodeType($node)->getPropertyType($propertyName); // We handle "reference" and "references" differently than other properties; // because we need to use another API for querying these references. @@ -160,7 +159,7 @@ public function getProperty(Node $node, $propertyName) } if ($convertedValue === null) { - $convertedValue = $this->getDefaultValueForProperty($node->nodeType, $propertyName); + $convertedValue = $this->getDefaultValueForProperty($this->getNodeType($node), $propertyName); if ($convertedValue !== null) { try { $convertedValue = $this->convertValue($convertedValue, $propertyType); @@ -196,7 +195,7 @@ private function toNodeIdentifierStrings(References $references): array public function getPropertiesArray(Node $node) { $properties = []; - foreach ($node->nodeType->getProperties() as $propertyName => $propertyConfiguration) { + foreach ($this->getNodeType($node)->getProperties() as $propertyName => $propertyConfiguration) { if ($propertyName[0] === '_' && $propertyName[1] === '_') { // skip fully-private properties continue; diff --git a/Classes/Fusion/Helper/NodeInfoHelper.php b/Classes/Fusion/Helper/NodeInfoHelper.php index 5635574cfd..62abda3f3c 100644 --- a/Classes/Fusion/Helper/NodeInfoHelper.php +++ b/Classes/Fusion/Helper/NodeInfoHelper.php @@ -30,12 +30,18 @@ use Neos\Neos\Ui\Domain\Service\NodePropertyConverterService; use Neos\Neos\Ui\Domain\Service\UserLocaleService; use Neos\Neos\Ui\Service\NodePolicyService; +use Neos\Neos\Utility\NodeTypeWithFallbackProvider; /** * @Flow\Scope("singleton") */ class NodeInfoHelper implements ProtectedContextAwareInterface { + use NodeTypeWithFallbackProvider; + + #[Flow\Inject] + protected ContentRepositoryRegistry $contentRepositoryRegistry; + /** * @Flow\Inject * @var NodePolicyService @@ -48,12 +54,6 @@ class NodeInfoHelper implements ProtectedContextAwareInterface */ protected $userLocaleService; - /** - * @Flow\Inject - * @var ContentRepositoryRegistry - */ - protected $contentRepositoryRegistry; - /** * @Flow\Inject * @var EntityToIdentityConverter @@ -209,7 +209,7 @@ public function renderNodeWithPropertiesAndChildrenInformation( protected function getUriInformation(Node $node, ControllerContext $controllerContext): array { $nodeInfo = []; - if (!$node->nodeType->isOfType($this->documentNodeTypeRole)) { + if (!$this->getNodeType($node)->isOfType($this->documentNodeTypeRole)) { return $nodeInfo; } $nodeInfo['uri'] = $this->previewUri($node, $controllerContext); @@ -342,7 +342,7 @@ public function renderNodesWithParents(array $nodes, ControllerContext $controll continue; } - while ($parentNode->nodeType->isOfType($baseNodeTypeOverride)) { + while ($this->getNodeType($parentNode)->isOfType($baseNodeTypeOverride)) { if (array_key_exists($parentNode->nodeAggregateId->value, $renderedNodes)) { $renderedNodes[$parentNode->nodeAggregateId->value]['intermediate'] = true; } else { diff --git a/Classes/Service/NodePolicyService.php b/Classes/Service/NodePolicyService.php index b31c8dc6b4..5f95a48d1d 100644 --- a/Classes/Service/NodePolicyService.php +++ b/Classes/Service/NodePolicyService.php @@ -27,24 +27,24 @@ use Neos\Flow\Security\Authorization\PrivilegeManagerInterface; use Neos\Flow\Security\Policy\PolicyService; use Neos\Neos\Security\Authorization\Privilege\NodeTreePrivilege; +use Neos\Neos\Utility\NodeTypeWithFallbackProvider; /** * @Flow\Scope("singleton") */ class NodePolicyService { + use NodeTypeWithFallbackProvider; + + #[Flow\Inject] + protected ContentRepositoryRegistry $contentRepositoryRegistry; + /** * @Flow\Inject * @var PrivilegeManagerInterface */ protected $privilegeManager; - /** - * @Flow\Inject - * @var ContentRepositoryRegistry - */ - protected $contentRepositoryRegistry; - /** * @Flow\Inject * @var ObjectManagerInterface @@ -183,7 +183,7 @@ public function getDisallowedProperties(Node $node): array ); }; - $disallowedProperties = array_filter(array_keys($node->nodeType->getProperties()), $filter); + $disallowedProperties = array_filter(array_keys($this->getNodeType($node)->getProperties()), $filter); return $disallowedProperties; } } From adc3a9a5d2edf8217652abd06d85a9589f8a75f7 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 10 Oct 2023 15:51:36 +0200 Subject: [PATCH 07/43] TASK: Migrate `Neos.Fusion:Collection` --- .../Private/Fusion/Component/Navigation/Navigation.fusion | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.TestNodeTypes/Resources/Private/Fusion/Component/Navigation/Navigation.fusion b/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.TestNodeTypes/Resources/Private/Fusion/Component/Navigation/Navigation.fusion index 06390ac533..f3a5e5d83f 100644 --- a/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.TestNodeTypes/Resources/Private/Fusion/Component/Navigation/Navigation.fusion +++ b/Tests/IntegrationTests/TestDistribution/DistributionPackages/Neos.TestNodeTypes/Resources/Private/Fusion/Component/Navigation/Navigation.fusion @@ -1,6 +1,6 @@ -prototype(Neos.TestNodeTypes:Navigation) < prototype(Neos.Fusion:Collection) { +prototype(Neos.TestNodeTypes:Navigation) < prototype(Neos.Fusion:Loop) { @process.wrap = afx`` - collection = ${q(site).children('[instanceof Neos.Neos:Document]').get()} + items = ${q(site).children('[instanceof Neos.Neos:Document]').get()} itemName = 'node' itemRenderer = Neos.Fusion:Tag { @process.wrap = afx`
  • {value}
  • ` From a7b8ecc1679706d5b60ad7cb5663ef324f4aad7f Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 10 Oct 2023 16:00:00 +0200 Subject: [PATCH 08/43] TASK: Adjust automated ci to use `Neos.TestNodeTypes:Document.HomePage` --- Tests/IntegrationTests/e2e-docker.sh | 4 ++-- Tests/IntegrationTests/e2e.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Tests/IntegrationTests/e2e-docker.sh b/Tests/IntegrationTests/e2e-docker.sh index ec2895235d..19b8b1c82a 100755 --- a/Tests/IntegrationTests/e2e-docker.sh +++ b/Tests/IntegrationTests/e2e-docker.sh @@ -56,14 +56,14 @@ dc exec -T php bash <<-'BASH' ./flow user:create --username=admin --password=admin --first-name=John --last-name=Doe --roles=Administrator || true ./flow cr:setup --content-repository onedimension - ./flow site:create neos-test-onedimension Neos.Test.OneDimension Neos.TestNodeTypes:Document.Page + ./flow site:create neos-test-onedimension Neos.Test.OneDimension Neos.TestNodeTypes:Document.HomePage ./flow domain:add neos-test-onedimension onedimension.localhost --port 8081 # TODO: Replace with "--assume-yes" flag once "./flow cr:prune" has one printf "y\n" | ./flow cr:prune --content-repository onedimension ./flow cr:import --content-repository onedimension --path ./DistributionPackages/Neos.Test.OneDimension/Resources/Private/Content ./flow cr:setup --content-repository twodimensions - ./flow site:create neos-test-twodimensions Neos.Test.TwoDimensions Neos.TestNodeTypes:Document.Page + ./flow site:create neos-test-twodimensions Neos.Test.TwoDimensions Neos.TestNodeTypes:Document.HomePage ./flow domain:add neos-test-twodimensions twodimensions.localhost --port 8081 # TODO: Replace with "--assume-yes" flag once "./flow cr:prune" has one printf "y\n" | ./flow cr:prune --content-repository twodimensions diff --git a/Tests/IntegrationTests/e2e.sh b/Tests/IntegrationTests/e2e.sh index e1331bcebb..52e251da0f 100755 --- a/Tests/IntegrationTests/e2e.sh +++ b/Tests/IntegrationTests/e2e.sh @@ -9,14 +9,14 @@ fi cd ../../.. ./flow cr:setup --content-repository onedimension -./flow site:create neos-test-onedimension Neos.Test.OneDimension Neos.TestNodeTypes:Document.Page +./flow site:create neos-test-onedimension Neos.Test.OneDimension Neos.TestNodeTypes:Document.HomePage ./flow domain:add neos-test-onedimension onedimension.localhost --port 8081 # TODO: Replace with "--assume-yes" flag once "./flow cr:prune" has one printf "y\n" | ./flow cr:prune --content-repository onedimension ./flow cr:import --content-repository onedimension --path ./DistributionPackages/Neos.Test.OneDimension/Resources/Private/Content ./flow cr:setup --content-repository twodimensions -./flow site:create neos-test-twodimensions Neos.Test.TwoDimensions Neos.TestNodeTypes:Document.Page +./flow site:create neos-test-twodimensions Neos.Test.TwoDimensions Neos.TestNodeTypes:Document.HomePage ./flow domain:add neos-test-twodimensions twodimensions.localhost --port 8081 # TODO: Replace with "--assume-yes" flag once "./flow cr:prune" has one printf "y\n" | ./flow cr:prune --content-repository twodimensions From 10189b73acd18d0d4f01d71e63fda72319dadb47 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 12 Oct 2023 23:11:32 +0200 Subject: [PATCH 09/43] TASK: Remove `NodeService::getClosestDocument` --- .../ContentRepository/Service/NodeService.php | 32 ------------------- .../Feedback/Operations/ReloadDocument.php | 16 ++++++---- 2 files changed, 9 insertions(+), 39 deletions(-) diff --git a/Classes/ContentRepository/Service/NodeService.php b/Classes/ContentRepository/Service/NodeService.php index cad0b5c744..1b0429e80f 100644 --- a/Classes/ContentRepository/Service/NodeService.php +++ b/Classes/ContentRepository/Service/NodeService.php @@ -30,38 +30,6 @@ class NodeService #[Flow\Inject] protected ContentRepositoryRegistry $contentRepositoryRegistry; - /** - * Helper method to retrieve the closest document for a node - */ - public function getClosestDocument(Node $node): ?Node - { - if ($this->getNodeType($node)->isOfType('Neos.Neos:Document')) { - return $node; - } - - $subgraph = $this->contentRepositoryRegistry->subgraphForNode($node); - - while ($node instanceof Node) { - if ($this->getNodeType($node)->isOfType('Neos.Neos:Document')) { - return $node; - } - $node = $subgraph->findParentNode($node->nodeAggregateId); - } - - return null; - } - - /** - * Helper method to check if a given node is a document node. - * - * @param Node $node The node to check - * @return boolean A boolean which indicates if the given node is a document node. - */ - public function isDocument(Node $node): bool - { - return ($this->getClosestDocument($node) === $node); - } - /** * Converts a given context path to a node object */ diff --git a/Classes/Domain/Model/Feedback/Operations/ReloadDocument.php b/Classes/Domain/Model/Feedback/Operations/ReloadDocument.php index 3b0d24cced..039881587c 100644 --- a/Classes/Domain/Model/Feedback/Operations/ReloadDocument.php +++ b/Classes/Domain/Model/Feedback/Operations/ReloadDocument.php @@ -11,10 +11,12 @@ * source code. */ +use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindClosestNodeFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; +use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; use Neos\Flow\Mvc\Controller\ControllerContext; -use Neos\Neos\Ui\ContentRepository\Service\NodeService; +use Neos\Neos\Domain\Service\NodeTypeNameFactory; use Neos\Neos\Ui\Domain\Model\AbstractFeedback; use Neos\Neos\Ui\Domain\Model\FeedbackInterface; use Neos\Neos\Ui\Fusion\Helper\NodeInfoHelper; @@ -23,11 +25,8 @@ class ReloadDocument extends AbstractFeedback { protected ?Node $node; - /** - * @Flow\Inject - * @var NodeService - */ - protected $nodeService; + #[Flow\Inject] + protected ContentRepositoryRegistry $contentRepositoryRegistry; public function getType(): string { @@ -73,7 +72,10 @@ public function serializePayload(ControllerContext $controllerContext): array } $nodeInfoHelper = new NodeInfoHelper(); - if ($documentNode = $this->nodeService->getClosestDocument($this->node)) { + $documentNode = $this->contentRepositoryRegistry->subgraphForNode($this->node) + ->findClosestNode($this->node->nodeAggregateId, FindClosestNodeFilter::create(nodeTypeConstraints: NodeTypeNameFactory::NAME_DOCUMENT)); + + if ($documentNode) { return [ 'uri' => $nodeInfoHelper->previewUri($documentNode, $controllerContext) ]; From 0c85b4a66cc7722745059bacd9f55ab2dd2dff71 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 12 Oct 2023 23:21:30 +0200 Subject: [PATCH 10/43] TASK: Leverage `findClosestNode` for "Neos.Neos:Document" --- .../Service/WorkspaceService.php | 20 ++++--------------- Classes/Domain/Model/AbstractChange.php | 17 ++++------------ Classes/Domain/Model/Changes/Remove.php | 5 ++++- 3 files changed, 12 insertions(+), 30 deletions(-) diff --git a/Classes/ContentRepository/Service/WorkspaceService.php b/Classes/ContentRepository/Service/WorkspaceService.php index 9ae80ff464..8e05538eae 100644 --- a/Classes/ContentRepository/Service/WorkspaceService.php +++ b/Classes/ContentRepository/Service/WorkspaceService.php @@ -14,8 +14,10 @@ use Neos\ContentRepository\Core\ContentRepository; use Neos\ContentRepository\Core\Factory\ContentRepositoryId; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Command\DiscardIndividualNodesFromWorkspace; +use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindClosestNodeFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\Workspace\Workspace; +use Neos\Neos\Domain\Service\NodeTypeNameFactory; use Neos\Neos\FrontendRouting\NodeAddress; use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; @@ -97,7 +99,7 @@ public function getPublishableNodeInfo(WorkspaceName $workspaceName, ContentRepo $node = $subgraph->findNodeById($change->nodeAggregateId); if ($node instanceof Node) { - $documentNode = $this->getClosestDocumentNode($node); + $documentNode = $subgraph->findClosestNode($node->nodeAggregateId, FindClosestNodeFilter::create(nodeTypeConstraints: NodeTypeNameFactory::NAME_DOCUMENT)); if ($documentNode instanceof Node) { $contentRepository = $this->contentRepositoryRegistry->get($documentNode->subgraphIdentity->contentRepositoryId); $nodeAddressFactory = NodeAddressFactory::create($contentRepository); @@ -161,7 +163,7 @@ public function predictRemoveNodeFeedbackFromDiscardIndividualNodesFromWorkspace ): array { $workspace = $contentRepository->getWorkspaceFinder()->findOneByName($command->workspaceName); if (is_null($workspace)) { - return Nodes::createEmpty(); + return []; } $changeFinder = $contentRepository->projectionState(ChangeFinder::class); @@ -201,18 +203,4 @@ public function predictRemoveNodeFeedbackFromDiscardIndividualNodesFromWorkspace return $result; } - - private function getClosestDocumentNode(Node $node): ?Node - { - $subgraph = $this->contentRepositoryRegistry->subgraphForNode($node); - - while ($node instanceof Node) { - if ($this->getNodeType($node)->isOfType('Neos.Neos:Document')) { - return $node; - } - $node = $subgraph->findParentNode($node->nodeAggregateId); - } - - return null; - } } diff --git a/Classes/Domain/Model/AbstractChange.php b/Classes/Domain/Model/AbstractChange.php index 9edfac63f3..62c877da2d 100644 --- a/Classes/Domain/Model/AbstractChange.php +++ b/Classes/Domain/Model/AbstractChange.php @@ -11,10 +11,12 @@ * source code. */ +use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindClosestNodeFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; use Neos\Flow\Persistence\PersistenceManagerInterface; +use Neos\Neos\Domain\Service\NodeTypeNameFactory; use Neos\Neos\Service\UserService; use Neos\Neos\Ui\Domain\Model\Feedback\Operations\NodeCreated; use Neos\Neos\Ui\Domain\Model\Feedback\Operations\ReloadDocument; @@ -64,7 +66,8 @@ public function getSubject(): ?Node protected function updateWorkspaceInfo(): void { if (!is_null($this->subject)) { - $documentNode = $this->findClosestDocumentNode($this->subject); + $subgraph = $this->contentRepositoryRegistry->subgraphForNode($this->subject); + $documentNode = $subgraph->findClosestNode($this->subject->nodeAggregateId, FindClosestNodeFilter::create(nodeTypeConstraints: NodeTypeNameFactory::NAME_DOCUMENT)); if (!is_null($documentNode)) { $contentRepository = $this->contentRepositoryRegistry->get($this->subject->subgraphIdentity->contentRepositoryId); $workspace = $contentRepository->getWorkspaceFinder()->findOneByCurrentContentStreamId( @@ -78,18 +81,6 @@ protected function updateWorkspaceInfo(): void } } - final protected function findClosestDocumentNode(Node $node): ?Node - { - while ($node instanceof Node) { - if ($this->getNodeType($node)->isOfType('Neos.Neos:Document')) { - return $node; - } - $node = $this->findParentNode($node); - } - - return null; - } - protected function findParentNode(Node $node): ?Node { return $this->contentRepositoryRegistry->subgraphForNode($node) diff --git a/Classes/Domain/Model/Changes/Remove.php b/Classes/Domain/Model/Changes/Remove.php index f204d69af3..ccf87a5c04 100644 --- a/Classes/Domain/Model/Changes/Remove.php +++ b/Classes/Domain/Model/Changes/Remove.php @@ -13,11 +13,13 @@ */ use Neos\ContentRepository\Core\DimensionSpace\Exception\DimensionSpacePointNotFound; +use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindClosestNodeFilter; use Neos\ContentRepository\Core\SharedModel\Exception\ContentStreamDoesNotExistYet; use Neos\ContentRepository\Core\SharedModel\Node\NodeVariantSelectionStrategy; use Neos\ContentRepository\Core\Feature\NodeRemoval\Command\RemoveNodeAggregate; use Neos\ContentRepository\Core\SharedModel\Exception\NodeAggregatesTypeIsAmbiguous; use Neos\Flow\Annotations as Flow; +use Neos\Neos\Domain\Service\NodeTypeNameFactory; use Neos\Neos\Fusion\Cache\ContentCacheFlusher; use Neos\Neos\Ui\Domain\Model\AbstractChange; use Neos\Neos\Ui\Domain\Model\Feedback\Operations\RemoveNode; @@ -68,7 +70,8 @@ public function apply(): void // otherwise we cannot find the parent nodes anymore. $this->updateWorkspaceInfo(); - $closestDocumentParentNode = $this->findClosestDocumentNode($subject); + $subgraph = $this->contentRepositoryRegistry->subgraphForNode($this->subject); + $closestDocumentParentNode = $subgraph->findClosestNode($this->subject->nodeAggregateId, FindClosestNodeFilter::create(nodeTypeConstraints: NodeTypeNameFactory::NAME_DOCUMENT)); $command = RemoveNodeAggregate::create( $subject->subgraphIdentity->contentStreamId, $subject->nodeAggregateId, From 7a0cde776b5d4fa0ccc5f89f941f095dd84f417f Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 12 Oct 2023 23:24:20 +0200 Subject: [PATCH 11/43] TASK: Rename to `NeosUiNodeService::getNodeFromContextPath` --- .../Service/{NodeService.php => NeosUiNodeService.php} | 10 ++++------ Classes/Controller/BackendServiceController.php | 6 +++--- .../Domain/Model/Changes/AbstractStructuralChange.php | 6 +++--- Classes/Domain/Model/Changes/CopyInto.php | 2 +- Classes/Domain/Model/Changes/MoveInto.php | 2 +- Classes/Domain/Service/NodeTreeBuilder.php | 4 ++-- Classes/TypeConverter/ChangeCollectionConverter.php | 8 ++++---- 7 files changed, 18 insertions(+), 20 deletions(-) rename Classes/ContentRepository/Service/{NodeService.php => NeosUiNodeService.php} (85%) diff --git a/Classes/ContentRepository/Service/NodeService.php b/Classes/ContentRepository/Service/NeosUiNodeService.php similarity index 85% rename from Classes/ContentRepository/Service/NodeService.php rename to Classes/ContentRepository/Service/NeosUiNodeService.php index 1b0429e80f..9ca28403bd 100644 --- a/Classes/ContentRepository/Service/NodeService.php +++ b/Classes/ContentRepository/Service/NeosUiNodeService.php @@ -21,22 +21,20 @@ use Neos\Neos\Utility\NodeTypeWithFallbackProvider; /** + * @internal * @Flow\Scope("singleton") */ -class NodeService +class NeosUiNodeService { use NodeTypeWithFallbackProvider; #[Flow\Inject] protected ContentRepositoryRegistry $contentRepositoryRegistry; - /** - * Converts a given context path to a node object - */ - public function getNodeFromContextPath(string $contextPath, ContentRepositoryId $contentRepositoryId): ?Node + public function findNodeBySerializedNodeAddress(string $serializedNodeAddress, ContentRepositoryId $contentRepositoryId): ?Node { $contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId); - $nodeAddress = NodeAddressFactory::create($contentRepository)->createFromUriString($contextPath); + $nodeAddress = NodeAddressFactory::create($contentRepository)->createFromUriString($serializedNodeAddress); $subgraph = $contentRepository->getContentGraph()->getSubgraph( $nodeAddress->contentStreamId, diff --git a/Classes/Controller/BackendServiceController.php b/Classes/Controller/BackendServiceController.php index 7c923fbcec..1f941184eb 100644 --- a/Classes/Controller/BackendServiceController.php +++ b/Classes/Controller/BackendServiceController.php @@ -37,7 +37,7 @@ use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\Neos\FrontendRouting\SiteDetection\SiteDetectionResult; use Neos\Neos\Service\UserService; -use Neos\Neos\Ui\ContentRepository\Service\NodeService; +use Neos\Neos\Ui\ContentRepository\Service\NeosUiNodeService; use Neos\Neos\Ui\ContentRepository\Service\WorkspaceService; use Neos\Neos\Ui\Domain\Model\ChangeCollection; use Neos\Neos\Ui\Domain\Model\Feedback\Messages\Error; @@ -88,7 +88,7 @@ class BackendServiceController extends ActionController /** * @Flow\Inject - * @var NodeService + * @var NeosUiNodeService */ protected $nodeService; @@ -590,7 +590,7 @@ public function flowQueryAction(array $chain): string /** @var array $payload */ $payload = $createContext['payload'] ?? []; $flowQuery = new FlowQuery(array_map( - fn ($envelope) => $this->nodeService->getNodeFromContextPath($envelope['$node'], $contentRepositoryId), + fn ($envelope) => $this->nodeService->findNodeBySerializedNodeAddress($envelope['$node'], $contentRepositoryId), $payload )); diff --git a/Classes/Domain/Model/Changes/AbstractStructuralChange.php b/Classes/Domain/Model/Changes/AbstractStructuralChange.php index f4eb59d5a1..de725b5fe4 100644 --- a/Classes/Domain/Model/Changes/AbstractStructuralChange.php +++ b/Classes/Domain/Model/Changes/AbstractStructuralChange.php @@ -20,7 +20,7 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\Nodes; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Flow\Annotations as Flow; -use Neos\Neos\Ui\ContentRepository\Service\NodeService; +use Neos\Neos\Ui\ContentRepository\Service\NeosUiNodeService; use Neos\Neos\Ui\Domain\Model\AbstractChange; use Neos\Neos\Ui\Domain\Model\Feedback\Operations\ReloadDocument; use Neos\Neos\Ui\Domain\Model\Feedback\Operations\RenderContentOutOfBand; @@ -50,7 +50,7 @@ abstract class AbstractStructuralChange extends AbstractChange /** * @Flow\Inject - * @var NodeService + * @var NeosUiNodeService */ protected $nodeService; @@ -111,7 +111,7 @@ public function getSiblingNode(): ?Node } if ($this->cachedSiblingNode === null) { - $this->cachedSiblingNode = $this->nodeService->getNodeFromContextPath( + $this->cachedSiblingNode = $this->nodeService->findNodeBySerializedNodeAddress( $this->siblingDomAddress->getContextPath(), $this->getSubject()->subgraphIdentity->contentRepositoryId ); diff --git a/Classes/Domain/Model/Changes/CopyInto.php b/Classes/Domain/Model/Changes/CopyInto.php index 5b2c3463f6..56c4e55d5d 100644 --- a/Classes/Domain/Model/Changes/CopyInto.php +++ b/Classes/Domain/Model/Changes/CopyInto.php @@ -32,7 +32,7 @@ public function getParentNode(): ?Node { if (!isset($this->cachedParentNode)) { $this->cachedParentNode = $this->parentContextPath - ? $this->nodeService->getNodeFromContextPath($this->parentContextPath, $this->getSubject()->subgraphIdentity->contentRepositoryId) + ? $this->nodeService->findNodeBySerializedNodeAddress($this->parentContextPath, $this->getSubject()->subgraphIdentity->contentRepositoryId) : null; } diff --git a/Classes/Domain/Model/Changes/MoveInto.php b/Classes/Domain/Model/Changes/MoveInto.php index ebccb70c9e..2018a8f1c1 100644 --- a/Classes/Domain/Model/Changes/MoveInto.php +++ b/Classes/Domain/Model/Changes/MoveInto.php @@ -33,7 +33,7 @@ public function getParentNode(): ?Node return null; } - return $this->nodeService->getNodeFromContextPath( + return $this->nodeService->findNodeBySerializedNodeAddress( $this->parentContextPath, $this->getSubject()->subgraphIdentity->contentRepositoryId ); diff --git a/Classes/Domain/Service/NodeTreeBuilder.php b/Classes/Domain/Service/NodeTreeBuilder.php index acab3f73e5..3fb6cc5dc5 100644 --- a/Classes/Domain/Service/NodeTreeBuilder.php +++ b/Classes/Domain/Service/NodeTreeBuilder.php @@ -17,7 +17,7 @@ use Neos\Flow\Annotations as Flow; use Neos\Flow\Mvc\Controller\ControllerContext; use Neos\Neos\Service\LinkingService; -use Neos\Neos\Ui\ContentRepository\Service\NodeService; +use Neos\Neos\Ui\ContentRepository\Service\NeosUiNodeService; class NodeTreeBuilder { @@ -58,7 +58,7 @@ class NodeTreeBuilder /** * @Flow\Inject - * @var NodeService + * @var NeosUiNodeService */ protected $nodeService; diff --git a/Classes/TypeConverter/ChangeCollectionConverter.php b/Classes/TypeConverter/ChangeCollectionConverter.php index 51e5fd43af..f6ac74214b 100644 --- a/Classes/TypeConverter/ChangeCollectionConverter.php +++ b/Classes/TypeConverter/ChangeCollectionConverter.php @@ -20,7 +20,7 @@ use Neos\Flow\Property\PropertyMappingConfigurationInterface; use Neos\Flow\Property\TypeConverter\AbstractTypeConverter; use Neos\Flow\Reflection\ReflectionService; -use Neos\Neos\Ui\ContentRepository\Service\NodeService; +use Neos\Neos\Ui\ContentRepository\Service\NeosUiNodeService; use Neos\Neos\Ui\Domain\Model\ChangeCollection; use Neos\Neos\Ui\Domain\Model\ChangeInterface; use Neos\Neos\Ui\Domain\Model\Changes\Property; @@ -76,7 +76,7 @@ class ChangeCollectionConverter /** * @Flow\Inject - * @var NodeService + * @var NeosUiNodeService */ protected $nodeService; @@ -141,7 +141,7 @@ protected function convertChangeData(array $changeData, ContentRepositoryId $con $subjectContextPath = $changeData['subject']; - $subject = $this->nodeService->getNodeFromContextPath($subjectContextPath, $contentRepositoryId); + $subject = $this->nodeService->findNodeBySerializedNodeAddress($subjectContextPath, $contentRepositoryId); if (is_null($subject)) { throw new \RuntimeException('Could not find node for subject "' . $subjectContextPath . '"', 1645657340); } @@ -150,7 +150,7 @@ protected function convertChangeData(array $changeData, ContentRepositoryId $con if (isset($changeData['reference']) && method_exists($changeClassInstance, 'setReference')) { $referenceContextPath = $changeData['reference']; - $reference = $this->nodeService->getNodeFromContextPath($referenceContextPath, $contentRepositoryId); + $reference = $this->nodeService->findNodeBySerializedNodeAddress($referenceContextPath, $contentRepositoryId); $changeClassInstance->setReference($reference); } From 369d27ab664d985b4f352eaabdc3b993719faa9c Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 12 Oct 2023 23:54:46 +0200 Subject: [PATCH 12/43] TASK: Use `NodeTypeNameFactory::forSites()` --- Classes/Controller/BackendController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Classes/Controller/BackendController.php b/Classes/Controller/BackendController.php index 72b1c2a3ea..4878424ad0 100644 --- a/Classes/Controller/BackendController.php +++ b/Classes/Controller/BackendController.php @@ -26,6 +26,7 @@ use Neos\Neos\Controller\Backend\MenuHelper; use Neos\Neos\Domain\Repository\DomainRepository; use Neos\Neos\Domain\Repository\SiteRepository; +use Neos\Neos\Domain\Service\NodeTypeNameFactory; use Neos\Neos\Domain\Service\WorkspaceNameBuilder; use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\Neos\FrontendRouting\SiteDetection\SiteDetectionResult; @@ -170,7 +171,7 @@ public function indexAction(string $node = null) // to call the contentGraph here directly. $rootNodeAggregate = $contentRepository->getContentGraph()->findRootNodeAggregateByType( $workspace->currentContentStreamId, - NodeTypeName::fromString('Neos.Neos:Sites') + NodeTypeNameFactory::forSites() ); $rootNode = $rootNodeAggregate->getNodeByCoveredDimensionSpacePoint($defaultDimensionSpacePoint); From 3d55e7c76ed8780b20fdd1fbcb7d15e31185a4ae Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 12 Oct 2023 23:56:54 +0200 Subject: [PATCH 13/43] TASK: Remove unused `NodeTreeBuilder` --- .../Controller/BackendServiceController.php | 12 - Classes/Domain/Service/NodeTreeBuilder.php | 225 ------------------ 2 files changed, 237 deletions(-) delete mode 100644 Classes/Domain/Service/NodeTreeBuilder.php diff --git a/Classes/Controller/BackendServiceController.php b/Classes/Controller/BackendServiceController.php index 7c923fbcec..206e8e8923 100644 --- a/Classes/Controller/BackendServiceController.php +++ b/Classes/Controller/BackendServiceController.php @@ -47,7 +47,6 @@ use Neos\Neos\Ui\Domain\Model\Feedback\Operations\ReloadDocument; use Neos\Neos\Ui\Domain\Model\Feedback\Operations\UpdateWorkspaceInfo; use Neos\Neos\Ui\Domain\Model\FeedbackCollection; -use Neos\Neos\Ui\Domain\Service\NodeTreeBuilder; use Neos\Neos\Ui\Fusion\Helper\NodeInfoHelper; use Neos\Neos\Ui\Fusion\Helper\WorkspaceHelper; use Neos\Neos\Ui\Service\NodeClipboard; @@ -484,17 +483,6 @@ public function initializeLoadTreeAction(): void $this->arguments['nodeTreeArguments']->getPropertyMappingConfiguration()->allowAllProperties(); } - /** - * Load the nodetree - */ - public function loadTreeAction(NodeTreeBuilder $nodeTreeArguments, bool $includeRoot = false): void - { - $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; - - $nodeTreeArguments->setControllerContext($this->controllerContext); - $this->view->assign('value', $nodeTreeArguments->build($contentRepositoryId, $includeRoot)); - } - /** * @throws \Neos\Flow\Mvc\Exception\NoSuchArgumentException */ diff --git a/Classes/Domain/Service/NodeTreeBuilder.php b/Classes/Domain/Service/NodeTreeBuilder.php deleted file mode 100644 index acab3f73e5..0000000000 --- a/Classes/Domain/Service/NodeTreeBuilder.php +++ /dev/null @@ -1,225 +0,0 @@ -rootContextPath = $rootContextPath; - } - - /** - * Get the root node - * - * @return Node - */ - private function getRoot() - { - if (!$this->root) { - $this->root = $this->active->getContext()->getCurrentSiteNode(); - } - - return $this->root; - } - - /** - * Set the active node - * - * @param string $activeContextPath - * @return void - */ - public function setActive($activeContextPath) - { - $this->activeContextPath = $activeContextPath; - } - - /** - * Set the node type filter - * - * @param string $nodeTypeFilter - * @return void - */ - public function setNodeTypeFilter($nodeTypeFilter) - { - $this->nodeTypeFilter = $nodeTypeFilter; - } - - /** - * Set the search term filter - * - * @param string $searchTermFilter - * @return void - */ - public function setSearchTermFilter($searchTermFilter) - { - $this->searchTermFilter = $searchTermFilter; - } - - /** - * Set the depth - * - * @param integer $depth - */ - public function setDepth($depth) - { - $this->depth = $depth; - } - - /** - * Set the controller context - * - * @param ControllerContext $controllerContext - * @return void - */ - public function setControllerContext(ControllerContext $controllerContext) - { - $this->controllerContext = $controllerContext; - } - - /** - * Build a json serializable tree structure containing node information - * - * @param bool $includeRoot - * @param null $root - * @param null $depth - * @return array - */ - public function build(ContentRepositoryId $contentRepositoryId, $includeRoot = false, $root = null, $depth = null) - { - $root = $root === null ? $this->getRoot() : $root; - $depth = $depth === null ? $this->depth : $depth; - - $result = []; - - /** @var Node $childNode */ - foreach ($root->getChildNodes($this->nodeTypeFilter) as $childNode) { - $hasChildNodes = $childNode->hasChildNodes($this->nodeTypeFilter); - $shouldLoadChildNodes = $hasChildNodes && ($depth > 1 || $this->isInRootLine($this->active, $childNode)); - - $result[$childNode->getName()] = [ - 'label' => $childNode->getNodeType()->isOfType('Neos.Neos:Document') ? - $childNode->getProperty('title') : $childNode->getLabel(), - 'contextPath' => $childNode->getContextPath(), - 'nodeType' => $childNode->getNodeType()->getName(), - 'hasChildren' => $hasChildNodes, - 'isActive' => $this->active && ($childNode->getPath() === $this->active->getPath()), - 'isFocused' => $this->active && ($childNode->getPath() === $this->active->getPath()), - 'isCollapsed' => !$shouldLoadChildNodes, - 'isCollapsable' => $hasChildNodes - ]; - - if ($shouldLoadChildNodes) { - $result[$childNode->getName()]['children'] = - $this->build(false, $childNode, $depth - 1); - } - - if ($childNode->getNodeType()->isOfType('Neos.Neos:Document')) { - $result[$childNode->getName()]['href'] = $this->linkingService->createNodeUri( - /* $controllerContext */ - $this->controllerContext, - /* $node */ - $childNode, - /* $baseNode */ - null, - /* $format */ - null, - /* $absolute */ - true - ); - } - } - - if ($includeRoot) { - return [ - $root->getName() => [ - 'label' => $root->getNodeType()->isOfType('Neos.Neos:Document') ? - $root->getProperty('title') : $root->getLabel(), - 'icon' => 'globe', - 'contextPath' => $root->getContextPath(), - 'nodeType' => $root->getNodeType()->getName(), - 'hasChildren' => count($result), - 'isCollapsed' => false, - 'isActive' => $this->active && ($root->getPath() === $this->active->getPath()), - 'isFocused' => $this->active && ($root->getPath() === $this->active->getPath()), - 'children' => $result - ] - ]; - } - - return $result; - } - - protected function isInRootLine(Node $haystack = null, Node $needle) - { - if ($haystack === null) { - return false; - } - - return mb_strrpos($haystack->getPath(), $needle->getPath(), null, 'UTF-8') === 0; - } -} From fd8f7223a1597eee5331610afc38f7994f78698b Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Fri, 13 Oct 2023 09:48:49 +0200 Subject: [PATCH 14/43] TASK: Completely prune "Load Tree" action --- Classes/Controller/BackendServiceController.php | 5 ----- Configuration/Routes.Service.yaml | 8 -------- Resources/Private/Fusion/Backend/Root.fusion | 3 --- packages/neos-ui-backend-connector/src/Endpoints/index.ts | 1 - 4 files changed, 17 deletions(-) diff --git a/Classes/Controller/BackendServiceController.php b/Classes/Controller/BackendServiceController.php index 206e8e8923..fccf423f8f 100644 --- a/Classes/Controller/BackendServiceController.php +++ b/Classes/Controller/BackendServiceController.php @@ -478,11 +478,6 @@ public function getWorkspaceInfoAction(): void $this->view->assign('value', $personalWorkspaceInfo); } - public function initializeLoadTreeAction(): void - { - $this->arguments['nodeTreeArguments']->getPropertyMappingConfiguration()->allowAllProperties(); - } - /** * @throws \Neos\Flow\Mvc\Exception\NoSuchArgumentException */ diff --git a/Configuration/Routes.Service.yaml b/Configuration/Routes.Service.yaml index e69d3f0ef9..a4ad58b2e8 100644 --- a/Configuration/Routes.Service.yaml +++ b/Configuration/Routes.Service.yaml @@ -54,14 +54,6 @@ '@action': 'clearClipboard' httpMethods: ['POST'] -- - name: 'Load Tree' - uriPattern: 'load-tree' - defaults: - '@controller': 'BackendService' - '@action': 'loadTree' - httpMethods: ['POST'] - - name: 'FlowQuery' uriPattern: 'flow-query' diff --git a/Resources/Private/Fusion/Backend/Root.fusion b/Resources/Private/Fusion/Backend/Root.fusion index 9018674065..af6e00a74b 100644 --- a/Resources/Private/Fusion/Backend/Root.fusion +++ b/Resources/Private/Fusion/Backend/Root.fusion @@ -125,9 +125,6 @@ backend = Neos.Fusion:Template { clearClipboard = Neos.Fusion:UriBuilder { action = 'clearClipboard' } - loadTree = Neos.Fusion:UriBuilder { - action = 'loadTree' - } flowQuery = Neos.Fusion:UriBuilder { action = 'flowQuery' } diff --git a/packages/neos-ui-backend-connector/src/Endpoints/index.ts b/packages/neos-ui-backend-connector/src/Endpoints/index.ts index 042bb7d60c..56f9075e0c 100644 --- a/packages/neos-ui-backend-connector/src/Endpoints/index.ts +++ b/packages/neos-ui-backend-connector/src/Endpoints/index.ts @@ -15,7 +15,6 @@ export interface Routes { copyNodes: string; cutNodes: string; clearClipboard: string; - loadTree: string; flowQuery: string; generateUriPathSegment: string; getWorkspaceInfo: string; From a7aaa430f9a095846b06212b28f7d4907fcbebf7 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 17 Oct 2023 00:09:21 +0200 Subject: [PATCH 15/43] TASK: Adjust to changes in `NodeType` Adjusts to changes to fix task neos/neos-development-collection#4515 --- .../Changes/AbstractStructuralChange.php | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Classes/Domain/Model/Changes/AbstractStructuralChange.php b/Classes/Domain/Model/Changes/AbstractStructuralChange.php index de725b5fe4..cf44178df0 100644 --- a/Classes/Domain/Model/Changes/AbstractStructuralChange.php +++ b/Classes/Domain/Model/Changes/AbstractStructuralChange.php @@ -186,15 +186,18 @@ protected function findChildNodes(Node $node): Nodes protected function isNodeTypeAllowedAsChildNode(Node $node, NodeType $nodeType): bool { - $subgraph = $this->contentRepositoryRegistry->subgraphForNode($node); - if ($node->classification === NodeAggregateClassification::CLASSIFICATION_TETHERED) { - $parentNode = $subgraph->findParentNode($node->nodeAggregateId); - return !$parentNode || $this->getNodeType($parentNode)->allowsGrandchildNodeType( - $node->nodeName->value, - $nodeType - ); - } else { + if ($node->classification !== NodeAggregateClassification::CLASSIFICATION_TETHERED) { return $this->getNodeType($node)->allowsChildNodeType($nodeType); } + + $subgraph = $this->contentRepositoryRegistry->subgraphForNode($node); + $parentNode = $subgraph->findParentNode($node->nodeAggregateId); + $nodeTypeManager = $this->contentRepositoryRegistry->get($node->subgraphIdentity->contentRepositoryId)->getNodeTypeManager(); + + return !$parentNode || $nodeTypeManager->isNodeTypeAllowedAsChildToTetheredNode( + $this->getNodeType($parentNode), + $node->nodeName, + $nodeType + ); } } From 6395dc2d41f370a456ebf747b6b631d6f1691ea8 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 19 Oct 2023 11:51:32 +0200 Subject: [PATCH 16/43] TASK: Remove NodePolicyService --- .../Controller/BackendServiceController.php | 16 +- Classes/Service/NodePolicyService.php | 189 ------------------ 2 files changed, 14 insertions(+), 191 deletions(-) delete mode 100644 Classes/Service/NodePolicyService.php diff --git a/Classes/Controller/BackendServiceController.php b/Classes/Controller/BackendServiceController.php index f77a2ecec1..c3c18a9d90 100644 --- a/Classes/Controller/BackendServiceController.php +++ b/Classes/Controller/BackendServiceController.php @@ -513,7 +513,13 @@ public function getAdditionalNodeMetadataAction(array $nodes): void }, $node->getOtherNodeVariants())));*/ if (!is_null($node)) { $result[$nodeAddress->serializeForUri()] = [ - 'policy' => $this->nodePolicyService->getNodePolicyInformation($node), + // todo reimplement nodePolicyService + 'policy' => [ + 'disallowedNodeTypes' => [], + 'canRemove' => true, + 'canEdit' => true, + 'disallowedProperties' => [] + ] //'dimensions' => $this->getCurrentDimensionPresetIdentifiersForNode($node), //'otherNodeVariants' => $otherNodeVariants ]; @@ -549,7 +555,13 @@ public function getPolicyInformationAction(array $nodes): void $node = $subgraph->findNodeById($nodeAddress->nodeAggregateId); if (!is_null($node)) { $result[$nodeAddress->serializeForUri()] = [ - 'policy' => $this->nodePolicyService->getNodePolicyInformation($node) + // todo reimplement nodePolicyService + 'policy' => [ + 'disallowedNodeTypes' => [], + 'canRemove' => true, + 'canEdit' => true, + 'disallowedProperties' => [] + ] ]; } } diff --git a/Classes/Service/NodePolicyService.php b/Classes/Service/NodePolicyService.php deleted file mode 100644 index 5f95a48d1d..0000000000 --- a/Classes/Service/NodePolicyService.php +++ /dev/null @@ -1,189 +0,0 @@ - the key is a Privilege class name; - * the value is "true" if privileges are configured for this class name. - * @Flow\CompileStatic - */ - public static function getUsedPrivilegeClassNames(ObjectManagerInterface $objectManager): array - { - /** @var PolicyService $policyService */ - $policyService = $objectManager->get(PolicyService::class); - $usedPrivilegeClassNames = []; - foreach ($policyService->getPrivilegeTargets() as $privilegeTarget) { - $usedPrivilegeClassNames[$privilegeTarget->getPrivilegeClassName()] = true; - foreach (class_parents($privilegeTarget->getPrivilegeClassName()) ?: [] as $parentPrivilege) { - if (is_a($parentPrivilege, PrivilegeInterface::class)) { - /** @var string $parentPrivilege */ - $usedPrivilegeClassNames[$parentPrivilege] = true; - } - } - } - - return $usedPrivilegeClassNames; - } - - /** - * @return array - */ - public function getNodePolicyInformation(Node $node): array - { - return [ - 'disallowedNodeTypes' => $this->getDisallowedNodeTypes($node), - 'canRemove' => $this->canRemoveNode($node), - 'canEdit' => $this->canEditNode($node), - 'disallowedProperties' => $this->getDisallowedProperties($node) - ]; - } - - /** - * @param Node $node - * @return bool - */ - public function isNodeTreePrivilegeGranted(Node $node): bool - { - if (!isset(self::getUsedPrivilegeClassNames($this->objectManager)[NodeTreePrivilege::class])) { - return true; - } - - return $this->privilegeManager->isGranted( - NodeTreePrivilege::class, - new NodePrivilegeSubject($node) - ); - } - - /** - * @param Node $node - * @return array - */ - public function getDisallowedNodeTypes(Node $node): array - { - $disallowedNodeTypes = []; - - if (!isset(self::getUsedPrivilegeClassNames($this->objectManager)[CreateNodePrivilege::class])) { - return $disallowedNodeTypes; - } - - $filter = function ($nodeType) use ($node) { - return !$this->privilegeManager->isGranted( - CreateNodePrivilege::class, - new CreateNodePrivilegeSubject($node, $nodeType) - ); - }; - - $contentRepository = $this->contentRepositoryRegistry->get($node->subgraphIdentity->contentRepositoryId); - $disallowedNodeTypeObjects = array_filter($contentRepository->getNodeTypeManager()->getNodeTypes(), $filter); - - $mapper = function ($nodeType) { - return $nodeType->getName(); - }; - - return array_map($mapper, $disallowedNodeTypeObjects); - } - - /** - * @param Node $node - * @return bool - */ - public function canRemoveNode(Node $node): bool - { - $canRemove = true; - if (isset(self::getUsedPrivilegeClassNames($this->objectManager)[RemoveNodePrivilege::class])) { - $canRemove = $this->privilegeManager->isGranted( - RemoveNodePrivilege::class, - new NodePrivilegeSubject($node) - ); - } - - return $canRemove; - } - - /** - * @param Node $node - * @return bool - */ - public function canEditNode(Node $node): bool - { - $canEdit = true; - if (isset(self::getUsedPrivilegeClassNames($this->objectManager)[EditNodePrivilege::class])) { - $canEdit = $this->privilegeManager->isGranted(EditNodePrivilege::class, new NodePrivilegeSubject($node)); - } - - return $canEdit; - } - - /** - * @param Node $node - * @return array - */ - public function getDisallowedProperties(Node $node): array - { - $disallowedProperties = []; - - if (!isset(self::getUsedPrivilegeClassNames($this->objectManager)[EditNodePropertyPrivilege::class])) { - return $disallowedProperties; - } - - $filter = function ($propertyName) use ($node) { - return !$this->privilegeManager->isGranted( - EditNodePropertyPrivilege::class, - new PropertyAwareNodePrivilegeSubject($node, null, $propertyName) - ); - }; - - $disallowedProperties = array_filter(array_keys($this->getNodeType($node)->getProperties()), $filter); - return $disallowedProperties; - } -} From 3642373031bf8c947521bc5537889723962c1482 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 19 Oct 2023 11:57:09 +0200 Subject: [PATCH 17/43] TASK: Introduce phpstan level 2 --- .../Controller/BackendServiceController.php | 15 ------------- .../Domain/Model/Changes/AbstractCreate.php | 2 +- Classes/Domain/Model/Changes/Property.php | 1 - Classes/Domain/Model/Changes/Remove.php | 1 - .../NeosUiDefaultNodesOperation.php | 3 +-- .../ExceptionHandler/PageExceptionHandler.php | 3 +-- ...ontentDimensionsHelperInternalsFactory.php | 3 ++- Classes/Fusion/Helper/NodeInfoHelper.php | 21 ------------------- .../ChangeCollectionConverter.php | 9 -------- phpstan.neon | 4 ++++ 10 files changed, 9 insertions(+), 53 deletions(-) create mode 100644 phpstan.neon diff --git a/Classes/Controller/BackendServiceController.php b/Classes/Controller/BackendServiceController.php index c3c18a9d90..32f16f0a10 100644 --- a/Classes/Controller/BackendServiceController.php +++ b/Classes/Controller/BackendServiceController.php @@ -50,7 +50,6 @@ use Neos\Neos\Ui\Fusion\Helper\NodeInfoHelper; use Neos\Neos\Ui\Fusion\Helper\WorkspaceHelper; use Neos\Neos\Ui\Service\NodeClipboard; -use Neos\Neos\Ui\Service\NodePolicyService; use Neos\Neos\Ui\Service\PublishingService; use Neos\Neos\Ui\TypeConverter\ChangeCollectionConverter; use Neos\Neos\Utility\NodeUriPathSegmentGenerator; @@ -103,12 +102,6 @@ class BackendServiceController extends ActionController */ protected $userService; - /** - * @Flow\Inject - * @var NodePolicyService - */ - protected $nodePolicyService; - /** * @Flow\Inject * @var ChangeCollectionConverter @@ -158,7 +151,6 @@ protected function initializeController(ActionRequest $request, ActionResponse $ /** * Apply a set of changes to the system */ - /** @phpstan-ignore-next-line */ public function changeAction(array $changes): void { $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; @@ -210,7 +202,6 @@ public function publishAllAction(): void * * @param array $nodeContextPaths */ - /** @phpstan-ignore-next-line */ public function publishAction(array $nodeContextPaths, string $targetWorkspaceName): void { $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; @@ -269,7 +260,6 @@ public function publishAction(array $nodeContextPaths, string $targetWorkspaceNa * * @param array $nodeContextPaths */ - /** @phpstan-ignore-next-line */ public function discardAction(array $nodeContextPaths): void { $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; @@ -422,7 +412,6 @@ public function changeBaseWorkspaceAction(string $targetWorkspaceName, string $d * @throws \Neos\Flow\Property\Exception * @throws \Neos\Flow\Security\Exception */ - /** @phpstan-ignore-next-line */ public function copyNodesAction(array $nodes): void { $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; @@ -454,7 +443,6 @@ public function clearClipboardAction() * @throws \Neos\Flow\Property\Exception * @throws \Neos\Flow\Security\Exception */ - /** @phpstan-ignore-next-line */ public function cutNodesAction(array $nodes): void { $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; @@ -490,7 +478,6 @@ public function initializeGetAdditionalNodeMetadataAction(): void /** * Fetches all the node information that can be lazy-loaded */ - /** @phpstan-ignore-next-line */ public function getAdditionalNodeMetadataAction(array $nodes): void { $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; @@ -574,7 +561,6 @@ public function getPolicyInformationAction(array $nodes): void * * @param array $chain */ - /** @phpstan-ignore-next-line */ public function flowQueryAction(array $chain): string { $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; @@ -590,7 +576,6 @@ public function flowQueryAction(array $chain): string )); foreach ($chain as $operation) { - // @phpstan-ignore-next-line $flowQuery = call_user_func_array([$flowQuery, $operation['type']], $operation['payload']); } diff --git a/Classes/Domain/Model/Changes/AbstractCreate.php b/Classes/Domain/Model/Changes/AbstractCreate.php index 86aca9dc6a..6ebae28193 100644 --- a/Classes/Domain/Model/Changes/AbstractCreate.php +++ b/Classes/Domain/Model/Changes/AbstractCreate.php @@ -87,7 +87,7 @@ public function getName(): ?string * @param Node $parentNode * @param NodeAggregateId|null $succeedingSiblingNodeAggregateId * @return Node - * @throws InvalidNodeCreationHandlerException|NodeNameIsAlreadyOccupied|NodeException + * @throws InvalidNodeCreationHandlerException|NodeNameIsAlreadyOccupied */ protected function createNode( Node $parentNode, diff --git a/Classes/Domain/Model/Changes/Property.php b/Classes/Domain/Model/Changes/Property.php index 2afbc0687b..6401e3bb28 100644 --- a/Classes/Domain/Model/Changes/Property.php +++ b/Classes/Domain/Model/Changes/Property.php @@ -142,7 +142,6 @@ public function canApply(): bool /** * Applies this change * - * @throws \Neos\ContentRepository\Exception\NodeException * @throws ContentStreamDoesNotExistYet * @throws NodeAggregatesTypeIsAmbiguous * @throws DimensionSpacePointNotFound diff --git a/Classes/Domain/Model/Changes/Remove.php b/Classes/Domain/Model/Changes/Remove.php index ccf87a5c04..e1e9063013 100644 --- a/Classes/Domain/Model/Changes/Remove.php +++ b/Classes/Domain/Model/Changes/Remove.php @@ -52,7 +52,6 @@ public function canApply(): bool * @throws NodeAggregatesTypeIsAmbiguous * @throws ContentStreamDoesNotExistYet * @throws DimensionSpacePointNotFound - * @throws \Neos\ContentRepository\Exception\NodeException */ public function apply(): void { diff --git a/Classes/FlowQueryOperations/NeosUiDefaultNodesOperation.php b/Classes/FlowQueryOperations/NeosUiDefaultNodesOperation.php index 4d80cd82b4..4a2da32809 100644 --- a/Classes/FlowQueryOperations/NeosUiDefaultNodesOperation.php +++ b/Classes/FlowQueryOperations/NeosUiDefaultNodesOperation.php @@ -101,8 +101,7 @@ public function evaluate(FlowQuery $flowQuery, array $arguments) $toggledNodes, $ancestors, $subgraph, - $nodeAddressFactory, - $contentRepository + $nodeAddressFactory ) { $baseNodeAddress = $nodeAddressFactory->createFromNode($baseNode); diff --git a/Classes/Fusion/ExceptionHandler/PageExceptionHandler.php b/Classes/Fusion/ExceptionHandler/PageExceptionHandler.php index 8fdfb46ed7..0f5da7f79d 100644 --- a/Classes/Fusion/ExceptionHandler/PageExceptionHandler.php +++ b/Classes/Fusion/ExceptionHandler/PageExceptionHandler.php @@ -12,7 +12,6 @@ */ use GuzzleHttp\Psr7\Message; -use function GuzzleHttp\Psr7\str; use Neos\Flow\Annotations as Flow; use Neos\Flow\Exception; use Neos\Flow\Mvc\View\ViewInterface; @@ -76,7 +75,7 @@ protected function handle($fusionPath, \Exception $exception, $referenceCode): s /** * Renders an actual HTTP response including the correct status and cache control header. * - * @param \Exception the exception + * @param \Exception $exception the exception * @param string $bodyContent * @return string */ diff --git a/Classes/Fusion/Helper/ContentDimensionsHelperInternalsFactory.php b/Classes/Fusion/Helper/ContentDimensionsHelperInternalsFactory.php index 77993c426e..1bb0c34aae 100644 --- a/Classes/Fusion/Helper/ContentDimensionsHelperInternalsFactory.php +++ b/Classes/Fusion/Helper/ContentDimensionsHelperInternalsFactory.php @@ -18,10 +18,11 @@ /** * @deprecated ugly - we want to get rid of this by adding dimension infos in the Subgraph + * @implements ContentRepositoryServiceFactoryInterface */ class ContentDimensionsHelperInternalsFactory implements ContentRepositoryServiceFactoryInterface { - public function build(ContentRepositoryServiceFactoryDependencies $serviceFactoryDependencies): ContentRepositoryServiceInterface + public function build(ContentRepositoryServiceFactoryDependencies $serviceFactoryDependencies): ContentDimensionsHelperInternals { return new ContentDimensionsHelperInternals($serviceFactoryDependencies->contentDimensionSource); } diff --git a/Classes/Fusion/Helper/NodeInfoHelper.php b/Classes/Fusion/Helper/NodeInfoHelper.php index 62abda3f3c..0f2bd21300 100644 --- a/Classes/Fusion/Helper/NodeInfoHelper.php +++ b/Classes/Fusion/Helper/NodeInfoHelper.php @@ -11,7 +11,6 @@ * source code. */ -use Neos\ContentRepository\Core\Projection\ContentGraph\ContentSubgraphInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\CountAncestorNodesFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindChildNodesFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; @@ -26,10 +25,8 @@ use Neos\Neos\FrontendRouting\NodeAddress; use Neos\Neos\FrontendRouting\NodeAddressFactory; use Neos\Neos\FrontendRouting\NodeUriBuilder; -use Neos\Neos\TypeConverter\EntityToIdentityConverter; use Neos\Neos\Ui\Domain\Service\NodePropertyConverterService; use Neos\Neos\Ui\Domain\Service\UserLocaleService; -use Neos\Neos\Ui\Service\NodePolicyService; use Neos\Neos\Utility\NodeTypeWithFallbackProvider; /** @@ -42,24 +39,12 @@ class NodeInfoHelper implements ProtectedContextAwareInterface #[Flow\Inject] protected ContentRepositoryRegistry $contentRepositoryRegistry; - /** - * @Flow\Inject - * @var NodePolicyService - */ - protected $nodePolicyService; - /** * @Flow\Inject * @var UserLocaleService */ protected $userLocaleService; - /** - * @Flow\Inject - * @var EntityToIdentityConverter - */ - protected $entityToIdentityConverter; - /** * @Flow\Inject * @var PersistenceManagerInterface @@ -78,12 +63,6 @@ class NodeInfoHelper implements ProtectedContextAwareInterface */ protected $baseNodeType; - /** - * @Flow\InjectConfiguration(path="userInterface.navigateComponent.nodeTree.loadingDepth", package="Neos.Neos") - * @var string - */ - protected $loadingDepth; - /** * @Flow\InjectConfiguration(path="nodeTypeRoles.document", package="Neos.Neos.Ui") * @var string diff --git a/Classes/TypeConverter/ChangeCollectionConverter.php b/Classes/TypeConverter/ChangeCollectionConverter.php index f6ac74214b..1d1d24f9ce 100644 --- a/Classes/TypeConverter/ChangeCollectionConverter.php +++ b/Classes/TypeConverter/ChangeCollectionConverter.php @@ -96,21 +96,12 @@ class ChangeCollectionConverter * Converts a accordingly formatted, associative array to a change collection * * @param array> $source - * @param string $targetType not used - * @param array $subProperties not used - * @param PropertyMappingConfigurationInterface $configuration not used - * @return ChangeCollection|Error An object or \Neos\Error\Messages\Error if the input format is not supported - * or could not be converted for other reasons * @throws \Exception */ public function convert( array $source, ContentRepositoryId $contentRepositoryId ): ChangeCollection { - if (!is_array($source)) { - throw new \RuntimeException(sprintf('Cannot convert %s to ChangeCollection.', gettype($source))); - } - $changeCollection = new ChangeCollection(); foreach ($source as $changeData) { $convertedData = $this->convertChangeData($changeData, $contentRepositoryId); diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000000..93039f2700 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,4 @@ +parameters: + level: 2 + paths: + - Classes From 455fd86bca311550987d04fc099fd9262409846a Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 19 Oct 2023 11:59:29 +0200 Subject: [PATCH 18/43] TASK: Level up to phpstan 5 --- Classes/Domain/Model/Changes/Remove.php | 2 +- Classes/Fusion/Helper/NodeInfoHelper.php | 2 +- phpstan.neon | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Classes/Domain/Model/Changes/Remove.php b/Classes/Domain/Model/Changes/Remove.php index e1e9063013..e58a98ff76 100644 --- a/Classes/Domain/Model/Changes/Remove.php +++ b/Classes/Domain/Model/Changes/Remove.php @@ -78,7 +78,7 @@ public function apply(): void NodeVariantSelectionStrategy::STRATEGY_ALL_SPECIALIZATIONS, ); if ($closestDocumentParentNode !== null) { - $command = $command->withRemovalAttachmentPoint($closestDocumentParentNode?->nodeAggregateId); + $command = $command->withRemovalAttachmentPoint($closestDocumentParentNode->nodeAggregateId); } $contentRepository = $this->contentRepositoryRegistry->get($subject->subgraphIdentity->contentRepositoryId); diff --git a/Classes/Fusion/Helper/NodeInfoHelper.php b/Classes/Fusion/Helper/NodeInfoHelper.php index 0f2bd21300..05b79eb763 100644 --- a/Classes/Fusion/Helper/NodeInfoHelper.php +++ b/Classes/Fusion/Helper/NodeInfoHelper.php @@ -226,7 +226,7 @@ protected function getBasicNodeInformation(Node $node): array 'parent' => $parentNode ? $nodeAddressFactory->createFromNode($parentNode)->serializeForUri() : null, 'matchesCurrentDimensions' => $node->subgraphIdentity->dimensionSpacePoint->equals($node->originDimensionSpacePoint), 'lastModificationDateTime' => $node->timestamps->lastModified?->format(\DateTime::ATOM), - 'creationDateTime' => $node->timestamps->created?->format(\DateTime::ATOM), + 'creationDateTime' => $node->timestamps->created->format(\DateTime::ATOM), 'lastPublicationDateTime' => $node->timestamps->originalLastModified?->format(\DateTime::ATOM) ]; } diff --git a/phpstan.neon b/phpstan.neon index 93039f2700..3abf7a6cac 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,4 +1,4 @@ parameters: - level: 2 + level: 5 paths: - Classes From 2d1b2b856f6665d50e627648e71928ba15fb0e78 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 19 Oct 2023 12:04:59 +0200 Subject: [PATCH 19/43] TASK: Run phpstan in ci --- .circleci/config.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index bbcb37a3b9..565b0fde03 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -140,6 +140,20 @@ jobs: cd /home/circleci/app/ bin/phpunit -c Build/BuildEssentials/PhpUnit/UnitTests.xml Packages/Application/Neos.Neos.Ui/Tests/Unit + php-linting: + docker: + - image: cimg/php:8.2-node + working_directory: *workspace_root + steps: + - attach_workspace: *attach_workspace + - restore_cache: *restore_app_cache + + - run: rm -rf /home/circleci/app/Packages/Application/Neos.Neos.Ui + - run: cd /home/circleci/app/Packages/Application && mv ~/neos-ui-workspace Neos.Neos.Ui + - run: | + cd /home/circleci/app/Packages/Application/Neos.Neos.Ui/Tests/Unit + ../../../bin/phpstan analyse + workflows: version: 2 build_and_test: From ad5890212aa7960c159b6bc937f8ea79b50f1441 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 19 Oct 2023 12:33:03 +0200 Subject: [PATCH 20/43] TASK: Add array types (phpstan level 6) --- .../Service/WorkspaceService.php | 1 + Classes/Controller/BackendServiceController.php | 14 +++++++------- Classes/Domain/Model/AbstractFeedback.php | 3 ++- .../Model/Feedback/Operations/Redirect.php | 4 ++-- .../Operations/ReloadContentOutOfBand.php | 2 +- .../Operations/UpdateNodePreviewUrl.php | 4 ++-- Classes/Domain/Model/FeedbackCollection.php | 4 ++-- Classes/Domain/Model/FeedbackInterface.php | 4 ++-- Classes/Domain/Model/RenderedNodeDomAddress.php | 5 ++--- .../Service/ConfigurationRenderingService.php | 16 ++++++++-------- .../StyleAndJavascriptInclusionService.php | 17 ++++++++++------- Classes/Domain/Service/UserLocaleService.php | 4 ++-- Classes/Fusion/Helper/ApiHelper.php | 7 +++---- .../Fusion/Helper/ContentDimensionsHelper.php | 1 + .../Helper/PositionalArraySorterHelper.php | 6 +++--- Classes/Fusion/Helper/StaticResourcesHelper.php | 2 +- Classes/Fusion/Helper/WorkspaceHelper.php | 5 ++++- .../RenderConfigurationImplementation.php | 6 +++--- phpstan.neon | 2 +- 19 files changed, 57 insertions(+), 50 deletions(-) diff --git a/Classes/ContentRepository/Service/WorkspaceService.php b/Classes/ContentRepository/Service/WorkspaceService.php index 8e05538eae..e717383043 100644 --- a/Classes/ContentRepository/Service/WorkspaceService.php +++ b/Classes/ContentRepository/Service/WorkspaceService.php @@ -157,6 +157,7 @@ public function getAllowedTargetWorkspaces(ContentRepository $contentRepository) return $workspacesArray; } + /** @return list */ public function predictRemoveNodeFeedbackFromDiscardIndividualNodesFromWorkspaceCommand( DiscardIndividualNodesFromWorkspace $command, ContentRepository $contentRepository diff --git a/Classes/Controller/BackendServiceController.php b/Classes/Controller/BackendServiceController.php index 32f16f0a10..7d9dc91ef1 100644 --- a/Classes/Controller/BackendServiceController.php +++ b/Classes/Controller/BackendServiceController.php @@ -150,14 +150,13 @@ protected function initializeController(ActionRequest $request, ActionResponse $ /** * Apply a set of changes to the system + * @param array> $changes */ public function changeAction(array $changes): void { $contentRepositoryId = SiteDetectionResult::fromRequest($this->request->getHttpRequest())->contentRepositoryId; - /** @param array> $changes */ $changes = $this->changeCollectionConverter->convert($changes, $contentRepositoryId); - /** @var ChangeCollection $changes */ try { $count = $changes->count(); $changes->apply(); @@ -200,7 +199,7 @@ public function publishAllAction(): void /** * Publish nodes * - * @param array $nodeContextPaths + * @param list $nodeContextPaths */ public function publishAction(array $nodeContextPaths, string $targetWorkspaceName): void { @@ -258,7 +257,7 @@ public function publishAction(array $nodeContextPaths, string $targetWorkspaceNa /** * Discard nodes * - * @param array $nodeContextPaths + * @param list $nodeContextPaths */ public function discardAction(array $nodeContextPaths): void { @@ -407,7 +406,7 @@ public function changeBaseWorkspaceAction(string $targetWorkspaceName, string $d /** * Persists the clipboard node on copy * - * @param array $nodes + * @param list $nodes * @return void * @throws \Neos\Flow\Property\Exception * @throws \Neos\Flow\Security\Exception @@ -439,7 +438,7 @@ public function clearClipboardAction() /** * Persists the clipboard node on cut * - * @param array $nodes + * @param list $nodes * @throws \Neos\Flow\Property\Exception * @throws \Neos\Flow\Security\Exception */ @@ -477,6 +476,7 @@ public function initializeGetAdditionalNodeMetadataAction(): void /** * Fetches all the node information that can be lazy-loaded + * @param list $nodes */ public function getAdditionalNodeMetadataAction(array $nodes): void { @@ -559,7 +559,7 @@ public function getPolicyInformationAction(array $nodes): void /** * Build and execute a flow query chain * - * @param array $chain + * @param array $chain */ public function flowQueryAction(array $chain): string { diff --git a/Classes/Domain/Model/AbstractFeedback.php b/Classes/Domain/Model/AbstractFeedback.php index 5a4ca35ae1..e852cd7c60 100644 --- a/Classes/Domain/Model/AbstractFeedback.php +++ b/Classes/Domain/Model/AbstractFeedback.php @@ -16,7 +16,8 @@ abstract class AbstractFeedback implements FeedbackInterface { - public function serialize(ControllerContext $controllerContext) + /** @return array */ + public function serialize(ControllerContext $controllerContext): array { return [ 'type' => $this->getType(), diff --git a/Classes/Domain/Model/Feedback/Operations/Redirect.php b/Classes/Domain/Model/Feedback/Operations/Redirect.php index 8020b73dab..e5d271dc88 100644 --- a/Classes/Domain/Model/Feedback/Operations/Redirect.php +++ b/Classes/Domain/Model/Feedback/Operations/Redirect.php @@ -89,9 +89,9 @@ public function isSimilarTo(FeedbackInterface $feedback) * Serialize the payload for this feedback * * @param ControllerContext $controllerContext - * @return array + * @return array */ - public function serializePayload(ControllerContext $controllerContext) + public function serializePayload(ControllerContext $controllerContext): array { $node = $this->getNode(); $redirectUri = $this->linkingService->createNodeUri($controllerContext, $node, null, null, true); diff --git a/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php b/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php index 07a6108a3f..fc511798de 100644 --- a/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php +++ b/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php @@ -154,7 +154,7 @@ protected function renderContent(ControllerContext $controllerContext): string|R /** * @return array */ - public function serialize(ControllerContext $controllerContext) + public function serialize(ControllerContext $controllerContext): array { try { return parent::serialize($controllerContext); diff --git a/Classes/Domain/Model/Feedback/Operations/UpdateNodePreviewUrl.php b/Classes/Domain/Model/Feedback/Operations/UpdateNodePreviewUrl.php index a0d122c2e3..5ef0b821f3 100644 --- a/Classes/Domain/Model/Feedback/Operations/UpdateNodePreviewUrl.php +++ b/Classes/Domain/Model/Feedback/Operations/UpdateNodePreviewUrl.php @@ -92,9 +92,9 @@ public function isSimilarTo(FeedbackInterface $feedback) * Serialize the payload for this feedback * * @param ControllerContext $controllerContext - * @return array + * @return array */ - public function serializePayload(ControllerContext $controllerContext) + public function serializePayload(ControllerContext $controllerContext): array { if ($this->node === null) { $newPreviewUrl = ''; diff --git a/Classes/Domain/Model/FeedbackCollection.php b/Classes/Domain/Model/FeedbackCollection.php index 511289c083..0857f1adbe 100644 --- a/Classes/Domain/Model/FeedbackCollection.php +++ b/Classes/Domain/Model/FeedbackCollection.php @@ -60,7 +60,7 @@ public function add(FeedbackInterface $feedback) /** * Serialize collection to `json_encode`able array * - * @return array + * @return array */ public function jsonSerialize(): array { @@ -76,7 +76,7 @@ public function jsonSerialize(): array ]; } - public function reset() + public function reset(): void { $this->feedbacks = []; } diff --git a/Classes/Domain/Model/FeedbackInterface.php b/Classes/Domain/Model/FeedbackInterface.php index 4ca4bd4f97..6eb7af63b7 100644 --- a/Classes/Domain/Model/FeedbackInterface.php +++ b/Classes/Domain/Model/FeedbackInterface.php @@ -20,9 +20,9 @@ interface FeedbackInterface * in AbstractFeedback, but can be overridden to implement fallback logic in case of errors. * * @param ControllerContext $controllerContext - * @return array + * @return array */ - public function serialize(ControllerContext $controllerContext); + public function serialize(ControllerContext $controllerContext): array; /** * Get the type identifier diff --git a/Classes/Domain/Model/RenderedNodeDomAddress.php b/Classes/Domain/Model/RenderedNodeDomAddress.php index 95264deaaf..249ce70e1e 100644 --- a/Classes/Domain/Model/RenderedNodeDomAddress.php +++ b/Classes/Domain/Model/RenderedNodeDomAddress.php @@ -95,10 +95,9 @@ public function getFusionPathForContentRendering(): string /** * Serialize to json * - * @return array + * @return array */ - #[\ReturnTypeWillChange] - public function jsonSerialize(): mixed + public function jsonSerialize(): array { return [ 'contextPath' => $this->getContextPath(), diff --git a/Classes/Domain/Service/ConfigurationRenderingService.php b/Classes/Domain/Service/ConfigurationRenderingService.php index 1c9c75c31b..577934152d 100644 --- a/Classes/Domain/Service/ConfigurationRenderingService.php +++ b/Classes/Domain/Service/ConfigurationRenderingService.php @@ -28,20 +28,20 @@ class ConfigurationRenderingService /** * @Flow\InjectConfiguration(package="Neos.Fusion", path="defaultContext") - * @var array + * @var array */ protected $fusionDefaultEelContext; /** * @Flow\InjectConfiguration(path="configurationDefaultEelContext") - * @var array + * @var array */ protected $additionalEelDefaultContext; /** - * @param array $configuration - * @param array $context - * @return array + * @param array $configuration + * @param array $context + * @return array * @throws \Neos\Eel\Exception */ public function computeConfiguration(array $configuration, array $context): array @@ -53,11 +53,11 @@ public function computeConfiguration(array $configuration, array $context): arra } /** - * @param array $adjustedConfiguration - * @param array $context + * @param array $adjustedConfiguration + * @param array $context * @throws \Neos\Eel\Exception */ - protected function computeConfigurationInternally(array &$adjustedConfiguration, array $context) + protected function computeConfigurationInternally(array &$adjustedConfiguration, array $context): void { foreach ($adjustedConfiguration as $key => &$value) { if (is_array($value)) { diff --git a/Classes/Domain/Service/StyleAndJavascriptInclusionService.php b/Classes/Domain/Service/StyleAndJavascriptInclusionService.php index afaf8e5ba9..28a095b080 100644 --- a/Classes/Domain/Service/StyleAndJavascriptInclusionService.php +++ b/Classes/Domain/Service/StyleAndJavascriptInclusionService.php @@ -36,43 +36,46 @@ class StyleAndJavascriptInclusionService /** * @Flow\InjectConfiguration(package="Neos.Fusion", path="defaultContext") - * @var array + * @var array */ protected $fusionDefaultEelContext; /** * @Flow\InjectConfiguration(path="configurationDefaultEelContext") - * @var array + * @var array */ protected $additionalEelDefaultContext; /** * @Flow\InjectConfiguration(path="resources.javascript") - * @var array + * @var array, position: string}> */ protected $javascriptResources; /** * @Flow\InjectConfiguration(path="resources.stylesheets") - * @var array + * @var array, position: string}> */ protected $stylesheetResources; - public function getHeadScripts() + public function getHeadScripts(): string { return $this->build($this->javascriptResources, function ($uri, $additionalAttributes) { return ''; }); } - public function getHeadStylesheets() + public function getHeadStylesheets(): string { return $this->build($this->stylesheetResources, function ($uri, $additionalAttributes) { return ''; }); } - protected function build(array $resourceArrayToSort, \Closure $builderForLine) + /** + * @param array}> $resourceArrayToSort + */ + protected function build(array $resourceArrayToSort, \Closure $builderForLine): string { $sortedResources = (new PositionalArraySorter($resourceArrayToSort))->toArray(); diff --git a/Classes/Domain/Service/UserLocaleService.php b/Classes/Domain/Service/UserLocaleService.php index b7dc351b24..aaafb2d721 100644 --- a/Classes/Domain/Service/UserLocaleService.php +++ b/Classes/Domain/Service/UserLocaleService.php @@ -40,9 +40,9 @@ class UserLocaleService /** * For serialization, we need to respect the UI locale, rather than the content locale * - * @param boolean $reset Reset to remebered locale + * @param boolean $reset Reset to remembered locale */ - public function switchToUILocale($reset = false) + public function switchToUILocale($reset = false): void { if ($reset === true) { // Reset the locale diff --git a/Classes/Fusion/Helper/ApiHelper.php b/Classes/Fusion/Helper/ApiHelper.php index 4f51751f9e..e53289a259 100644 --- a/Classes/Fusion/Helper/ApiHelper.php +++ b/Classes/Fusion/Helper/ApiHelper.php @@ -20,12 +20,11 @@ class ApiHelper implements ProtectedContextAwareInterface * * Use this helper to prevent associative arrays from being converted to non-associative arrays by json_encode. * This is an internal helper and might change without further notice - * FIXME: Probably better to produce objects in the first place "upstream". * - * @param array $array Associative array which may be empty - * @return array|\stdClass Non-empty associative array or empty object + * @param array $array Associative array which may be empty + * @return array|\stdClass Non-empty associative array or empty object */ - public function emptyArrayToObject(array $array) + public function emptyArrayToObject(array $array): array|object { return $array === [] ? new \stdClass() : $array; } diff --git a/Classes/Fusion/Helper/ContentDimensionsHelper.php b/Classes/Fusion/Helper/ContentDimensionsHelper.php index 7008f58a68..ff2226a185 100644 --- a/Classes/Fusion/Helper/ContentDimensionsHelper.php +++ b/Classes/Fusion/Helper/ContentDimensionsHelper.php @@ -88,6 +88,7 @@ public function allowedPresetsByName(DimensionSpacePoint $dimensions, ContentRep return $allowedPresets; } + /** @return array> */ public function dimensionSpacePointArray(AbstractDimensionSpacePoint $dimensionSpacePoint): array { return $dimensionSpacePoint->toLegacyDimensionArray(); diff --git a/Classes/Fusion/Helper/PositionalArraySorterHelper.php b/Classes/Fusion/Helper/PositionalArraySorterHelper.php index d3aab671b2..5cb7bc44b4 100644 --- a/Classes/Fusion/Helper/PositionalArraySorterHelper.php +++ b/Classes/Fusion/Helper/PositionalArraySorterHelper.php @@ -17,11 +17,11 @@ class PositionalArraySorterHelper implements ProtectedContextAwareInterface { /** - * @param array $array + * @param array $array * @param string $positionPath - * @return array + * @return array */ - public function sort($array, $positionPath = 'position') + public function sort(array $array, string $positionPath = 'position'): array { return (new PositionalArraySorter($array, $positionPath))->toArray(); } diff --git a/Classes/Fusion/Helper/StaticResourcesHelper.php b/Classes/Fusion/Helper/StaticResourcesHelper.php index 2eb9cc9927..1e0b595bd3 100644 --- a/Classes/Fusion/Helper/StaticResourcesHelper.php +++ b/Classes/Fusion/Helper/StaticResourcesHelper.php @@ -22,7 +22,7 @@ class StaticResourcesHelper implements ProtectedContextAwareInterface */ protected $frontendDevelopmentMode; - public function compiledResourcePackage() + public function compiledResourcePackage(): string { if ($this->frontendDevelopmentMode) { return 'Neos.Neos.Ui'; diff --git a/Classes/Fusion/Helper/WorkspaceHelper.php b/Classes/Fusion/Helper/WorkspaceHelper.php index 79903349ac..7d3c8c14b3 100644 --- a/Classes/Fusion/Helper/WorkspaceHelper.php +++ b/Classes/Fusion/Helper/WorkspaceHelper.php @@ -49,7 +49,10 @@ class WorkspaceHelper implements ProtectedContextAwareInterface */ protected $securityContext; - public function getAllowedTargetWorkspaces(ContentRepositoryId $contentRepositoryId) + /** + * @return array> + */ + public function getAllowedTargetWorkspaces(ContentRepositoryId $contentRepositoryId): array { $contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId); return $this->workspaceService->getAllowedTargetWorkspaces($contentRepository); diff --git a/Classes/Fusion/RenderConfigurationImplementation.php b/Classes/Fusion/RenderConfigurationImplementation.php index 152d82093b..96b085b7f0 100644 --- a/Classes/Fusion/RenderConfigurationImplementation.php +++ b/Classes/Fusion/RenderConfigurationImplementation.php @@ -26,12 +26,12 @@ class RenderConfigurationImplementation extends AbstractFusionObject /** * @Flow\InjectConfiguration() - * @var array + * @var array */ protected $settings; /** - * @return array + * @return array */ protected function getContext(): array { @@ -49,7 +49,7 @@ protected function getPath(): string /** * Appends an item to the given collection * - * @return array + * @return array * @throws Exception */ public function evaluate() diff --git a/phpstan.neon b/phpstan.neon index 3abf7a6cac..302c9f028f 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,4 +1,4 @@ parameters: - level: 5 + level: 6 paths: - Classes From 5a6602671beb532ee4957ef7d7bacf69f8c2d21a Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 19 Oct 2023 12:33:22 +0200 Subject: [PATCH 21/43] TASK: Remove legacy UiDependentImageSerializer --- .../UiDependentImageSerializer.php | 45 ------------------- Configuration/Settings.yaml | 2 +- 2 files changed, 1 insertion(+), 46 deletions(-) delete mode 100644 Classes/TypeConverter/UiDependentImageSerializer.php diff --git a/Classes/TypeConverter/UiDependentImageSerializer.php b/Classes/TypeConverter/UiDependentImageSerializer.php deleted file mode 100644 index 39f6456aec..0000000000 --- a/Classes/TypeConverter/UiDependentImageSerializer.php +++ /dev/null @@ -1,45 +0,0 @@ -objectManager->get(ImageInterfaceArrayPresenter::class); - return $innerConverter->convertFrom($source, $targetType, $convertedChildProperties, $configuration); - } -} diff --git a/Configuration/Settings.yaml b/Configuration/Settings.yaml index 7e7ee51eaf..92de6e127f 100644 --- a/Configuration/Settings.yaml +++ b/Configuration/Settings.yaml @@ -20,7 +20,7 @@ Neos: inspector: dataTypes: Neos\Media\Domain\Model\ImageInterface: - typeConverter: Neos\Neos\Ui\TypeConverter\UiDependentImageSerializer + typeConverter: Neos\Media\TypeConverter\ImageInterfaceArrayPresenter translation: autoInclude: 'Neos.Neos.Ui': From afb3460bd1be1fb1dc1f5e123659db3f80ef8676 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 19 Oct 2023 12:46:04 +0200 Subject: [PATCH 22/43] TASK: Fix phpstan level 6 --- Classes/Service/NodePropertyValidationService.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Classes/Service/NodePropertyValidationService.php b/Classes/Service/NodePropertyValidationService.php index 552fbd20f3..228e00bb88 100644 --- a/Classes/Service/NodePropertyValidationService.php +++ b/Classes/Service/NodePropertyValidationService.php @@ -38,12 +38,11 @@ class NodePropertyValidationService protected $dateTimeConverter; /** - * @param $value * @param string $validatorName - * @param array $validatorConfiguration + * @param array $validatorConfiguration * @return bool */ - public function validate($value, string $validatorName, array $validatorConfiguration): bool + public function validate(mixed $value, string $validatorName, array $validatorConfiguration): bool { $validator = $this->resolveValidator($validatorName, $validatorConfiguration); @@ -70,7 +69,7 @@ public function validate($value, string $validatorName, array $validatorConfigur /** * @param string $validatorName - * @param array $validatorConfiguration + * @param array $validatorConfiguration * @return ValidatorInterface|null */ protected function resolveValidator(string $validatorName, array $validatorConfiguration) @@ -88,6 +87,8 @@ protected function resolveValidator(string $validatorName, array $validatorConfi return null; } - return new $fullQualifiedValidatorClassName($validatorConfiguration); + /** @var ValidatorInterface $validator */ + $validator = new $fullQualifiedValidatorClassName($validatorConfiguration); + return $validator; } } From ef2172f53dffe51a9797411d942f4fcccd6b7680 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 19 Oct 2023 12:47:18 +0200 Subject: [PATCH 23/43] TASK: Fix phpstan ci --- .circleci/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 565b0fde03..f57d0a5c8e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -175,3 +175,6 @@ workflows: - php-unittests: requires: - build_flow_app + - php-linting: + requires: + - build_flow_app From fc1b95830e94be34c006f19665b76ae7e1022a6f Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 19 Oct 2023 13:03:03 +0200 Subject: [PATCH 24/43] TASK: Level up - pling kling kling 7 :D --- Classes/Controller/BackendServiceController.php | 10 ++++++---- .../Service/StyleAndJavascriptInclusionService.php | 2 +- .../Fusion/ExceptionHandler/PageExceptionHandler.php | 1 + phpstan.neon | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Classes/Controller/BackendServiceController.php b/Classes/Controller/BackendServiceController.php index 7d9dc91ef1..afc3205d06 100644 --- a/Classes/Controller/BackendServiceController.php +++ b/Classes/Controller/BackendServiceController.php @@ -24,6 +24,7 @@ use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\Eel\FlowQuery\FlowQuery; +use Neos\Eel\FlowQuery\Operations\GetOperation; use Neos\Flow\Annotations as Flow; use Neos\Flow\Mvc\ActionRequest; use Neos\Flow\Mvc\ActionResponse; @@ -39,7 +40,6 @@ use Neos\Neos\Service\UserService; use Neos\Neos\Ui\ContentRepository\Service\NeosUiNodeService; use Neos\Neos\Ui\ContentRepository\Service\WorkspaceService; -use Neos\Neos\Ui\Domain\Model\ChangeCollection; use Neos\Neos\Ui\Domain\Model\Feedback\Messages\Error; use Neos\Neos\Ui\Domain\Model\Feedback\Messages\Info; use Neos\Neos\Ui\Domain\Model\Feedback\Messages\Success; @@ -559,7 +559,7 @@ public function getPolicyInformationAction(array $nodes): void /** * Build and execute a flow query chain * - * @param array $chain + * @param list}> $chain */ public function flowQueryAction(array $chain): string { @@ -568,7 +568,6 @@ public function flowQueryAction(array $chain): string $createContext = array_shift($chain); $finisher = array_pop($chain); - /** @var array $payload */ $payload = $createContext['payload'] ?? []; $flowQuery = new FlowQuery(array_map( fn ($envelope) => $this->nodeService->findNodeBySerializedNodeAddress($envelope['$node'], $contentRepositoryId), @@ -576,9 +575,12 @@ public function flowQueryAction(array $chain): string )); foreach ($chain as $operation) { - $flowQuery = call_user_func_array([$flowQuery, $operation['type']], $operation['payload']); + $flowQuery = $flowQuery->__call($operation['type'], $operation['payload']); } + /** @see GetOperation */ + assert(is_callable([$flowQuery, 'get'])); + $nodeInfoHelper = new NodeInfoHelper(); $type = $finisher['type'] ?? null; $result = match ($type) { diff --git a/Classes/Domain/Service/StyleAndJavascriptInclusionService.php b/Classes/Domain/Service/StyleAndJavascriptInclusionService.php index 28a095b080..429acb92aa 100644 --- a/Classes/Domain/Service/StyleAndJavascriptInclusionService.php +++ b/Classes/Domain/Service/StyleAndJavascriptInclusionService.php @@ -95,7 +95,7 @@ protected function build(array $resourceArrayToSort, \Closure $builderForLine): if (strpos($resourceExpression, 'resource://') === 0) { // Cache breaker - $hash = substr(md5_file($resourceExpression), 0, 8); + $hash = substr(md5_file($resourceExpression) ?: '', 0, 8); $resourceExpression = $this->resourceManager->getPublicPackageResourceUriByPath($resourceExpression); } $finalUri = $hash ? $resourceExpression . '?' . $hash : $resourceExpression; diff --git a/Classes/Fusion/ExceptionHandler/PageExceptionHandler.php b/Classes/Fusion/ExceptionHandler/PageExceptionHandler.php index 0f5da7f79d..3ac58869a0 100644 --- a/Classes/Fusion/ExceptionHandler/PageExceptionHandler.php +++ b/Classes/Fusion/ExceptionHandler/PageExceptionHandler.php @@ -69,6 +69,7 @@ protected function handle($fusionPath, \Exception $exception, $referenceCode): s 'message' => $output ]); + // @phpstan-ignore-next-line return $this->wrapHttpResponse($exception, $fluidView->render()); } diff --git a/phpstan.neon b/phpstan.neon index 302c9f028f..90b4b0c2db 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,4 +1,4 @@ parameters: - level: 6 + level: 7 paths: - Classes From 140346b1c3b0c9523aa577858438b4c28d5bf92b Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 19 Oct 2023 13:05:56 +0200 Subject: [PATCH 25/43] TASK: Add phpstan to ci via composer --- Tests/IntegrationTests/TestDistribution/composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/IntegrationTests/TestDistribution/composer.json b/Tests/IntegrationTests/TestDistribution/composer.json index 20704ec76d..a83a30f06b 100644 --- a/Tests/IntegrationTests/TestDistribution/composer.json +++ b/Tests/IntegrationTests/TestDistribution/composer.json @@ -1,4 +1,3 @@ - { "name": "neos/test-distribution", "description": "Neos test distribution. Change this number if you need to break CircleCI's cache: 14", @@ -28,7 +27,8 @@ }, "require-dev": { "neos/buildessentials": "@dev", - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.0", + "phpstan/phpstan": "^1.10" }, "extra": { "patches": { From 3055ab83671d9011a83cd5f1ce8f8751eaf6887a Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 19 Oct 2023 22:33:06 +0200 Subject: [PATCH 26/43] TASK: Fix types --- Classes/ContentRepository/Service/WorkspaceService.php | 4 +--- Classes/Domain/Model/Changes/AbstractStructuralChange.php | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Classes/ContentRepository/Service/WorkspaceService.php b/Classes/ContentRepository/Service/WorkspaceService.php index e717383043..86e6bc4f52 100644 --- a/Classes/ContentRepository/Service/WorkspaceService.php +++ b/Classes/ContentRepository/Service/WorkspaceService.php @@ -16,7 +16,6 @@ use Neos\ContentRepository\Core\Feature\WorkspacePublication\Command\DiscardIndividualNodesFromWorkspace; use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindClosestNodeFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; -use Neos\ContentRepository\Core\Projection\Workspace\Workspace; use Neos\Neos\Domain\Service\NodeTypeNameFactory; use Neos\Neos\FrontendRouting\NodeAddress; use Neos\Neos\FrontendRouting\NodeAddressFactory; @@ -128,7 +127,6 @@ public function getAllowedTargetWorkspaces(ContentRepository $contentRepository) $user = $this->domainUserService->getCurrentUser(); $workspacesArray = []; - /** @var Workspace $workspace */ foreach ($contentRepository->getWorkspaceFinder()->findAll() as $workspace) { // FIXME: This check should be implemented through a specialized Workspace Privilege or something similar // Skip workspace not owned by current user @@ -193,7 +191,7 @@ public function predictRemoveNodeFeedbackFromDiscardIndividualNodesFromWorkspace $childNode = $subgraph->findNodeById($nodeToDiscard->nodeAggregateId); $parentNode = $subgraph->findParentNode($nodeToDiscard->nodeAggregateId); - if ($parentNode) { + if ($childNode && $parentNode) { $result[] = new RemoveNode($childNode, $parentNode); $handledNodes[] = $nodeToDiscard; } diff --git a/Classes/Domain/Model/Changes/AbstractStructuralChange.php b/Classes/Domain/Model/Changes/AbstractStructuralChange.php index cf44178df0..f49e22baa5 100644 --- a/Classes/Domain/Model/Changes/AbstractStructuralChange.php +++ b/Classes/Domain/Model/Changes/AbstractStructuralChange.php @@ -106,7 +106,7 @@ public function getSiblingDomAddress(): ?RenderedNodeDomAddress */ public function getSiblingNode(): ?Node { - if ($this->siblingDomAddress === null) { + if ($this->siblingDomAddress === null || !$this->getSubject()) { return null; } @@ -152,7 +152,7 @@ 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($parentNode->subgraphIdentity->contentRepositoryId); + $contentRepository = $this->contentRepositoryRegistry->get($node->subgraphIdentity->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 From b271053d1f01557b657e57a704b2fd3b34b69d29 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Fri, 20 Oct 2023 15:15:59 +0200 Subject: [PATCH 27/43] TASK: Flow doesnt know about `list` type --- Classes/Controller/BackendServiceController.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Classes/Controller/BackendServiceController.php b/Classes/Controller/BackendServiceController.php index afc3205d06..825de3c014 100644 --- a/Classes/Controller/BackendServiceController.php +++ b/Classes/Controller/BackendServiceController.php @@ -199,7 +199,7 @@ public function publishAllAction(): void /** * Publish nodes * - * @param list $nodeContextPaths + * @psalm-param list $nodeContextPaths */ public function publishAction(array $nodeContextPaths, string $targetWorkspaceName): void { @@ -257,7 +257,7 @@ public function publishAction(array $nodeContextPaths, string $targetWorkspaceNa /** * Discard nodes * - * @param list $nodeContextPaths + * @psalm-param list $nodeContextPaths */ public function discardAction(array $nodeContextPaths): void { @@ -406,7 +406,7 @@ public function changeBaseWorkspaceAction(string $targetWorkspaceName, string $d /** * Persists the clipboard node on copy * - * @param list $nodes + * @psalm-param list $nodes * @return void * @throws \Neos\Flow\Property\Exception * @throws \Neos\Flow\Security\Exception @@ -438,7 +438,7 @@ public function clearClipboardAction() /** * Persists the clipboard node on cut * - * @param list $nodes + * @psalm-param list $nodes * @throws \Neos\Flow\Property\Exception * @throws \Neos\Flow\Security\Exception */ @@ -476,7 +476,7 @@ public function initializeGetAdditionalNodeMetadataAction(): void /** * Fetches all the node information that can be lazy-loaded - * @param list $nodes + * @psalm-param list $nodes */ public function getAdditionalNodeMetadataAction(array $nodes): void { @@ -559,7 +559,7 @@ public function getPolicyInformationAction(array $nodes): void /** * Build and execute a flow query chain * - * @param list}> $chain + * @psalm-param list}> $chain */ public function flowQueryAction(array $chain): string { From fc80f493c8427343f9437599e7ea297e81561f71 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Fri, 20 Oct 2023 15:51:28 +0200 Subject: [PATCH 28/43] TASK: Flow doesnt know about typed `array` type --- Classes/Controller/BackendServiceController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/Controller/BackendServiceController.php b/Classes/Controller/BackendServiceController.php index 825de3c014..af8e6a8b3a 100644 --- a/Classes/Controller/BackendServiceController.php +++ b/Classes/Controller/BackendServiceController.php @@ -150,7 +150,7 @@ protected function initializeController(ActionRequest $request, ActionResponse $ /** * Apply a set of changes to the system - * @param array> $changes + * @psalm-param list> $changes */ public function changeAction(array $changes): void { @@ -525,7 +525,7 @@ public function initializeGetPolicyInformationAction(): void } /** - * @param array $nodes + * @psalm-param list $nodes */ public function getPolicyInformationAction(array $nodes): void { From a9291267922733984283e08f0c3a7845cd644461 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Fri, 20 Oct 2023 17:01:16 +0200 Subject: [PATCH 29/43] TASK: Remove `CACHE_VERSION` and invalidate cache after each run The `CACHE_VERSION` was introduced via https://github.com/neos/neos-ui/pull/2883 as previously the cache could only be invalidated by changing the `composer.json` Eventually we should refactor our ci completely and only cache what is safely cacheable. This change effectively disables the cache. (We need the cache though for subsequent jobs) --- .circleci/config.yml | 18 +++++++++--------- README.md | 12 ------------ 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f57d0a5c8e..8161324e90 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,34 +3,34 @@ version: 2.0 aliases: - &workspace_root ~/neos-ui-workspace - &store_yarn_package_cache - key: yarn-cache-v{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }} + key: yarn-cache-v{{ .Environment.CIRCLE_WORKFLOW_ID }}-{{ checksum "yarn.lock" }} paths: - ~/.cache/yarn - &restore_yarn_package_cache keys: - - yarn-cache-v{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }} + - yarn-cache-v{{ .Environment.CIRCLE_WORKFLOW_ID }}-{{ checksum "yarn.lock" }} - &store_app_cache - key: full-app-cache-v{{ .Environment.CACHE_VERSION }}-{{ arch }}-{{ checksum "Tests/IntegrationTests/TestDistribution/composer.json" }}-{{ checksum "Tests/IntegrationTests/TestDistribution/Configuration/Settings.yaml" }} + key: full-app-cache-v{{ .Environment.CIRCLE_WORKFLOW_ID }}-{{ arch }}-{{ checksum "Tests/IntegrationTests/TestDistribution/composer.json" }}-{{ checksum "Tests/IntegrationTests/TestDistribution/Configuration/Settings.yaml" }} paths: - /home/circleci/app - &restore_app_cache keys: - - full-app-cache-v{{ .Environment.CACHE_VERSION }}-{{ arch }}-{{ checksum "Tests/IntegrationTests/TestDistribution/composer.json" }}-{{ checksum "Tests/IntegrationTests/TestDistribution/Configuration/Settings.yaml" }} - - full-app-cache-v{{ .Environment.CACHE_VERSION }}-{{ arch }}-{{ checksum "Tests/IntegrationTests/TestDistribution/composer.json" }}- - - full-app-cache-v{{ .Environment.CACHE_VERSION }}-{{ arch }}- + - full-app-cache-v{{ .Environment.CIRCLE_WORKFLOW_ID }}-{{ arch }}-{{ checksum "Tests/IntegrationTests/TestDistribution/composer.json" }}-{{ checksum "Tests/IntegrationTests/TestDistribution/Configuration/Settings.yaml" }} + - full-app-cache-v{{ .Environment.CIRCLE_WORKFLOW_ID }}-{{ arch }}-{{ checksum "Tests/IntegrationTests/TestDistribution/composer.json" }}- + - full-app-cache-v{{ .Environment.CIRCLE_WORKFLOW_ID }}-{{ arch }}- - &save_composer_cache - key: composer-cache-v{{ .Environment.CACHE_VERSION }}-{{ arch }}-{{ checksum "Tests/IntegrationTests/TestDistribution/composer.json" }} + key: composer-cache-v{{ .Environment.CIRCLE_WORKFLOW_ID }}-{{ arch }}-{{ checksum "Tests/IntegrationTests/TestDistribution/composer.json" }} paths: - /home/circleci/composer/cache-dir - &restore_composer_cache keys: - - composer-cache-v{{ .Environment.CACHE_VERSION }}-{{ arch }}-{{ checksum "Tests/IntegrationTests/TestDistribution/composer.json" }} - - composer-cache-v{{ .Environment.CACHE_VERSION }}-{{ arch }}- + - composer-cache-v{{ .Environment.CIRCLE_WORKFLOW_ID }}-{{ arch }}-{{ checksum "Tests/IntegrationTests/TestDistribution/composer.json" }} + - composer-cache-v{{ .Environment.CIRCLE_WORKFLOW_ID }}-{{ arch }}- - &attach_workspace at: *workspace_root diff --git a/README.md b/README.md index 8a5f024a6f..b937fce186 100644 --- a/README.md +++ b/README.md @@ -191,18 +191,6 @@ To speed up the e2e-test workflow/feedback loop you can start the system under t * Observe Flow exceptions and logs in build artifacts. * You can trigger a SSH enabled build via the CircleCI interface and then login. -###### Just the end to end tests fail - -It can happen that end to end tests fail caused by cached sources. So if you change PHP code for instance and don't adjust the composer.json it can happen that your new code change is not used because it is not part of the cache. In this case we need to flush the CircleCI caches manualy. - -We have introduced an environment variable called CACHE_VERSION. We need to change the variable to to new timestamp for instance to invalidate the caches. - -1. go to https://app.circleci.com/settings/project/github/neos/neos-ui and login -2. open the project settings and choose `Environment Variables` -3. Delete the `CACHE_VERSION` and create a new one with the value of the current timestamp - -Retrigger the build and it should work. - #### Releasing You only need to trigger the jenkins release with the version you want to release. From ad0d09969c8e323a2040b8721da4fc1afe009ef2 Mon Sep 17 00:00:00 2001 From: Mani Yadla <133841094+YadlaMani@users.noreply.github.com> Date: Fri, 20 Oct 2023 20:46:01 +0530 Subject: [PATCH 30/43] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8a5f024a6f..0f6339b00a 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Release roadmap is [available here](https://www.neos.io/features/release-process That means: * All bugfixes go to the lowest maintained branch * All new features go only to the 8.3 and 9.0 branch -* New minor and major releases are made in sync with Neos/Flow. Bugfix releases may be available independantly +* New minor and major releases are made in sync with Neos/Flow. Bugfix releases may be available independently ### Currently maintained versions @@ -57,7 +57,7 @@ composer update neos/neos-ui ### Installing latest development -For trying out the new UI, we recommend you to run the regularily released beta releases. +For trying out the new UI, we recommend you to run the regularly released beta releases. However, if you want to stay on bleeding-edge, or want to help out developing, you'll need the `9.0.x-dev` release. You can install the latest release using: From 671201bd11b9a067ea6b097b0fea174b42fe824c Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Sat, 21 Oct 2023 00:34:20 +0200 Subject: [PATCH 31/43] TASK: Fix phpstan ci --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8161324e90..1586bb789a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -151,7 +151,7 @@ jobs: - run: rm -rf /home/circleci/app/Packages/Application/Neos.Neos.Ui - run: cd /home/circleci/app/Packages/Application && mv ~/neos-ui-workspace Neos.Neos.Ui - run: | - cd /home/circleci/app/Packages/Application/Neos.Neos.Ui/Tests/Unit + cd /home/circleci/app/Packages/Application/Neos.Neos.Ui ../../../bin/phpstan analyse workflows: From 114c0e533a61c15b73ecce15754430c46a3c4f76 Mon Sep 17 00:00:00 2001 From: Bernhard Schmitt Date: Sat, 21 Oct 2023 01:01:05 +0200 Subject: [PATCH 32/43] 4622 - Allow other views than Fusion for out-of-band rendering --- .../OutOfBandRenderingViewFactory.php | 55 +++++++++++++++++++ .../Operations/ReloadContentOutOfBand.php | 16 +++--- .../Operations/RenderContentOutOfBand.php | 21 ++++--- Configuration/Settings.yaml | 2 + 4 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 Classes/Domain/Model/Feedback/Operations/OutOfBandRenderingViewFactory.php diff --git a/Classes/Domain/Model/Feedback/Operations/OutOfBandRenderingViewFactory.php b/Classes/Domain/Model/Feedback/Operations/OutOfBandRenderingViewFactory.php new file mode 100644 index 0000000000..cdeecd7e05 --- /dev/null +++ b/Classes/Domain/Model/Feedback/Operations/OutOfBandRenderingViewFactory.php @@ -0,0 +1,55 @@ +viewObjectName)) { + throw new \DomainException( + 'Declared view for out of band rendering (' . $this->viewObjectName . ') does not exist', + 1697821296 + ); + } + $view = new $this->viewObjectName(); + if (!$view instanceof AbstractView) { + throw new \DomainException( + 'Declared view (' . $this->viewObjectName . ') does not implement ' . AbstractView::class + . ' required for out-of-band rendering', + 1697821429 + ); + } + if (!$view instanceof RenderingEntryPointAware) { + throw new \DomainException( + 'Declared view (' . $this->viewObjectName . ') does not implement ' . RenderingEntryPointAware::class + . ' required for out-of-band rendering', + 1697821364 + ); + } + + return $view; + } +} diff --git a/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php b/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php index fc511798de..0243c8724f 100644 --- a/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php +++ b/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php @@ -23,7 +23,6 @@ use Neos\Neos\Ui\Domain\Model\AbstractFeedback; use Neos\Neos\Ui\Domain\Model\FeedbackInterface; use Neos\Neos\Ui\Domain\Model\RenderedNodeDomAddress; -use Neos\Neos\View\FusionView; use Psr\Http\Message\ResponseInterface; class ReloadContentOutOfBand extends AbstractFeedback @@ -53,6 +52,9 @@ class ReloadContentOutOfBand extends AbstractFeedback #[Flow\Inject] protected RenderingModeService $renderingModeService; + #[Flow\Inject] + protected OutOfBandRenderingViewFactory $outOfBandRenderingViewFactory; + public function setNode(Node $node): void { $this->node = $node; @@ -137,14 +139,14 @@ protected function renderContent(ControllerContext $controllerContext): string|R if ($this->nodeDomAddress) { $renderingMode = $this->renderingModeService->findByCurrentUser(); - $fusionView = new FusionView(); - $fusionView->setControllerContext($controllerContext); - $fusionView->setOption('renderingModeName', $renderingMode->name); + $view = $this->outOfBandRenderingViewFactory->resolveView(); + $view->setControllerContext($controllerContext); + $view->setOption('renderingModeName', $renderingMode->name); - $fusionView->assign('value', $this->node); - $fusionView->setFusionPath($this->nodeDomAddress->getFusionPathForContentRendering()); + $view->assign('value', $this->node); + $view->setRenderingEntryPoint($this->nodeDomAddress->getFusionPathForContentRendering()); - return $fusionView->render(); + return $view->render(); } } diff --git a/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php b/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php index 409ad394e7..3f6efd9652 100644 --- a/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php +++ b/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php @@ -1,5 +1,4 @@ node = $node; @@ -183,14 +188,14 @@ protected function renderContent(ControllerContext $controllerContext): string|R if ($parentDomAddress) { $renderingMode = $this->renderingModeService->findByCurrentUser(); - $fusionView = new FusionView(); - $fusionView->setControllerContext($controllerContext); - $fusionView->setOption('renderingModeName', $renderingMode->name); + $view = $this->outOfBandRenderingViewFactory->resolveView(); + $view->setControllerContext($controllerContext); + $view->setOption('renderingModeName', $renderingMode->name); - $fusionView->assign('value', $parentNode); - $fusionView->setFusionPath($parentDomAddress->getFusionPath()); + $view->assign('value', $parentNode); + $view->setRenderingEntryPoint($parentDomAddress->getFusionPath()); - return $fusionView->render(); + return $view->render(); } } diff --git a/Configuration/Settings.yaml b/Configuration/Settings.yaml index 92de6e127f..2d6b009589 100644 --- a/Configuration/Settings.yaml +++ b/Configuration/Settings.yaml @@ -191,6 +191,8 @@ Neos: 'Neos.Neos.Ui:MoveBefore': Neos\Neos\Ui\Domain\Model\Changes\MoveBefore 'Neos.Neos.Ui:MoveAfter': Neos\Neos\Ui\Domain\Model\Changes\MoveAfter 'Neos.Neos.Ui:MoveInto': Neos\Neos\Ui\Domain\Model\Changes\MoveInto + outOfBandRendering: + viewObjectName: 'Neos\Neos\View\FusionView' Flow: security: authentication: From f9ceb178d10459b979d4579e17d25a34fd5bbc50 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:55:12 +0200 Subject: [PATCH 33/43] TASK: Adjust `SetNodeReferences` to use static `create` factory Neos change https://github.com/neos/neos-development-collection/pull/4646 --- Classes/Domain/Model/Changes/Property.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/Domain/Model/Changes/Property.php b/Classes/Domain/Model/Changes/Property.php index 6401e3bb28..448a15a260 100644 --- a/Classes/Domain/Model/Changes/Property.php +++ b/Classes/Domain/Model/Changes/Property.php @@ -176,7 +176,7 @@ public function apply(): void } $commandResult = $contentRepository->handle( - new SetNodeReferences( + SetNodeReferences::create( $subject->subgraphIdentity->contentStreamId, $subject->nodeAggregateId, $subject->originDimensionSpacePoint, From ee7834752977755aab66558e940e460018a9bde5 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 26 Oct 2023 12:26:25 +0200 Subject: [PATCH 34/43] TASK: Adjust `FindClosestNodeFilter::create(nodeTypeConstraints)` --- Classes/ContentRepository/Service/WorkspaceService.php | 2 +- Classes/Domain/Model/AbstractChange.php | 2 +- Classes/Domain/Model/Changes/Remove.php | 2 +- Classes/Domain/Model/Feedback/Operations/ReloadDocument.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Classes/ContentRepository/Service/WorkspaceService.php b/Classes/ContentRepository/Service/WorkspaceService.php index 86e6bc4f52..ae6db1eca0 100644 --- a/Classes/ContentRepository/Service/WorkspaceService.php +++ b/Classes/ContentRepository/Service/WorkspaceService.php @@ -98,7 +98,7 @@ public function getPublishableNodeInfo(WorkspaceName $workspaceName, ContentRepo $node = $subgraph->findNodeById($change->nodeAggregateId); if ($node instanceof Node) { - $documentNode = $subgraph->findClosestNode($node->nodeAggregateId, FindClosestNodeFilter::create(nodeTypeConstraints: NodeTypeNameFactory::NAME_DOCUMENT)); + $documentNode = $subgraph->findClosestNode($node->nodeAggregateId, FindClosestNodeFilter::create(nodeTypes: NodeTypeNameFactory::NAME_DOCUMENT)); if ($documentNode instanceof Node) { $contentRepository = $this->contentRepositoryRegistry->get($documentNode->subgraphIdentity->contentRepositoryId); $nodeAddressFactory = NodeAddressFactory::create($contentRepository); diff --git a/Classes/Domain/Model/AbstractChange.php b/Classes/Domain/Model/AbstractChange.php index 62c877da2d..af92a52c74 100644 --- a/Classes/Domain/Model/AbstractChange.php +++ b/Classes/Domain/Model/AbstractChange.php @@ -67,7 +67,7 @@ protected function updateWorkspaceInfo(): void { if (!is_null($this->subject)) { $subgraph = $this->contentRepositoryRegistry->subgraphForNode($this->subject); - $documentNode = $subgraph->findClosestNode($this->subject->nodeAggregateId, FindClosestNodeFilter::create(nodeTypeConstraints: NodeTypeNameFactory::NAME_DOCUMENT)); + $documentNode = $subgraph->findClosestNode($this->subject->nodeAggregateId, FindClosestNodeFilter::create(nodeTypes: NodeTypeNameFactory::NAME_DOCUMENT)); if (!is_null($documentNode)) { $contentRepository = $this->contentRepositoryRegistry->get($this->subject->subgraphIdentity->contentRepositoryId); $workspace = $contentRepository->getWorkspaceFinder()->findOneByCurrentContentStreamId( diff --git a/Classes/Domain/Model/Changes/Remove.php b/Classes/Domain/Model/Changes/Remove.php index e58a98ff76..29987380dd 100644 --- a/Classes/Domain/Model/Changes/Remove.php +++ b/Classes/Domain/Model/Changes/Remove.php @@ -70,7 +70,7 @@ public function apply(): void $this->updateWorkspaceInfo(); $subgraph = $this->contentRepositoryRegistry->subgraphForNode($this->subject); - $closestDocumentParentNode = $subgraph->findClosestNode($this->subject->nodeAggregateId, FindClosestNodeFilter::create(nodeTypeConstraints: NodeTypeNameFactory::NAME_DOCUMENT)); + $closestDocumentParentNode = $subgraph->findClosestNode($this->subject->nodeAggregateId, FindClosestNodeFilter::create(nodeTypes: NodeTypeNameFactory::NAME_DOCUMENT)); $command = RemoveNodeAggregate::create( $subject->subgraphIdentity->contentStreamId, $subject->nodeAggregateId, diff --git a/Classes/Domain/Model/Feedback/Operations/ReloadDocument.php b/Classes/Domain/Model/Feedback/Operations/ReloadDocument.php index 039881587c..ee9651ee6b 100644 --- a/Classes/Domain/Model/Feedback/Operations/ReloadDocument.php +++ b/Classes/Domain/Model/Feedback/Operations/ReloadDocument.php @@ -73,7 +73,7 @@ public function serializePayload(ControllerContext $controllerContext): array $nodeInfoHelper = new NodeInfoHelper(); $documentNode = $this->contentRepositoryRegistry->subgraphForNode($this->node) - ->findClosestNode($this->node->nodeAggregateId, FindClosestNodeFilter::create(nodeTypeConstraints: NodeTypeNameFactory::NAME_DOCUMENT)); + ->findClosestNode($this->node->nodeAggregateId, FindClosestNodeFilter::create(nodeTypes: NodeTypeNameFactory::NAME_DOCUMENT)); if ($documentNode) { return [ From 08841c10ecb45463ac0455ea19d569dcf0c30435 Mon Sep 17 00:00:00 2001 From: Bernhard Schmitt Date: Mon, 30 Oct 2023 12:30:24 +0100 Subject: [PATCH 35/43] Take over out-of-band view declaration to the UI --- .../Operations/ReloadContentOutOfBand.php | 1 + .../Operations/RenderContentOutOfBand.php | 1 + Classes/View/OutOfBandRenderingCapable.php | 26 +++++++++++++++++ Classes/View/OutOfBandRenderingFusionView.php | 28 +++++++++++++++++++ .../OutOfBandRenderingViewFactory.php | 9 +++--- Configuration/Settings.yaml | 2 +- 6 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 Classes/View/OutOfBandRenderingCapable.php create mode 100644 Classes/View/OutOfBandRenderingFusionView.php rename Classes/{Domain/Model/Feedback/Operations => View}/OutOfBandRenderingViewFactory.php (83%) diff --git a/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php b/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php index 0243c8724f..019504574b 100644 --- a/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php +++ b/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php @@ -23,6 +23,7 @@ use Neos\Neos\Ui\Domain\Model\AbstractFeedback; use Neos\Neos\Ui\Domain\Model\FeedbackInterface; use Neos\Neos\Ui\Domain\Model\RenderedNodeDomAddress; +use Neos\Neos\Ui\View\OutOfBandRenderingViewFactory; use Psr\Http\Message\ResponseInterface; class ReloadContentOutOfBand extends AbstractFeedback diff --git a/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php b/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php index 3f6efd9652..d5714f8641 100644 --- a/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php +++ b/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php @@ -26,6 +26,7 @@ use Neos\Neos\Ui\Domain\Model\AbstractFeedback; use Neos\Neos\Ui\Domain\Model\FeedbackInterface; use Neos\Neos\Ui\Domain\Model\RenderedNodeDomAddress; +use Neos\Neos\Ui\View\OutOfBandRenderingViewFactory; use Psr\Http\Message\ResponseInterface; class RenderContentOutOfBand extends AbstractFeedback diff --git a/Classes/View/OutOfBandRenderingCapable.php b/Classes/View/OutOfBandRenderingCapable.php new file mode 100644 index 0000000000..31907e22b2 --- /dev/null +++ b/Classes/View/OutOfBandRenderingCapable.php @@ -0,0 +1,26 @@ +setFusionPath($renderingEntryPoint); + } +} diff --git a/Classes/Domain/Model/Feedback/Operations/OutOfBandRenderingViewFactory.php b/Classes/View/OutOfBandRenderingViewFactory.php similarity index 83% rename from Classes/Domain/Model/Feedback/Operations/OutOfBandRenderingViewFactory.php rename to Classes/View/OutOfBandRenderingViewFactory.php index cdeecd7e05..23f0620dc4 100644 --- a/Classes/Domain/Model/Feedback/Operations/OutOfBandRenderingViewFactory.php +++ b/Classes/View/OutOfBandRenderingViewFactory.php @@ -12,11 +12,10 @@ declare(strict_types=1); -namespace Neos\Neos\Ui\Domain\Model\Feedback\Operations; +namespace Neos\Neos\Ui\View; use Neos\Flow\Mvc\View\AbstractView; use Neos\Flow\Annotations as Flow; -use Neos\Neos\View\RenderingEntryPointAware; class OutOfBandRenderingViewFactory { @@ -26,7 +25,7 @@ class OutOfBandRenderingViewFactory #[Flow\InjectConfiguration(path: 'outOfBandRendering.viewObjectName')] protected string $viewObjectName; - public function resolveView(): AbstractView&RenderingEntryPointAware + public function resolveView(): AbstractView&OutOfBandRenderingCapable { if (!class_exists($this->viewObjectName)) { throw new \DomainException( @@ -42,9 +41,9 @@ public function resolveView(): AbstractView&RenderingEntryPointAware 1697821429 ); } - if (!$view instanceof RenderingEntryPointAware) { + if (!$view instanceof OutOfBandRenderingCapable) { throw new \DomainException( - 'Declared view (' . $this->viewObjectName . ') does not implement ' . RenderingEntryPointAware::class + 'Declared view (' . $this->viewObjectName . ') does not implement ' . OutOfBandRenderingCapable::class . ' required for out-of-band rendering', 1697821364 ); diff --git a/Configuration/Settings.yaml b/Configuration/Settings.yaml index 2d6b009589..414f5f4e77 100644 --- a/Configuration/Settings.yaml +++ b/Configuration/Settings.yaml @@ -192,7 +192,7 @@ Neos: 'Neos.Neos.Ui:MoveAfter': Neos\Neos\Ui\Domain\Model\Changes\MoveAfter 'Neos.Neos.Ui:MoveInto': Neos\Neos\Ui\Domain\Model\Changes\MoveInto outOfBandRendering: - viewObjectName: 'Neos\Neos\View\FusionView' + viewObjectName: 'Neos\Neos\Ui\View\OutOfBandRenderingFusionView' Flow: security: authentication: From 1e492465ab8f4b615ce77bf662b3a7a6a7af8bbb Mon Sep 17 00:00:00 2001 From: Bernhard Schmitt Date: Mon, 30 Oct 2023 12:40:38 +0100 Subject: [PATCH 36/43] 4622 - Catch view render results of unsupported type --- .../Model/Feedback/Operations/ReloadContentOutOfBand.php | 6 +++++- .../Model/Feedback/Operations/RenderContentOutOfBand.php | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php b/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php index 019504574b..ba1102a772 100644 --- a/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php +++ b/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php @@ -147,7 +147,11 @@ protected function renderContent(ControllerContext $controllerContext): string|R $view->assign('value', $this->node); $view->setRenderingEntryPoint($this->nodeDomAddress->getFusionPathForContentRendering()); - return $view->render(); + $result = $view->render(); + + return (is_string($result) || $result instanceof ResponseInterface) + ? $result + : ''; } } diff --git a/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php b/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php index d5714f8641..9737f78c5c 100644 --- a/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php +++ b/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php @@ -196,7 +196,11 @@ protected function renderContent(ControllerContext $controllerContext): string|R $view->assign('value', $parentNode); $view->setRenderingEntryPoint($parentDomAddress->getFusionPath()); - return $view->render(); + $result = $view->render(); + + return (is_string($result) || $result instanceof ResponseInterface) + ? $result + : ''; } } From 6f501c554f8eec7dcb71dcc3bdd8980db1390af1 Mon Sep 17 00:00:00 2001 From: Bernhard Schmitt Date: Mon, 30 Oct 2023 12:45:22 +0100 Subject: [PATCH 37/43] 4622 - make OutOfBandRenderingCapable more strict for render() --- .../Model/Feedback/Operations/ReloadContentOutOfBand.php | 6 +----- .../Model/Feedback/Operations/RenderContentOutOfBand.php | 6 +----- Classes/View/OutOfBandRenderingCapable.php | 4 ++++ 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php b/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php index ba1102a772..019504574b 100644 --- a/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php +++ b/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php @@ -147,11 +147,7 @@ protected function renderContent(ControllerContext $controllerContext): string|R $view->assign('value', $this->node); $view->setRenderingEntryPoint($this->nodeDomAddress->getFusionPathForContentRendering()); - $result = $view->render(); - - return (is_string($result) || $result instanceof ResponseInterface) - ? $result - : ''; + return $view->render(); } } diff --git a/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php b/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php index 9737f78c5c..d5714f8641 100644 --- a/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php +++ b/Classes/Domain/Model/Feedback/Operations/RenderContentOutOfBand.php @@ -196,11 +196,7 @@ protected function renderContent(ControllerContext $controllerContext): string|R $view->assign('value', $parentNode); $view->setRenderingEntryPoint($parentDomAddress->getFusionPath()); - $result = $view->render(); - - return (is_string($result) || $result instanceof ResponseInterface) - ? $result - : ''; + return $view->render(); } } diff --git a/Classes/View/OutOfBandRenderingCapable.php b/Classes/View/OutOfBandRenderingCapable.php index 31907e22b2..31cb7a5809 100644 --- a/Classes/View/OutOfBandRenderingCapable.php +++ b/Classes/View/OutOfBandRenderingCapable.php @@ -14,6 +14,8 @@ namespace Neos\Neos\Ui\View; +use Psr\Http\Message\ResponseInterface; + /** * The interface for views capable of out-of-band rendering by accepting string serialized entry points */ @@ -23,4 +25,6 @@ interface OutOfBandRenderingCapable * Set the rendering entry point, e.g. a Fusion path to use for rendering */ public function setRenderingEntryPoint(string $renderingEntryPoint): void; + + public function render(): string|ResponseInterface; } From 759ebd832e51909c2766a6bd209342306c002d78 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Mon, 30 Oct 2023 15:06:03 +0100 Subject: [PATCH 38/43] BUGFIX: Apply multiple properties from inspector --- Classes/Domain/Model/Feedback/Operations/UpdateNodeInfo.php | 2 +- Classes/Domain/Model/FeedbackCollection.php | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Classes/Domain/Model/Feedback/Operations/UpdateNodeInfo.php b/Classes/Domain/Model/Feedback/Operations/UpdateNodeInfo.php index a5093bac59..a7ee6a8eed 100644 --- a/Classes/Domain/Model/Feedback/Operations/UpdateNodeInfo.php +++ b/Classes/Domain/Model/Feedback/Operations/UpdateNodeInfo.php @@ -113,7 +113,7 @@ public function serializePayload(ControllerContext $controllerContext): array * * @return array> */ - public function serializeNodeRecursively(Node $node, ControllerContext $controllerContext): array + private function serializeNodeRecursively(Node $node, ControllerContext $controllerContext): array { $contentRepository = $this->contentRepositoryRegistry->get($node->subgraphIdentity->contentRepositoryId); $nodeAddressFactory = NodeAddressFactory::create($contentRepository); diff --git a/Classes/Domain/Model/FeedbackCollection.php b/Classes/Domain/Model/FeedbackCollection.php index 0857f1adbe..5f5a9dd9f7 100644 --- a/Classes/Domain/Model/FeedbackCollection.php +++ b/Classes/Domain/Model/FeedbackCollection.php @@ -48,8 +48,9 @@ public function setControllerContext(ControllerContext $controllerContext) */ public function add(FeedbackInterface $feedback) { - foreach ($this->feedbacks as $value) { - if ($value->isSimilarTo($feedback)) { + foreach ($this->feedbacks as $i => $value) { + if ($feedback->isSimilarTo($value)) { + $this->feedbacks[$i] = $feedback; return; } } From b489c7e76fe0c11ed1ee542ebb76d38bd2583376 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 31 Oct 2023 10:32:25 +0100 Subject: [PATCH 39/43] TASK: Remove Shortcut Override --- .../Private/Fusion/Prototypes/Shortcut.fusion | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 Resources/Private/Fusion/Prototypes/Shortcut.fusion diff --git a/Resources/Private/Fusion/Prototypes/Shortcut.fusion b/Resources/Private/Fusion/Prototypes/Shortcut.fusion deleted file mode 100644 index 23d36fe282..0000000000 --- a/Resources/Private/Fusion/Prototypes/Shortcut.fusion +++ /dev/null @@ -1,17 +0,0 @@ -prototype(Neos.Neos:Page) { - head { - shortcutCSS = Neos.Fusion:Tag { - @position = 'after guestFrameApplication' - - tagName = 'style' - content = Neos.Fusion:Value { - value = '#neos-shortcut {position: fixed;top: 0;left: 0;width: 100%;height: 100%;background-color: #323232;z-index: 9999;font-family: "Noto Sans", sans-serif;-webkit-font-smoothing: antialiased;}#neos-shortcut p {position: relative;margin: 0 auto;width: 500px;height: 60px;top: 50%;margin-top: -30px;color: #fff;font-size: 22px;line-height: 1.4;text-align: center;}#neos-shortcut p a {color: #00b5ff;text-decoration: none;}#neos-shortcut p a:hover {color: #39c6ff;}' - } - - @if { - inBackend = ${renderingMode.isEdit || renderingMode.isPreview} - isShortcut = ${q(node).is('[instanceof Neos.Neos:Shortcut]')} - } - } - } -} From 24daee6e4df89152cf34f7527f8f62be30bcdbd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Mu=CC=88ller?= Date: Tue, 31 Oct 2023 19:08:54 +0100 Subject: [PATCH 40/43] BUGFIX: Feedbacks have null defaults for optional properties This is necessary to avoid errors when the property was not initialized before access which happens in the current codebase and should be refactored completely. Fixes: #3655 --- Classes/Domain/Model/AbstractChange.php | 2 +- .../Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php | 2 +- Classes/Domain/Model/Feedback/Operations/ReloadDocument.php | 2 +- Classes/Domain/Model/Feedback/Operations/UpdateNodeInfo.php | 2 +- .../Domain/Model/Feedback/Operations/UpdateWorkspaceInfo.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Classes/Domain/Model/AbstractChange.php b/Classes/Domain/Model/AbstractChange.php index 62c877da2d..d81859d4e5 100644 --- a/Classes/Domain/Model/AbstractChange.php +++ b/Classes/Domain/Model/AbstractChange.php @@ -27,7 +27,7 @@ abstract class AbstractChange implements ChangeInterface { use NodeTypeWithFallbackProvider; - protected ?Node $subject; + protected ?Node $subject = null; #[Flow\Inject] protected ContentRepositoryRegistry $contentRepositoryRegistry; diff --git a/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php b/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php index 019504574b..8b8b5b900b 100644 --- a/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php +++ b/Classes/Domain/Model/Feedback/Operations/ReloadContentOutOfBand.php @@ -28,7 +28,7 @@ class ReloadContentOutOfBand extends AbstractFeedback { - protected ?Node $node; + protected ?Node $node = null; protected ?RenderedNodeDomAddress $nodeDomAddress; diff --git a/Classes/Domain/Model/Feedback/Operations/ReloadDocument.php b/Classes/Domain/Model/Feedback/Operations/ReloadDocument.php index 039881587c..addcf09cad 100644 --- a/Classes/Domain/Model/Feedback/Operations/ReloadDocument.php +++ b/Classes/Domain/Model/Feedback/Operations/ReloadDocument.php @@ -23,7 +23,7 @@ class ReloadDocument extends AbstractFeedback { - protected ?Node $node; + protected ?Node $node = null; #[Flow\Inject] protected ContentRepositoryRegistry $contentRepositoryRegistry; diff --git a/Classes/Domain/Model/Feedback/Operations/UpdateNodeInfo.php b/Classes/Domain/Model/Feedback/Operations/UpdateNodeInfo.php index a7ee6a8eed..27d363dec6 100644 --- a/Classes/Domain/Model/Feedback/Operations/UpdateNodeInfo.php +++ b/Classes/Domain/Model/Feedback/Operations/UpdateNodeInfo.php @@ -23,7 +23,7 @@ class UpdateNodeInfo extends AbstractFeedback { - protected ?Node $node; + protected ?Node $node = null; /** * @Flow\Inject diff --git a/Classes/Domain/Model/Feedback/Operations/UpdateWorkspaceInfo.php b/Classes/Domain/Model/Feedback/Operations/UpdateWorkspaceInfo.php index 86c190cc9e..2cdce7bb69 100644 --- a/Classes/Domain/Model/Feedback/Operations/UpdateWorkspaceInfo.php +++ b/Classes/Domain/Model/Feedback/Operations/UpdateWorkspaceInfo.php @@ -23,7 +23,7 @@ class UpdateWorkspaceInfo extends AbstractFeedback { - protected ?WorkspaceName $workspaceName; + protected ?WorkspaceName $workspaceName = null; /** * @Flow\Inject From 2e5cf50cd9e48b1eeecd9760326ebce9e4426560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anke=20H=C3=A4slich?= Date: Wed, 1 Nov 2023 11:05:58 +0100 Subject: [PATCH 41/43] BUGFIX: Add missing null defaults for optional properties --- Classes/Domain/Model/Changes/AbstractCreate.php | 2 +- Classes/Domain/Model/Changes/CopyInto.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/Domain/Model/Changes/AbstractCreate.php b/Classes/Domain/Model/Changes/AbstractCreate.php index 6ebae28193..c2278f8d3b 100644 --- a/Classes/Domain/Model/Changes/AbstractCreate.php +++ b/Classes/Domain/Model/Changes/AbstractCreate.php @@ -29,7 +29,7 @@ abstract class AbstractCreate extends AbstractStructuralChange /** * The type of the node that will be created */ - protected ?NodeTypeName $nodeTypeName; + protected ?NodeTypeName $nodeTypeName = null; /** * Incoming data from creationDialog diff --git a/Classes/Domain/Model/Changes/CopyInto.php b/Classes/Domain/Model/Changes/CopyInto.php index 56c4e55d5d..b0a37574d5 100644 --- a/Classes/Domain/Model/Changes/CopyInto.php +++ b/Classes/Domain/Model/Changes/CopyInto.php @@ -21,7 +21,7 @@ class CopyInto extends AbstractStructuralChange { protected ?string $parentContextPath; - protected ?Node $cachedParentNode; + protected ?Node $cachedParentNode = null; public function setParentContextPath(string $parentContextPath): void { From 5306eea28f490552cde663eeeb1f4a3fe1cc4190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anke=20H=C3=A4slich?= Date: Wed, 1 Nov 2023 17:36:28 +0100 Subject: [PATCH 42/43] TASK: Remove auto publishing feature --- Configuration/Settings.yaml | 1 - .../src/User/Settings/index.spec.js | 53 ------------------ .../src/User/Settings/index.ts | 56 ------------------- .../neos-ui-redux-store/src/User/index.ts | 5 +- packages/neos-ui-sagas/src/Changes/index.js | 13 +---- packages/neos-ui-sagas/src/Publish/index.js | 14 ----- packages/neos-ui-sagas/src/manifest.js | 1 - .../PrimaryToolbar/PublishDropDown/index.js | 45 +-------------- 8 files changed, 4 insertions(+), 184 deletions(-) delete mode 100644 packages/neos-ui-redux-store/src/User/Settings/index.spec.js delete mode 100644 packages/neos-ui-redux-store/src/User/Settings/index.ts diff --git a/Configuration/Settings.yaml b/Configuration/Settings.yaml index 414f5f4e77..a5aa25d1cf 100644 --- a/Configuration/Settings.yaml +++ b/Configuration/Settings.yaml @@ -176,7 +176,6 @@ Neos: preferences: interfaceLanguage: '${q(user).property(''preferences.interfaceLanguage'') || Configuration.setting(''Neos.Neos.userInterface.defaultLanguage'')}' settings: - isAutoPublishingEnabled: false targetWorkspace: 'live' changes: types: diff --git a/packages/neos-ui-redux-store/src/User/Settings/index.spec.js b/packages/neos-ui-redux-store/src/User/Settings/index.spec.js deleted file mode 100644 index a942bbc090..0000000000 --- a/packages/neos-ui-redux-store/src/User/Settings/index.spec.js +++ /dev/null @@ -1,53 +0,0 @@ -import {actionTypes, actions, reducer, defaultState} from './index'; -import {actionTypes as system} from '../../System/index'; - -test(`should export actionTypes`, () => { - expect(actionTypes).not.toBe(undefined); - expect(typeof (actionTypes.TOGGLE_AUTO_PUBLISHING)).toBe('string'); -}); - -test(`should export action creators`, () => { - expect(actions).not.toBe(undefined); - expect(typeof (actions.toggleAutoPublishing)).toBe('function'); -}); - -test(`should export a reducer`, () => { - expect(reducer).not.toBe(undefined); - expect(typeof (reducer)).toBe('function'); -}); - -test(`The reducer should return the default state when called with undefined.`, () => { - const nextState = reducer(undefined, { - type: 'unknown' - }); - - expect(nextState).toBe(defaultState); -}); - -test(`The reducer should correctly rehydrate data on INIT.`, () => { - const initValues = { - isAutoPublishingEnabled: true - }; - const nextState = reducer(undefined, { - type: system.INIT, - payload: { - user: { - settings: initValues - } - } - }); - expect(nextState).toEqual(initValues); -}); - -test(` - The "toggle" action should be able to reverse the value of the - "isAutoPublishingEnabled" key.`, () => { - const state = { - isAutoPublishingEnabled: false - }; - const nextState1 = reducer(state, actions.toggleAutoPublishing()); - const nextState2 = reducer(nextState1, actions.toggleAutoPublishing()); - - expect(nextState1.isAutoPublishingEnabled).toBe(true); - expect(nextState2.isAutoPublishingEnabled).toBe(false); -}); diff --git a/packages/neos-ui-redux-store/src/User/Settings/index.ts b/packages/neos-ui-redux-store/src/User/Settings/index.ts deleted file mode 100644 index 29cb79f778..0000000000 --- a/packages/neos-ui-redux-store/src/User/Settings/index.ts +++ /dev/null @@ -1,56 +0,0 @@ -import produce from 'immer'; -import {action as createAction, ActionType} from 'typesafe-actions'; - -import {actionTypes as system, InitAction} from '../../System'; - -// -// Export the subreducer state shape interface -// -export interface State extends Readonly<{ - isAutoPublishingEnabled: boolean; -}> {} - -export const defaultState: State = { - isAutoPublishingEnabled: false -}; - -// -// Export the action types -// -export enum actionTypes { - TOGGLE_AUTO_PUBLISHING = '@neos/neos-ui/User/Settings/TOGGLE_AUTO_PUBLISHING' -} - -// -// Export the actions -// -export const actions = { - /** - * Toggles the auto publishing mode for the current logged in user. - */ - toggleAutoPublishing: () => createAction(actionTypes.TOGGLE_AUTO_PUBLISHING) -}; - -// -// Export the union type of all actions -// -export type Action = ActionType; - -// -// Export the reducer -// -export const reducer = (state: State = defaultState, action: Action | InitAction) => produce(state, draft => { - switch (action.type) { - case system.INIT: - draft.isAutoPublishingEnabled = action.payload.user.settings.isAutoPublishingEnabled; - break; - case actionTypes.TOGGLE_AUTO_PUBLISHING: - draft.isAutoPublishingEnabled = !state.isAutoPublishingEnabled; - break; - } -}); - -// -// Export the selectors -// -export const selectors = {}; diff --git a/packages/neos-ui-redux-store/src/User/index.ts b/packages/neos-ui-redux-store/src/User/index.ts index 46b794a61f..fbe1d17a3c 100644 --- a/packages/neos-ui-redux-store/src/User/index.ts +++ b/packages/neos-ui-redux-store/src/User/index.ts @@ -1,17 +1,15 @@ import {combineReducers} from '../combineReducers'; -import * as Settings from './Settings'; import * as Preferences from './Preferences'; import * as Name from './Name'; import * as Impersonate from './Impersonate'; -const all = {Settings, Preferences, Name, Impersonate}; +const all = {Preferences, Name, Impersonate}; // // Export the subreducer state shape interface // export interface State { - settings: Settings.State; preferences: Preferences.State; name: Name.State; impersonate: Impersonate.State; @@ -35,7 +33,6 @@ export const actions = typedKeys(all).reduce((acc, cur) => ({...acc, [cur]: all[ // Export the reducer // export const reducer = combineReducers({ - settings: Settings.reducer, preferences: Preferences.reducer, name: Name.reducer, impersonate: Impersonate.reducer diff --git a/packages/neos-ui-sagas/src/Changes/index.js b/packages/neos-ui-sagas/src/Changes/index.js index 5bff7889d8..f0df377dfa 100644 --- a/packages/neos-ui-sagas/src/Changes/index.js +++ b/packages/neos-ui-sagas/src/Changes/index.js @@ -1,11 +1,9 @@ import {takeEvery, put, call, select} from 'redux-saga/effects'; import {$get} from 'plow-js'; -import {actionTypes, actions, selectors} from '@neos-project/neos-ui-redux-store'; +import {actionTypes, actions} from '@neos-project/neos-ui-redux-store'; import backend from '@neos-project/neos-ui-backend-connector'; -const {publishableNodesInDocumentSelector, baseWorkspaceSelector} = selectors.CR.Workspaces; - function * persistChanges(changes) { const {change} = backend.get().endpoints; @@ -14,15 +12,6 @@ function * persistChanges(changes) { try { const feedback = yield call(change, changes); yield put(actions.ServerFeedback.handleServerFeedback(feedback)); - - const state = yield select(); - const isAutoPublishingEnabled = $get('user.settings.isAutoPublishingEnabled', state); - - if (isAutoPublishingEnabled) { - const baseWorkspace = baseWorkspaceSelector(state); - const publishableNodesInDocument = publishableNodesInDocumentSelector(state); - yield put(actions.CR.Workspaces.publish(publishableNodesInDocument.map($get('contextPath')), baseWorkspace)); - } } catch (error) { console.error('Failed to persist changes', error); } finally { diff --git a/packages/neos-ui-sagas/src/Publish/index.js b/packages/neos-ui-sagas/src/Publish/index.js index 6822c2d301..e8a650d86e 100644 --- a/packages/neos-ui-sagas/src/Publish/index.js +++ b/packages/neos-ui-sagas/src/Publish/index.js @@ -5,8 +5,6 @@ import {actionTypes, actions, selectors} from '@neos-project/neos-ui-redux-store import backend from '@neos-project/neos-ui-backend-connector'; import {getGuestFrameDocument} from '@neos-project/neos-ui-guest-frame/src/dom'; -const {publishableNodesInDocumentSelector} = selectors.CR.Workspaces; - export function * watchPublish() { const {publish} = backend.get().endpoints; @@ -27,18 +25,6 @@ export function * watchPublish() { }); } -export function * watchToggleAutoPublish() { - yield takeEvery(actionTypes.User.Settings.TOGGLE_AUTO_PUBLISHING, function * publishInitially() { - const state = yield select(); - const isAutoPublishingEnabled = $get('user.settings.isAutoPublishingEnabled', state); - - if (isAutoPublishingEnabled) { - const publishableNodesInDocument = publishableNodesInDocumentSelector(state); - yield put(actions.CR.Workspaces.publish(publishableNodesInDocument.map($get('contextPath')), 'live')); - } - }); -} - export function * watchChangeBaseWorkspace() { const {changeBaseWorkspace} = backend.get().endpoints; yield takeEvery(actionTypes.CR.Workspaces.CHANGE_BASE_WORKSPACE, function * change(action) { diff --git a/packages/neos-ui-sagas/src/manifest.js b/packages/neos-ui-sagas/src/manifest.js index 6c88de7dfc..55cdfa564c 100644 --- a/packages/neos-ui-sagas/src/manifest.js +++ b/packages/neos-ui-sagas/src/manifest.js @@ -51,7 +51,6 @@ manifest('main.sagas', {}, globalRegistry => { sagasRegistry.set('neos-ui/Publish/watchChangeBaseWorkspace', {saga: publish.watchChangeBaseWorkspace}); sagasRegistry.set('neos-ui/Publish/discardIfConfirmed', {saga: publish.discardIfConfirmed}); sagasRegistry.set('neos-ui/Publish/watchPublish', {saga: publish.watchPublish}); - sagasRegistry.set('neos-ui/Publish/watchToggleAutoPublish', {saga: publish.watchToggleAutoPublish}); sagasRegistry.set('neos-ui/ServerFeedback/watchServerFeedback', {saga: serverFeedback.watchServerFeedback}); diff --git a/packages/neos-ui/src/Containers/PrimaryToolbar/PublishDropDown/index.js b/packages/neos-ui/src/Containers/PrimaryToolbar/PublishDropDown/index.js index aa39151dcc..c37151c371 100644 --- a/packages/neos-ui/src/Containers/PrimaryToolbar/PublishDropDown/index.js +++ b/packages/neos-ui/src/Containers/PrimaryToolbar/PublishDropDown/index.js @@ -7,8 +7,6 @@ import {$transform, $get} from 'plow-js'; import Badge from '@neos-project/react-ui-components/src/Badge/'; import Icon from '@neos-project/react-ui-components/src/Icon/'; -import CheckBox from '@neos-project/react-ui-components/src/CheckBox/'; -import Label from '@neos-project/react-ui-components/src/Label/'; import DropDown from '@neos-project/react-ui-components/src/DropDown/'; import I18n from '@neos-project/neos-ui-i18n'; @@ -29,10 +27,8 @@ import style from './style.module.css'; publishableNodesInDocument: publishableNodesInDocumentSelector, personalWorkspaceName: personalWorkspaceNameSelector, baseWorkspace: baseWorkspaceSelector, - isWorkspaceReadOnly: isWorkspaceReadOnlySelector, - isAutoPublishingEnabled: $get('user.settings.isAutoPublishingEnabled') + isWorkspaceReadOnly: isWorkspaceReadOnlySelector }), { - toggleAutoPublishing: actions.User.Settings.toggleAutoPublishing, changeBaseWorkspaceAction: actions.CR.Workspaces.changeBaseWorkspace, publishAction: actions.CR.Workspaces.publish, discardAction: actions.CR.Workspaces.commenceDiscard @@ -52,8 +48,6 @@ export default class PublishDropDown extends PureComponent { personalWorkspaceName: PropTypes.string.isRequired, baseWorkspace: PropTypes.string.isRequired, neos: PropTypes.object.isRequired, - isAutoPublishingEnabled: PropTypes.bool, - toggleAutoPublishing: PropTypes.func.isRequired, publishAction: PropTypes.func.isRequired, discardAction: PropTypes.func.isRequired, changeBaseWorkspaceAction: PropTypes.func.isRequired, @@ -92,9 +86,7 @@ export default class PublishDropDown extends PureComponent { isSaving, isPublishing, isDiscarding, - isAutoPublishingEnabled, isWorkspaceReadOnly, - toggleAutoPublishing, baseWorkspace, changeBaseWorkspaceAction, i18nRegistry, @@ -107,10 +99,6 @@ export default class PublishDropDown extends PureComponent { const canPublishLocally = !isSaving && !isPublishing && !isDiscarding && publishableNodesInDocument && (publishableNodesInDocument.length > 0); const canPublishGlobally = !isSaving && !isPublishing && !isDiscarding && publishableNodes && (publishableNodes.length > 0); const changingWorkspaceAllowed = !canPublishGlobally; - const autoPublishWrapperClassNames = mergeClassNames({ - [style.dropDown__item]: true, - [style['dropDown__item--noHover']]: true - }); const mainButton = this.getTranslatedMainButton(baseWorkspaceTitle); const dropDownBtnClassName = mergeClassNames({ [style.dropDown__btn]: true, @@ -213,27 +201,6 @@ export default class PublishDropDown extends PureComponent { )} -
  • - { - /** - PLEASE NOTE: this additional styleClass is a fix, because react checkboxes inside a react select component are buggy, - for further information see https://github.com/neos/neos-ui/pull/3211 - */ - } - -
  • @@ -253,8 +220,7 @@ export default class PublishDropDown extends PureComponent { publishableNodesInDocument, isSaving, isPublishing, - isDiscarding, - isAutoPublishingEnabled + isDiscarding } = this.props; const canPublishLocally = publishableNodesInDocument && (publishableNodesInDocument.length > 0); @@ -270,13 +236,6 @@ export default class PublishDropDown extends PureComponent { return 'Discarding...'; } - if (isAutoPublishingEnabled) { - if (baseWorkspaceTitle) { - return ; - } - return ; - } - if (canPublishLocally) { return ; } From 15457773c75fed41f86e840face27ac7b31f6835 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Tue, 7 Nov 2023 16:00:12 +0000 Subject: [PATCH 43/43] Updating composer dependency and npm versions for release of 9.0.0-beta1 --- package.json | 5 +++-- packages/debug-reason-for-rendering/package.json | 5 +++-- packages/jest-preset-neos-ui/package.json | 5 +++-- packages/neos-ts-interfaces/package.json | 5 +++-- packages/neos-ui-backend-connector/package.json | 5 +++-- packages/neos-ui-build/package.json | 5 +++-- packages/neos-ui-ckeditor5-bindings/package.json | 5 +++-- packages/neos-ui-constants/package.json | 5 +++-- packages/neos-ui-containers/package.json | 5 +++-- packages/neos-ui-contentrepository/package.json | 5 +++-- packages/neos-ui-decorators/package.json | 5 +++-- packages/neos-ui-editors/package.json | 5 +++-- packages/neos-ui-extensibility-webpack-adapter/package.json | 5 +++-- packages/neos-ui-extensibility/package.json | 5 +++-- packages/neos-ui-guest-frame/package.json | 5 +++-- packages/neos-ui-i18n/package.json | 5 +++-- packages/neos-ui-inspector/package.json | 5 +++-- packages/neos-ui-redux-store/package.json | 5 +++-- packages/neos-ui-sagas/package.json | 5 +++-- packages/neos-ui-validators/package.json | 5 +++-- packages/neos-ui-views/package.json | 5 +++-- packages/neos-ui/package.json | 5 +++-- packages/positional-array-sorter/package.json | 5 +++-- packages/react-proptypes/package.json | 5 +++-- packages/react-ui-components/package.json | 5 +++-- packages/utils-helpers/package.json | 5 +++-- packages/utils-logger/package.json | 5 +++-- packages/utils-redux/package.json | 5 +++-- 28 files changed, 84 insertions(+), 56 deletions(-) diff --git a/package.json b/package.json index 6c18551057..dc344929a3 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "bugs": "https://github.com/neos/neos-ui/issues", "homepage": "https://github.com/neos/neos-ui/blob/master/README.md", "license": "GNU GPLv3", - "version": "8.3.4", + "version": "9.0.0-beta1", "private": true, "resolutions": { "moment": "^2.20.1", @@ -44,5 +44,6 @@ "jest": { "preset": "@neos-project/jest-preset-neos-ui" }, - "packageManager": "yarn@3.2.0" + "packageManager": "yarn@3.2.0", + "stableVersion": "8.3.4" } diff --git a/packages/debug-reason-for-rendering/package.json b/packages/debug-reason-for-rendering/package.json index d2f110a7e7..44afe5e013 100644 --- a/packages/debug-reason-for-rendering/package.json +++ b/packages/debug-reason-for-rendering/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/debug-reason-for-rendering", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "React Performance Optimization Utility - Why does a component re-render?", "repository": "neos/neos-ui", "bugs": "https://github.com/neos/neos-ui/issues", @@ -9,5 +9,6 @@ "license": "MIT", "peerDependencies": { "react": "^16.12.0" - } + }, + "stableVersion": "8.3.4" } diff --git a/packages/jest-preset-neos-ui/package.json b/packages/jest-preset-neos-ui/package.json index 2388681ee4..a4e280691c 100644 --- a/packages/jest-preset-neos-ui/package.json +++ b/packages/jest-preset-neos-ui/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/jest-preset-neos-ui", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "The jest preset for all packages of the neos-ui mono-repo.", "main": "jest-preset.json", "private": true, @@ -13,5 +13,6 @@ "peerDependencies": { "enzyme": "^3.8.0" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/neos-ts-interfaces/package.json b/packages/neos-ts-interfaces/package.json index c3f0c72c88..614e1ccefd 100644 --- a/packages/neos-ts-interfaces/package.json +++ b/packages/neos-ts-interfaces/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ts-interfaces", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Neos domain-related TypeScript interfaces", "private": true, "main": "src/index.ts", @@ -9,5 +9,6 @@ "@neos-project/neos-ui-build": "workspace:*", "typescript": "^4.6.4" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui-backend-connector/package.json b/packages/neos-ui-backend-connector/package.json index 13c30d9e43..ffb8724b82 100644 --- a/packages/neos-ui-backend-connector/package.json +++ b/packages/neos-ui-backend-connector/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ui-backend-connector", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Endoints and fetch cals to the Neos CMS backend", "private": true, "main": "./src/index.ts", @@ -13,5 +13,6 @@ "@neos-project/utils-helpers": "workspace:*", "plow-js": "3.0.0" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui-build/package.json b/packages/neos-ui-build/package.json index f586002fdc..f480a7aac1 100644 --- a/packages/neos-ui-build/package.json +++ b/packages/neos-ui-build/package.json @@ -1,6 +1,7 @@ { "name": "@neos-project/neos-ui-build", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Bob der Baumeister", - "private": true + "private": true, + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui-ckeditor5-bindings/package.json b/packages/neos-ui-ckeditor5-bindings/package.json index 8ee6deb1fe..e7097d92b6 100644 --- a/packages/neos-ui-ckeditor5-bindings/package.json +++ b/packages/neos-ui-ckeditor5-bindings/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ui-ckeditor5-bindings", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Prepare CKEditor5 for the Neos CMS UI", "private": true, "main": "./src/manifest.js", @@ -35,5 +35,6 @@ "react": "^16.12.0", "react-redux": "^7.1.3" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui-constants/package.json b/packages/neos-ui-constants/package.json index 482dc85a0e..a377286493 100644 --- a/packages/neos-ui-constants/package.json +++ b/packages/neos-ui-constants/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ui-constants", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Container package to store Neos CMS UI constants", "private": true, "main": "./src/index.js", @@ -8,5 +8,6 @@ "@neos-project/jest-preset-neos-ui": "workspace:*", "typescript": "^4.6.4" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui-containers/package.json b/packages/neos-ui-containers/package.json index c073cff79d..904ae9728d 100644 --- a/packages/neos-ui-containers/package.json +++ b/packages/neos-ui-containers/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ui-containers", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Smart components for Neos CMS UI.", "private": true, "main": "./src/index.js", @@ -18,5 +18,6 @@ "prop-types": "^15.5.10", "react": "^16.12.0" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui-contentrepository/package.json b/packages/neos-ui-contentrepository/package.json index 6d6470bd8f..da9f89973b 100644 --- a/packages/neos-ui-contentrepository/package.json +++ b/packages/neos-ui-contentrepository/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ui-contentrepository", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Bindings for the Neos ContentRepository", "private": true, "main": "./src/manifest.js", @@ -22,5 +22,6 @@ "setupFiles": [ "../jest-preset-neos-ui/src/setupNeosUiHostEnv.js" ] - } + }, + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui-decorators/package.json b/packages/neos-ui-decorators/package.json index c46f5f96ca..62c6b2bb20 100644 --- a/packages/neos-ui-decorators/package.json +++ b/packages/neos-ui-decorators/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ui-decorators", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Decorators for Neos CMS UI.", "private": true, "main": "./src/index.ts", @@ -16,5 +16,6 @@ "@neos-project/neos-ts-interfaces": "workspace:*", "reselect": "^3.0.1" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui-editors/package.json b/packages/neos-ui-editors/package.json index 490d32442f..e0827ab6f0 100644 --- a/packages/neos-ui-editors/package.json +++ b/packages/neos-ui-editors/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ui-editors", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Neos CMS UI Editors for use in the inspector.", "main": "src/manifest.js", "private": true, @@ -42,5 +42,6 @@ "react-redux": "^7.1.3", "redux": "^4.0.5" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui-extensibility-webpack-adapter/package.json b/packages/neos-ui-extensibility-webpack-adapter/package.json index 28ad74adca..3dac6bfc71 100644 --- a/packages/neos-ui-extensibility-webpack-adapter/package.json +++ b/packages/neos-ui-extensibility-webpack-adapter/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ui-extensibility-webpack-adapter", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Minimal configuration, highly opinionated Webpack 4 + Babel plugin build stack for the Neos CMS UI", "repository": "neos/neos-ui", "bugs": "https://github.com/neos/neos-ui/issues", @@ -36,5 +36,6 @@ "babel-core": "^6.26.3", "typescript": "^4.6.4" } - } + }, + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui-extensibility/package.json b/packages/neos-ui-extensibility/package.json index 9af380ef96..969e1cac71 100644 --- a/packages/neos-ui-extensibility/package.json +++ b/packages/neos-ui-extensibility/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ui-extensibility", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Core of the extensibility mechanisms for the Neos UI", "repository": "neos/neos-ui", "bugs": "https://github.com/neos/neos-ui/issues", @@ -22,5 +22,6 @@ }, "dependencies": { "@neos-project/positional-array-sorter": "workspace:*" - } + }, + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui-guest-frame/package.json b/packages/neos-ui-guest-frame/package.json index 7980490de1..5c363cba12 100644 --- a/packages/neos-ui-guest-frame/package.json +++ b/packages/neos-ui-guest-frame/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ui-guest-frame", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Guest frame initialization bindings", "private": true, "main": "./src/manifest.js", @@ -29,5 +29,6 @@ "react": "^16.12.0", "react-redux": "^7.1.3" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui-i18n/package.json b/packages/neos-ui-i18n/package.json index 2f14a04980..c9b6b766fc 100644 --- a/packages/neos-ui-i18n/package.json +++ b/packages/neos-ui-i18n/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ui-i18n", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "I18n utilities and components for Neos CMS UI.", "private": true, "main": "./src/index.tsx", @@ -18,5 +18,6 @@ "peerDependencies": { "react": "^16.12.0" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui-inspector/package.json b/packages/neos-ui-inspector/package.json index 3e165105b5..f34bbeb6eb 100644 --- a/packages/neos-ui-inspector/package.json +++ b/packages/neos-ui-inspector/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ui-inspector", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Components for integrating views and editors into the Neos CMS UI inspector.", "private": true, "main": "./src/index.js", @@ -20,5 +20,6 @@ "react": "^16.12.0", "react-redux": "^7.1.3" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui-redux-store/package.json b/packages/neos-ui-redux-store/package.json index 88e8a07850..7a7f188c1b 100644 --- a/packages/neos-ui-redux-store/package.json +++ b/packages/neos-ui-redux-store/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ui-redux-store", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Redux store implementation for the Neos CMS UI", "private": true, "main": "./src/index.ts", @@ -20,5 +20,6 @@ "reselect": "^3.0.1", "typesafe-actions": "^5.1.0" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui-sagas/package.json b/packages/neos-ui-sagas/package.json index b719b11116..ae979ac863 100644 --- a/packages/neos-ui-sagas/package.json +++ b/packages/neos-ui-sagas/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ui-sagas", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Redux Sagas implementation for the Neos CMS UI", "private": true, "main": "src/index.js", @@ -19,5 +19,6 @@ "plow-js": "3.0.0", "redux-saga": "^0.15.0" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui-validators/package.json b/packages/neos-ui-validators/package.json index 3b9c64be65..3614411507 100644 --- a/packages/neos-ui-validators/package.json +++ b/packages/neos-ui-validators/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ui-validators", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Validators for Neos CMS UI.", "private": true, "main": "./src/index.ts", @@ -19,5 +19,6 @@ "peerDependencies": { "react": "^16.12.0" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui-views/package.json b/packages/neos-ui-views/package.json index 269104bff9..837a24dfbf 100644 --- a/packages/neos-ui-views/package.json +++ b/packages/neos-ui-views/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ui-views", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Neos CMS UI Views for use in the inspector.", "main": "./src/index.js", "private": true, @@ -27,5 +27,6 @@ "react": "^16.12.0", "react-redux": "^7.1.3" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/neos-ui/package.json b/packages/neos-ui/package.json index 661b1d07ad..378dcf1568 100644 --- a/packages/neos-ui/package.json +++ b/packages/neos-ui/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/neos-ui", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Neos CMS UI written in ReactJS and a ton of other fun technology.", "private": true, "devDependencies": { @@ -66,5 +66,6 @@ "reselect": "^3.0.1", "uuid": "^3.3.2" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/positional-array-sorter/package.json b/packages/positional-array-sorter/package.json index 320363e5d7..93d98b9049 100644 --- a/packages/positional-array-sorter/package.json +++ b/packages/positional-array-sorter/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/positional-array-sorter", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Flexible array sorter that sorts an array according to a 'position' meta data.", "repository": "neos/neos-ui", "bugs": "https://github.com/neos/neos-ui/issues", @@ -19,5 +19,6 @@ "devDependencies": { "@neos-project/jest-preset-neos-ui": "workspace:*", "typescript": "^4.6.4" - } + }, + "stableVersion": "8.3.4" } diff --git a/packages/react-proptypes/package.json b/packages/react-proptypes/package.json index 1c1c2cf16a..3f49b9ecee 100644 --- a/packages/react-proptypes/package.json +++ b/packages/react-proptypes/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/react-proptypes", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Neos CMS specific proptypes for react", "private": true, "main": "./src/index.js", @@ -11,5 +11,6 @@ "peerDependencies": { "prop-types": "^15.5.10" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/react-ui-components/package.json b/packages/react-ui-components/package.json index 811545dbcb..534ea88d4f 100644 --- a/packages/react-ui-components/package.json +++ b/packages/react-ui-components/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/react-ui-components", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "The UI components which power the Neos backend application.", "repository": "neos/neos-ui", "bugs": "https://github.com/neos/neos-ui/issues", @@ -96,5 +96,6 @@ "stylelint": "^13.7.2", "typescript": "^4.6.0" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/utils-helpers/package.json b/packages/utils-helpers/package.json index 7553008d7d..b54c4c061b 100644 --- a/packages/utils-helpers/package.json +++ b/packages/utils-helpers/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/utils-helpers", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Helper functions for Neos CMS UI.", "private": true, "main": "./src/index.ts", @@ -11,5 +11,6 @@ "@neos-project/jest-preset-neos-ui": "workspace:*", "typescript": "^4.6.4" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/utils-logger/package.json b/packages/utils-logger/package.json index 9a812f3d29..5dbfd12ab9 100644 --- a/packages/utils-logger/package.json +++ b/packages/utils-logger/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/utils-logger", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Logger implementation for Neos CMS UI.", "private": true, "main": "./src/index.ts", @@ -11,5 +11,6 @@ "@neos-project/jest-preset-neos-ui": "workspace:*", "typescript": "^4.6.4" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" } diff --git a/packages/utils-redux/package.json b/packages/utils-redux/package.json index f057146f59..6f6fcd3dee 100644 --- a/packages/utils-redux/package.json +++ b/packages/utils-redux/package.json @@ -1,6 +1,6 @@ { "name": "@neos-project/utils-redux", - "version": "8.3.4", + "version": "9.0.0-beta1", "description": "Neos CMS UI Redux Helper utilitites", "private": true, "main": "./src/index.ts", @@ -8,5 +8,6 @@ "@neos-project/jest-preset-neos-ui": "workspace:*", "typescript": "^4.6.4" }, - "license": "GNU GPLv3" + "license": "GNU GPLv3", + "stableVersion": "8.3.4" }