17
17
use Neos \ContentRepository \Core \NodeType \NodeType ;
18
18
use Neos \ContentRepository \Core \Projection \ContentGraph \Filter \FindReferencesFilter ;
19
19
use Neos \ContentRepository \Core \Projection \ContentGraph \Node ;
20
- use Neos \ContentRepository \Core \Projection \ContentGraph \References ;
21
20
use Neos \ContentRepository \Core \Projection \NodeHiddenState \NodeHiddenStateFinder ;
22
21
use Neos \ContentRepositoryRegistry \ContentRepositoryRegistry ;
23
22
use Neos \Flow \Annotations as Flow ;
40
39
* THIS IS DIRTY CODE. In the longer run, the neos UI should work DIRECTLY with serialized properties
41
40
* instead of the objects.
42
41
*
42
+ * @internal
43
43
* @Flow\Scope("singleton")
44
44
*/
45
45
class NodePropertyConverterService
@@ -99,14 +99,40 @@ public function injectThrowableStorage(ThrowableStorageInterface $throwableStora
99
99
$ this ->throwableStorage = $ throwableStorage ;
100
100
}
101
101
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
+
102
132
/**
103
133
* Get a single property reduced to a simple type (no objects) representation
104
- *
105
- * @param Node $node
106
- * @param string $propertyName
107
- * @return mixed
108
134
*/
109
- public function getProperty (Node $ node , $ propertyName )
135
+ private function getProperty (Node $ node , string $ propertyName ): mixed
110
136
{
111
137
if ($ propertyName === '_hidden ' ) {
112
138
$ contentRepository = $ this ->contentRepositoryRegistry ->get ($ node ->subgraphIdentity ->contentRepositoryId );
@@ -118,38 +144,14 @@ public function getProperty(Node $node, $propertyName)
118
144
$ node ->nodeAggregateId
119
145
)->isHidden ;
120
146
}
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
- );
144
147
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 ' ) {
148
149
$ propertyValue = ObjectAccess::getProperty ($ node , ltrim ($ propertyName , '_ ' ));
149
150
} else {
150
151
$ propertyValue = $ node ->getProperty ($ propertyName );
151
152
}
152
153
154
+ $ propertyType = $ this ->getNodeType ($ node )->getPropertyType ($ propertyName );
153
155
try {
154
156
$ convertedValue = $ this ->convertValue ($ propertyValue , $ propertyType );
155
157
} catch (PropertyException $ exception ) {
@@ -175,35 +177,25 @@ public function getProperty(Node $node, $propertyName)
175
177
}
176
178
177
179
/**
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
191
181
*
192
182
* @param Node $node
193
183
* @return array<string,mixed>
194
184
*/
195
185
public function getPropertiesArray (Node $ node )
196
186
{
197
187
$ properties = [];
198
- foreach ($ this ->getNodeType ($ node )->getProperties () as $ propertyName => $ propertyConfiguration ) {
188
+ foreach ($ this ->getNodeType ($ node )->getProperties () as $ propertyName => $ _ ) {
199
189
if ($ propertyName [0 ] === '_ ' && $ propertyName [1 ] === '_ ' ) {
200
190
// skip fully-private properties
201
191
continue ;
202
192
}
203
193
204
194
$ properties [$ propertyName ] = $ this ->getProperty ($ node , $ propertyName );
205
195
}
206
-
196
+ foreach ($ this ->getNodeType ($ node )->getReferences () as $ referenceName => $ _ ) {
197
+ $ properties [$ referenceName ] = $ this ->getReference ($ node , $ referenceName );
198
+ }
207
199
return $ properties ;
208
200
}
209
201
0 commit comments