Skip to content

Commit 50d6e20

Browse files
mhsdesignmarkusguenther
authored andcommitted
TASK: Adjust to split up references and properties
1 parent 112813d commit 50d6e20

File tree

5 files changed

+64
-80
lines changed

5 files changed

+64
-80
lines changed

Classes/Domain/Model/Changes/Property.php

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,8 @@ public function canApply(): bool
134134
}
135135
$nodeType = $this->subject->nodeType;
136136
$propertyName = $this->getPropertyName();
137-
$nodeTypeProperties = $nodeType->getProperties();
138137

139-
return isset($nodeTypeProperties[$propertyName]);
138+
return $nodeType->hasProperty($propertyName) || $nodeType->hasReference($propertyName);
140139
}
141140

142141
/**
@@ -153,26 +152,16 @@ public function apply(): void
153152
if ($this->canApply() && !is_null($subject) && !is_null($propertyName)) {
154153
$contentRepository = $this->contentRepositoryRegistry->get($subject->subgraphIdentity->contentRepositoryId);
155154

156-
$propertyType = $this->getNodeType($subject)->getPropertyType($propertyName);
157-
158-
// Use extra commands for reference handling
159-
if ($propertyType === 'reference' || $propertyType === 'references') {
155+
if ($this->getNodeType($subject)->hasReference($propertyName)) {
156+
// Use extra commands for reference handling
160157
$value = $this->getValue();
158+
161159
$destinationNodeAggregateIds = [];
162-
if ($propertyType === 'reference') {
163-
if (is_string($value) && !empty($value)) {
164-
$destinationNodeAggregateIds[] = $value;
165-
}
166-
}
167160

168-
if ($propertyType === 'references') {
169-
/** @var array<int,string> $values */
170-
$values = $value;
171-
if (is_array($values)) {
172-
foreach ($values as $singleNodeAggregateId) {
173-
$destinationNodeAggregateIds[] = $singleNodeAggregateId;
174-
}
175-
}
161+
if (is_string($value) && !empty($value)) {
162+
$destinationNodeAggregateIds = [$value];
163+
} elseif (is_array($value)) {
164+
$destinationNodeAggregateIds = $value;
176165
}
177166

178167
$commandResult = $contentRepository->handle(
@@ -278,8 +267,12 @@ public function apply(): void
278267
$updateNodeInfo->setNode($node);
279268
$this->feedbackCollection->add($updateNodeInfo);
280269

281-
$reloadIfChangedConfigurationPath = sprintf('properties.%s.ui.reloadIfChanged', $propertyName);
282-
if (!$this->getIsInline() && $this->getNodeType($node)->getConfiguration($reloadIfChangedConfigurationPath)) {
270+
if (!$this->getIsInline()
271+
&& (
272+
$this->getNodeType($node)->hasConfiguration(sprintf('properties.%s.ui.reloadIfChanged', $propertyName))
273+
|| $this->getNodeType($node)->hasConfiguration(sprintf('references.%s.ui.reloadIfChanged', $propertyName))
274+
)
275+
) {
283276
if ($this->getNodeDomAddress() && $this->getNodeDomAddress()->getFusionPath()
284277
&& $parentNode
285278
&& $this->getNodeType($parentNode)->isOfType('Neos.Neos:ContentCollection')) {
@@ -292,9 +285,12 @@ public function apply(): void
292285
}
293286
}
294287

295-
$reloadPageIfChangedConfigurationPath = sprintf('properties.%s.ui.reloadPageIfChanged', $propertyName);
296288
if (!$this->getIsInline()
297-
&& $this->getNodeType($node)->getConfiguration($reloadPageIfChangedConfigurationPath)) {
289+
&& (
290+
$this->getNodeType($node)->hasConfiguration(sprintf('properties.%s.ui.reloadPageIfChanged', $propertyName))
291+
|| $this->getNodeType($node)->hasConfiguration(sprintf('references.%s.ui.reloadPageIfChanged', $propertyName))
292+
)
293+
) {
298294
$this->reloadDocument($node);
299295
}
300296
}

Classes/Domain/Service/NodePropertyConversionService.php

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,10 @@ class NodePropertyConversionService
4444
*/
4545
public function convert(NodeType $nodeType, string $propertyName, string|array|null $rawValue): mixed
4646
{
47-
// WORKAROUND: $nodeType->getPropertyType() is missing the "initialize" call,
48-
// so we need to trigger another method beforehand.
49-
$nodeType->getFullConfiguration();
47+
if ($nodeType->hasReference($propertyName)) {
48+
throw new \Exception("not implemented here, must be handled outside.");
49+
}
50+
5051
$propertyType = $nodeType->getPropertyType($propertyName);
5152

5253
if (is_null($rawValue)) {
@@ -57,12 +58,6 @@ public function convert(NodeType $nodeType, string $propertyName, string|array|n
5758
case 'string':
5859
return $rawValue;
5960

60-
case 'reference':
61-
throw new \Exception("not implemented here, must be handled outside.");
62-
63-
case 'references':
64-
throw new \Exception("not implemented here, must be handled outside.");
65-
6661
case 'DateTime':
6762
return $this->convertDateTime($rawValue);
6863

Classes/Domain/Service/NodePropertyConverterService.php

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use Neos\ContentRepository\Core\NodeType\NodeType;
1818
use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindReferencesFilter;
1919
use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
20-
use Neos\ContentRepository\Core\Projection\ContentGraph\References;
2120
use Neos\ContentRepository\Core\Projection\NodeHiddenState\NodeHiddenStateFinder;
2221
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
2322
use Neos\Flow\Annotations as Flow;
@@ -40,6 +39,7 @@
4039
* THIS IS DIRTY CODE. In the longer run, the neos UI should work DIRECTLY with serialized properties
4140
* instead of the objects.
4241
*
42+
* @internal
4343
* @Flow\Scope("singleton")
4444
*/
4545
class NodePropertyConverterService
@@ -99,14 +99,40 @@ public function injectThrowableStorage(ThrowableStorageInterface $throwableStora
9999
$this->throwableStorage = $throwableStorage;
100100
}
101101

102+
/**
103+
* @return list<string>|string|null
104+
*/
105+
private function getReference(Node $node, string $referenceName): array|string|null
106+
{
107+
$subgraph = $this->contentRepositoryRegistry->subgraphForNode($node);
108+
$references = $subgraph->findReferences(
109+
$node->nodeAggregateId,
110+
FindReferencesFilter::create(referenceName: $referenceName)
111+
);
112+
113+
$referenceIdentifiers = [];
114+
foreach ($references as $reference) {
115+
$referenceIdentifiers[] = $reference->node->nodeAggregateId->value;
116+
}
117+
118+
$maxItems = $this->getNodeType($node)->getReferences()[$referenceName]['constraints']['maxItems'] ?? null;
119+
120+
if ($maxItems === 1) {
121+
// special handling to simulate old single reference behaviour.
122+
// todo should be adjusted in the ui
123+
if (count($referenceIdentifiers) === 0) {
124+
return null;
125+
} else {
126+
return reset($referenceIdentifiers);
127+
}
128+
}
129+
return $referenceIdentifiers;
130+
}
131+
102132
/**
103133
* Get a single property reduced to a simple type (no objects) representation
104-
*
105-
* @param Node $node
106-
* @param string $propertyName
107-
* @return mixed
108134
*/
109-
public function getProperty(Node $node, $propertyName)
135+
private function getProperty(Node $node, string $propertyName): mixed
110136
{
111137
if ($propertyName === '_hidden') {
112138
$contentRepository = $this->contentRepositoryRegistry->get($node->subgraphIdentity->contentRepositoryId);
@@ -118,38 +144,14 @@ public function getProperty(Node $node, $propertyName)
118144
$node->nodeAggregateId
119145
)->isHidden;
120146
}
121-
$propertyType = $this->getNodeType($node)->getPropertyType($propertyName);
122-
123-
// We handle "reference" and "references" differently than other properties;
124-
// because we need to use another API for querying these references.
125-
if ($propertyType === 'reference') {
126-
$subgraph = $this->contentRepositoryRegistry->subgraphForNode($node);
127-
$referenceIdentifiers = $this->toNodeIdentifierStrings(
128-
$subgraph->findReferences(
129-
$node->nodeAggregateId,
130-
FindReferencesFilter::create(referenceName: $propertyName)
131-
)
132-
);
133-
if (count($referenceIdentifiers) === 0) {
134-
return null;
135-
} else {
136-
return reset($referenceIdentifiers);
137-
}
138-
} elseif ($propertyType === 'references') {
139-
$subgraph = $this->contentRepositoryRegistry->subgraphForNode($node);
140-
$references = $subgraph->findReferences(
141-
$node->nodeAggregateId,
142-
FindReferencesFilter::create(referenceName: $propertyName)
143-
);
144147

145-
return $this->toNodeIdentifierStrings($references);
146-
// Here, the normal property access logic starts.
147-
} elseif ($propertyName[0] === '_' && $propertyName !== '_hiddenInIndex') {
148+
if ($propertyName[0] === '_' && $propertyName !== '_hiddenInIndex') {
148149
$propertyValue = ObjectAccess::getProperty($node, ltrim($propertyName, '_'));
149150
} else {
150151
$propertyValue = $node->getProperty($propertyName);
151152
}
152153

154+
$propertyType = $this->getNodeType($node)->getPropertyType($propertyName);
153155
try {
154156
$convertedValue = $this->convertValue($propertyValue, $propertyType);
155157
} catch (PropertyException $exception) {
@@ -175,35 +177,25 @@ public function getProperty(Node $node, $propertyName)
175177
}
176178

177179
/**
178-
* @return array<int,string>
179-
*/
180-
private function toNodeIdentifierStrings(References $references): array
181-
{
182-
$identifiers = [];
183-
foreach ($references as $reference) {
184-
$identifiers[] = $reference->node->nodeAggregateId->value;
185-
}
186-
return $identifiers;
187-
}
188-
189-
/**
190-
* Get all properties reduced to simple type (no objects) representations in an array
180+
* Get all properties and references stuff reduced to simple type (no objects) representations in an array
191181
*
192182
* @param Node $node
193183
* @return array<string,mixed>
194184
*/
195185
public function getPropertiesArray(Node $node)
196186
{
197187
$properties = [];
198-
foreach ($this->getNodeType($node)->getProperties() as $propertyName => $propertyConfiguration) {
188+
foreach ($this->getNodeType($node)->getProperties() as $propertyName => $_) {
199189
if ($propertyName[0] === '_' && $propertyName[1] === '_') {
200190
// skip fully-private properties
201191
continue;
202192
}
203193

204194
$properties[$propertyName] = $this->getProperty($node, $propertyName);
205195
}
206-
196+
foreach ($this->getNodeType($node)->getReferences() as $referenceName => $_) {
197+
$properties[$referenceName] = $this->getReference($node, $referenceName);
198+
}
207199
return $properties;
208200
}
209201

Classes/Fusion/Helper/NodeInfoHelper.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
use Neos\Neos\Utility\NodeTypeWithFallbackProvider;
3131

3232
/**
33+
* @internal
3334
* @Flow\Scope("singleton")
3435
*/
3536
class NodeInfoHelper implements ProtectedContextAwareInterface

Classes/NodeCreationHandler/CreationDialogPropertiesCreationHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public function handle(CreateNodeAggregateWithNode $command, array $data, Conten
5555
continue;
5656
}
5757
$propertyValue = $data[$propertyName];
58-
if ($propertyType !== 'references' && $propertyType !== 'reference' && $propertyType !== TypeHandling::getTypeForValue($propertyValue)) {
58+
if (!$nodeType->hasReference($propertyName) && $propertyType !== TypeHandling::getTypeForValue($propertyValue)) {
5959
$propertyValue = $this->propertyMapper->convert($propertyValue, $propertyType, $propertyMappingConfiguration);
6060
}
6161

0 commit comments

Comments
 (0)