diff --git a/Classes/Domain/NodeCreation/NodeCreationElements.php b/Classes/Domain/NodeCreation/NodeCreationElements.php index 8148c2112f..b89d29ac58 100644 --- a/Classes/Domain/NodeCreation/NodeCreationElements.php +++ b/Classes/Domain/NodeCreation/NodeCreationElements.php @@ -46,6 +46,10 @@ * type: string * ui: * showInCreationDialog: true + * references: + * myReferences: + * ui: + * showInCreationDialog: true * * @implements \IteratorAggregate * @internal Especially the constructor and the serialized data diff --git a/Classes/Infrastructure/ContentRepository/CreationDialog/CreationDialogNodeTypePostprocessor.php b/Classes/Infrastructure/ContentRepository/CreationDialog/CreationDialogNodeTypePostprocessor.php index d0edd45d52..3d92d1de50 100644 --- a/Classes/Infrastructure/ContentRepository/CreationDialog/CreationDialogNodeTypePostprocessor.php +++ b/Classes/Infrastructure/ContentRepository/CreationDialog/CreationDialogNodeTypePostprocessor.php @@ -17,6 +17,7 @@ use Neos\ContentRepository\Core\NodeType\NodeType; use Neos\ContentRepository\Core\NodeType\NodeTypePostprocessorInterface; use Neos\Flow\Annotations as Flow; +use Neos\Neos\Ui\Domain\NodeCreation\NodeCreationElements; use Neos\Utility\Arrays; use Neos\Utility\PositionalArraySorter; @@ -88,10 +89,14 @@ public function process(NodeType $nodeType, array &$configuration, array $option { $creationDialogElements = $configuration['ui']['creationDialog']['elements'] ?? []; - if (!empty($configuration['properties'] ?? null)) { + if (!empty($configuration['properties'])) { $creationDialogElements = $this->promotePropertiesIntoCreationDialog($configuration['properties'], $creationDialogElements); } + if (!empty($configuration['references'])) { + $creationDialogElements = $this->promoteReferencesIntoCreationDialog($configuration['references'], $creationDialogElements); + } + $this->mergeDefaultCreationDialogElementEditors($creationDialogElements); if ($creationDialogElements !== []) { @@ -224,4 +229,74 @@ private function promotePropertyIntoCreationDialog(string $propertyName, array $ $convertedConfiguration['ui']['editorOptions'] = $editorOptions; return $convertedConfiguration; } + + /** + * @param array $references + * @param array $explicitCreationDialogElements + * @return array + */ + private function promoteReferencesIntoCreationDialog(array $references, array $explicitCreationDialogElements): array + { + foreach ($references as $referenceName => $referenceConfiguration) { + if ( + !isset($referenceConfiguration['ui']['showInCreationDialog']) + || $referenceConfiguration['ui']['showInCreationDialog'] !== true + ) { + continue; + } + + $creationDialogElement = $this->promoteReferenceIntoCreationDialog($referenceConfiguration); + if (isset($explicitCreationDialogElements[$referenceName])) { + $creationDialogElement = Arrays::arrayMergeRecursiveOverrule( + $creationDialogElement, + $explicitCreationDialogElements[$referenceName] + ); + } + $explicitCreationDialogElements[$referenceName] = $creationDialogElement; + } + return $explicitCreationDialogElements; + } + + /** + * Converts a NodeType reference configuration to the corresponding creationDialog "element" configuration + * + * @param array $referenceConfiguration + * @return array + */ + private function promoteReferenceIntoCreationDialog(array $referenceConfiguration): array + { + $maxAllowedItems = $referenceConfiguration['constraints']['maxItems'] ?? null; + $referenceMagicType = $maxAllowedItems === 1 ? 'reference' : 'references'; + /** + * For references, we add this magic type to the elements configuration {@see NodeCreationElements} + */ + $convertedConfiguration = [ + 'type' => $referenceMagicType, + ]; + if (isset($referenceConfiguration['ui']['label'])) { + $convertedConfiguration['ui']['label'] = $referenceConfiguration['ui']['label']; + } + if (isset($referenceConfiguration['defaultValue'])) { + $convertedConfiguration['defaultValue'] = $referenceConfiguration['defaultValue']; + } + if (isset($referenceConfiguration['ui']['help'])) { + $convertedConfiguration['ui']['help'] = $referenceConfiguration['ui']['help']; + } + if (isset($referenceConfiguration['ui']['inspector']['position'])) { + $convertedConfiguration['position'] = $referenceConfiguration['ui']['inspector']['position']; + } + if (isset($referenceConfiguration['ui']['inspector']['hidden'])) { + $convertedConfiguration['ui']['hidden'] = $referenceConfiguration['ui']['inspector']['hidden']; + } + /** + * the editor will be set based on the type above via {@see self::mergeDefaultCreationDialogElementEditors} + */ + if (isset($referenceConfiguration['ui']['inspector']['editor'])) { + $convertedConfiguration['ui']['editor'] = $referenceConfiguration['ui']['inspector']['editor']; + } + if (isset($referenceConfiguration['ui']['inspector']['editorOptions'])) { + $convertedConfiguration['ui']['editorOptions'] = $referenceConfiguration['ui']['inspector']['editorOptions']; + } + return $convertedConfiguration; + } } diff --git a/Tests/Unit/CreationDialogNodeTypePostprocessorTest.php b/Tests/Unit/CreationDialogNodeTypePostprocessorTest.php index d09de2d2bc..b5f19d3ced 100644 --- a/Tests/Unit/CreationDialogNodeTypePostprocessorTest.php +++ b/Tests/Unit/CreationDialogNodeTypePostprocessorTest.php @@ -7,9 +7,72 @@ use Neos\Flow\Tests\UnitTestCase; use Neos\Neos\NodeTypePostprocessor\DefaultPropertyEditorPostprocessor; use Neos\Neos\Ui\Infrastructure\ContentRepository\CreationDialog\CreationDialogNodeTypePostprocessor; +use Symfony\Component\Yaml\Yaml; class CreationDialogNodeTypePostprocessorTest extends UnitTestCase { + public function examples(): iterable + { + yield 'multiple references' => [ + 'nodeTypeDefinition' => <<<'YAML' + references: + someReferences: + ui: + showInCreationDialog: true + YAML, + 'expectedCreationDialog' => <<<'YAML' + elements: + someReferences: + type: references + ui: + editor: ReferencesEditor + YAML + ]; + + yield 'singular reference' => [ + 'nodeTypeDefinition' => <<<'YAML' + references: + someReference: + constraints: + maxItems: 1 + ui: + showInCreationDialog: true + YAML, + 'expectedCreationDialog' => <<<'YAML' + elements: + someReference: + type: reference + ui: + editor: SingularReferenceEditor + YAML + ]; + } + + /** + * @test + * @dataProvider examples + */ + public function processExamples(string $nodeTypeDefinition, string $expectedCreationDialog) + { + $configuration = array_merge([ + 'references' => [], + 'properties' => [] + ], Yaml::parse($nodeTypeDefinition)); + + $dataTypesDefaultConfiguration = [ + 'reference' => [ + 'editor' => 'SingularReferenceEditor', + ], + 'references' => [ + 'editor' => 'ReferencesEditor', + ], + ]; + + $result = $this->processConfigurationFully($configuration, $dataTypesDefaultConfiguration, []); + + self::assertEquals(Yaml::parse($expectedCreationDialog), $result['ui']['creationDialog'] ?? null); + } + /** * promoted elements (showInCreationDialog: true) *