Skip to content

Commit

Permalink
TASK: Allow promoting new references into creation dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
mhsdesign committed Apr 6, 2024
1 parent 3d8dcaa commit 4558a71
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 1 deletion.
4 changes: 4 additions & 0 deletions Classes/Domain/NodeCreation/NodeCreationElements.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
* type: string
* ui:
* showInCreationDialog: true
* references:
* myReferences:
* ui:
* showInCreationDialog: true
*
* @implements \IteratorAggregate<string, mixed>
* @internal Especially the constructor and the serialized data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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 !== []) {
Expand Down Expand Up @@ -224,4 +229,74 @@ private function promotePropertyIntoCreationDialog(string $propertyName, array $
$convertedConfiguration['ui']['editorOptions'] = $editorOptions;
return $convertedConfiguration;
}

/**
* @param array<string, mixed> $references
* @param array<string, mixed> $explicitCreationDialogElements
* @return array<string, mixed>
*/
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<string,mixed> $referenceConfiguration
* @return array<string,mixed>
*/
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'];
}
/**
* we require the `editor` to be already set by the {@see DefaultPropertyEditorPostprocessor}
*/
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;
}
}
63 changes: 63 additions & 0 deletions Tests/Unit/CreationDialogNodeTypePostprocessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
*
Expand Down

0 comments on commit 4558a71

Please sign in to comment.