diff --git a/Neos.ContentRepository.Core/Classes/NodeType/NodeType.php b/Neos.ContentRepository.Core/Classes/NodeType/NodeType.php index 8684aed30a3..4775254218c 100644 --- a/Neos.ContentRepository.Core/Classes/NodeType/NodeType.php +++ b/Neos.ContentRepository.Core/Classes/NodeType/NodeType.php @@ -152,6 +152,11 @@ protected function buildFullConfiguration(): array } $this->fullConfiguration = Arrays::arrayMergeRecursiveOverrule($mergedConfiguration, $this->localConfiguration); + // Remove unset properties + $this->fullConfiguration['properties'] = array_filter($this->fullConfiguration['properties'] ?? [], function ($propertyConfiguration) { + return $propertyConfiguration !== null; + }); + if ( isset($this->fullConfiguration['childNodes']) && is_array($this->fullConfiguration['childNodes']) diff --git a/Neos.ContentRepository.Core/Classes/NodeType/NodeTypeManager.php b/Neos.ContentRepository.Core/Classes/NodeType/NodeTypeManager.php index 9fa0f00408b..68051eab5fd 100644 --- a/Neos.ContentRepository.Core/Classes/NodeType/NodeTypeManager.php +++ b/Neos.ContentRepository.Core/Classes/NodeType/NodeTypeManager.php @@ -220,20 +220,6 @@ protected function loadNodeType(string $nodeTypeName, array &$completeNodeTypeCo ); } - // Remove unset properties - $properties = []; - if (isset($nodeTypeConfiguration['properties']) && is_array($nodeTypeConfiguration['properties'])) { - $properties = $nodeTypeConfiguration['properties']; - } - - $nodeTypeConfiguration['properties'] = array_filter($properties, function ($propertyConfiguration) { - return $propertyConfiguration !== null; - }); - - if ($nodeTypeConfiguration['properties'] === []) { - unset($nodeTypeConfiguration['properties']); - } - $nodeType = new NodeType( NodeTypeName::fromString($nodeTypeName), $superTypes, diff --git a/Neos.ContentRepository.Core/Tests/Unit/NodeType/NodeTypeManagerTest.php b/Neos.ContentRepository.Core/Tests/Unit/NodeType/NodeTypeManagerTest.php index 60dfb8741bd..8f41b22d4f8 100644 --- a/Neos.ContentRepository.Core/Tests/Unit/NodeType/NodeTypeManagerTest.php +++ b/Neos.ContentRepository.Core/Tests/Unit/NodeType/NodeTypeManagerTest.php @@ -312,7 +312,6 @@ public function arraySupertypesFormatThrowsException() $this->expectException(NodeConfigurationException::class); $nodeTypesFixture = [ 'Neos.ContentRepository.Testing:Base' => [ - 'final' => true ], 'Neos.ContentRepository.Testing:Sub' => [ 'superTypes' => [0 => 'Neos.ContentRepository.Testing:Base'] @@ -335,4 +334,92 @@ public function getSubNodeTypesWithDifferentIncludeFlagValuesReturnsCorrectValue $subNodeTypes = $this->nodeTypeManager->getSubNodeTypes('Neos.ContentRepository.Testing:ContentObject', false); self::assertArrayNotHasKey('Neos.ContentRepository.Testing:AbstractType', $subNodeTypes); } + + /** + * @test + */ + public function anInheritedNodeTypePropertyCanBeUnset(): void + { + $nodeTypesFixture = [ + 'Neos.ContentRepository.Testing:Base' => [ + 'properties' => [ + 'foo' => [ + 'type' => 'boolean', + ] + ] + ], + 'Neos.ContentRepository.Testing:Sub' => [ + 'superTypes' => ['Neos.ContentRepository.Testing:Base' => true], + 'properties' => [ + 'foo' => null + ] + ] + ]; + + $this->prepareNodeTypeManager($nodeTypesFixture); + $nodeType = $this->nodeTypeManager->getNodeType('Neos.ContentRepository.Testing:Sub'); + + self::assertSame([], $nodeType->getProperties()); + } + + /** + * @test + */ + public function allInheritedNodeTypePropertiesCanBeUnset(): void + { + $nodeTypesFixture = [ + 'Neos.ContentRepository.Testing:Base' => [ + 'properties' => [ + 'foo' => [ + 'type' => 'boolean', + ] + ] + ], + 'Neos.ContentRepository.Testing:Sub' => [ + 'superTypes' => ['Neos.ContentRepository.Testing:Base' => true], + 'properties' => null + ] + ]; + + $this->prepareNodeTypeManager($nodeTypesFixture); + $nodeType = $this->nodeTypeManager->getNodeType('Neos.ContentRepository.Testing:Sub'); + + self::assertSame([], $nodeType->getProperties()); + } + + /** + * @test + */ + public function anInheritedNodeTypePropertyCannotBeSetToEmptyArray(): void + { + $nodeTypesFixture = [ + 'Neos.ContentRepository.Testing:Base' => [ + 'properties' => [ + 'foo' => [ + 'type' => 'boolean', + 'ui' => [ + 'inspector' => [ + 'group' => 'things' + ] + ] + ] + ] + ], + 'Neos.ContentRepository.Testing:Sub' => [ + 'superTypes' => ['Neos.ContentRepository.Testing:Base' => true], + 'properties' => [ + // Pseudo unset. + // The property will still be existent but looses its type information (falls back to string). + // Also, the property will not show up anymore in the ui as the inspector configuration is gone as well. + 'foo' => [] + ] + ] + ]; + + $this->prepareNodeTypeManager($nodeTypesFixture); + $nodeType = $this->nodeTypeManager->getNodeType('Neos.ContentRepository.Testing:Sub'); + + self::assertSame(['foo' => []], $nodeType->getProperties()); + self::assertSame('string', $nodeType->getPropertyType('foo')); + } }