11
11
* source code.
12
12
*/
13
13
14
+ use GuzzleHttp \Psr7 \Uri ;
14
15
use Neos \ContentRepository \Domain \Model \Node ;
15
16
use Neos \ContentRepository \Domain \Model \NodeInterface ;
16
17
use Neos \ContentRepository \Domain \Service \ContextFactoryInterface ;
17
- use Neos \ContentRepository \Domain \Utility \ NodePaths ;
18
+ use Neos \ContentRepository \Domain \Service \ NodeTypeManager ;
18
19
use Neos \Eel \ProtectedContextAwareInterface ;
19
20
use Neos \Flow \Annotations as Flow ;
21
+ use Neos \Flow \Http \Helper \UriHelper ;
20
22
use Neos \Flow \Mvc \Controller \ControllerContext ;
21
23
use Neos \Flow \Persistence \PersistenceManagerInterface ;
22
24
use Neos \Neos \Domain \Service \ContentContext ;
@@ -97,6 +99,17 @@ class NodeInfoHelper implements ProtectedContextAwareInterface
97
99
*/
98
100
protected $ ignoredNodeTypeRole ;
99
101
102
+ /**
103
+ * @Flow\Inject
104
+ * @var NodeTypeManager
105
+ */
106
+ protected $ nodeTypeManager ;
107
+
108
+ /**
109
+ * @var array<string, string>
110
+ */
111
+ protected array $ sitePreviewUris = [];
112
+
100
113
/**
101
114
* @param NodeInterface $node
102
115
* @param ?ControllerContext $controllerContext
@@ -107,20 +120,32 @@ class NodeInfoHelper implements ProtectedContextAwareInterface
107
120
*/
108
121
public function renderNode (NodeInterface $ node , ?ControllerContext $ controllerContext = null , $ omitMostPropertiesForTreeState = false , $ nodeTypeFilterOverride = null )
109
122
{
123
+ $ includedNodeTypes = $ this ->getIncludedNodeTypes ($ controllerContext , $ nodeTypeFilterOverride );
110
124
return ($ omitMostPropertiesForTreeState ?
111
- $ this ->renderNodeWithMinimalPropertiesAndChildrenInformation ($ node , $ controllerContext , $ nodeTypeFilterOverride ) :
125
+ $ this ->renderNodeWithMinimalPropertiesAndChildrenInformation (
126
+ $ node ,
127
+ $ controllerContext ,
128
+ $ this ->buildNodeTypeFilterString (
129
+ $ includedNodeTypes ,
130
+ $ this ->nodeTypeStringsToList ($ this ->ignoredNodeTypeRole )
131
+ ),
132
+ $ this ->shouldIncludeContentChildNodes ($ includedNodeTypes )
133
+ ) :
112
134
$ this ->renderNodeWithPropertiesAndChildrenInformation ($ node , $ controllerContext , $ nodeTypeFilterOverride )
113
135
);
114
136
}
115
137
116
138
/**
117
139
* @param NodeInterface $node
118
140
* @param ControllerContext|null $controllerContext
119
- * @param ?string $nodeTypeFilterOverride
120
141
* @return array|null
121
142
*/
122
- public function renderNodeWithMinimalPropertiesAndChildrenInformation (NodeInterface $ node , ?ControllerContext $ controllerContext = null , ?string $ nodeTypeFilterOverride = null )
123
- {
143
+ public function renderNodeWithMinimalPropertiesAndChildrenInformation (
144
+ NodeInterface $ node ,
145
+ ?ControllerContext $ controllerContext = null ,
146
+ string $ nodeTypeFilter = '' ,
147
+ bool $ includeContentChildNodes = false
148
+ ) {
124
149
if (!$ this ->nodePolicyService ->isNodeTreePrivilegeGranted ($ node )) {
125
150
return null ;
126
151
}
@@ -137,15 +162,9 @@ public function renderNodeWithMinimalPropertiesAndChildrenInformation(NodeInterf
137
162
138
163
if ($ controllerContext !== null ) {
139
164
$ nodeInfo = array_merge ($ nodeInfo , $ this ->getUriInformation ($ node , $ controllerContext ));
140
- if ($ controllerContext ->getRequest ()->hasArgument ('presetBaseNodeType ' )) {
141
- $ presetBaseNodeType = $ controllerContext ->getRequest ()->getArgument ('presetBaseNodeType ' );
142
- }
143
165
}
144
166
145
- $ baseNodeType = $ nodeTypeFilterOverride ? $ nodeTypeFilterOverride : (isset ($ presetBaseNodeType ) ? $ presetBaseNodeType : $ this ->defaultBaseNodeType );
146
- $ nodeTypeFilter = $ this ->buildNodeTypeFilterString ($ this ->nodeTypeStringsToList ($ baseNodeType ), $ this ->nodeTypeStringsToList ($ this ->ignoredNodeTypeRole ));
147
-
148
- $ nodeInfo ['children ' ] = $ this ->renderChildrenInformation ($ node , $ nodeTypeFilter );
167
+ $ nodeInfo ['children ' ] = $ this ->renderChildrenInformation ($ node , $ nodeTypeFilter , $ includeContentChildNodes );
149
168
150
169
$ this ->userLocaleService ->switchToUILocale (true );
151
170
@@ -200,7 +219,7 @@ protected function getUriInformation(NodeInterface $node, ControllerContext $con
200
219
}
201
220
202
221
try {
203
- $ nodeInfo ['uri ' ] = $ this ->uri ($ node , $ controllerContext );
222
+ $ nodeInfo ['uri ' ] = $ this ->previewUri ($ node , $ controllerContext );
204
223
} catch (\Neos \Neos \Exception $ exception ) {
205
224
// Unless there is a serious problem with routes there shouldn't be an exception ever.
206
225
$ nodeInfo ['uri ' ] = '' ;
@@ -239,12 +258,16 @@ protected function getBasicNodeInformation(NodeInterface $node): array
239
258
* @param string $nodeTypeFilterString
240
259
* @return array
241
260
*/
242
- protected function renderChildrenInformation (NodeInterface $ node , string $ nodeTypeFilterString ): array
261
+ protected function renderChildrenInformation (NodeInterface $ node , string $ nodeTypeFilterString, bool $ includeContentChildNodes = true ): array
243
262
{
244
263
$ documentChildNodes = $ node ->getChildNodes ($ nodeTypeFilterString );
245
- // child nodes for content tree, must not include those nodes filtered out by `baseNodeType`
246
- $ contentChildNodes = $ node ->getChildNodes ($ this ->buildContentChildNodeFilterString ());
247
- $ childNodes = array_merge ($ documentChildNodes , $ contentChildNodes );
264
+ if ($ includeContentChildNodes ) {
265
+ // child nodes for content tree, must not include those nodes filtered out by `baseNodeType`
266
+ $ contentChildNodes = $ node ->getChildNodes ($ this ->buildContentChildNodeFilterString ());
267
+ $ childNodes = array_merge ($ documentChildNodes , $ contentChildNodes );
268
+ } else {
269
+ $ childNodes = $ documentChildNodes ;
270
+ }
248
271
249
272
$ mapper = static function (NodeInterface $ childNode ) {
250
273
return [
@@ -262,14 +285,43 @@ protected function renderChildrenInformation(NodeInterface $node, string $nodeTy
262
285
* @param bool $omitMostPropertiesForTreeState
263
286
* @return array
264
287
*/
265
- public function renderNodes (array $ nodes , ControllerContext $ controllerContext , $ omitMostPropertiesForTreeState = false ): array
288
+ public function renderNodes (
289
+ array $ nodes ,
290
+ ControllerContext $ controllerContext ,
291
+ $ omitMostPropertiesForTreeState = false ,
292
+ bool $ includeContentChildNodes = true
293
+ ): array {
294
+ if ($ omitMostPropertiesForTreeState ) {
295
+ $ includedNodeTypes = $ this ->getIncludedNodeTypes ($ controllerContext );
296
+ $ nodeTypeFilterString = $ this ->buildNodeTypeFilterString (
297
+ $ includedNodeTypes ,
298
+ $ this ->nodeTypeStringsToList ($ this ->ignoredNodeTypeRole )
299
+ );
300
+ $ renderedNodes = array_map (function ($ node ) use ($ controllerContext , $ includeContentChildNodes , $ nodeTypeFilterString ) {
301
+ return $ this ->renderNodeWithMinimalPropertiesAndChildrenInformation (
302
+ $ node ,
303
+ $ controllerContext ,
304
+ $ nodeTypeFilterString ,
305
+ $ includeContentChildNodes
306
+ );
307
+ }, $ nodes );
308
+ } else {
309
+ $ renderedNodes = array_map (function ($ node ) use ($ controllerContext ) {
310
+ return $ this ->renderNodeWithPropertiesAndChildrenInformation ($ node , $ controllerContext );
311
+ }, $ nodes );
312
+ }
313
+
314
+ return array_values (array_filter ($ renderedNodes ));
315
+ }
316
+
317
+ protected function getIncludedNodeTypes (?ControllerContext $ controllerContext , string $ nodeTypeFilterOverride = null ): array
266
318
{
267
- $ methodName = $ omitMostPropertiesForTreeState ? 'renderNodeWithMinimalPropertiesAndChildrenInformation ' : 'renderNodeWithPropertiesAndChildrenInformation ' ;
268
- $ mapper = function (NodeInterface $ node ) use ($ controllerContext , $ methodName ) {
269
- return $ this ->$ methodName ($ node , $ controllerContext );
270
- };
319
+ if ($ controllerContext ?->getRequest()->hasArgument ('presetBaseNodeType ' )) {
320
+ $ presetBaseNodeType = $ controllerContext ?->getRequest()->getArgument ('presetBaseNodeType ' );
321
+ }
271
322
272
- return array_values (array_filter (array_map ($ mapper , $ nodes )));
323
+ $ baseNodeType = $ nodeTypeFilterOverride ?: $ presetBaseNodeType ?? $ this ->defaultBaseNodeType ;
324
+ return $ this ->nodeTypeStringsToList ($ baseNodeType );
273
325
}
274
326
275
327
/**
@@ -278,17 +330,29 @@ public function renderNodes(array $nodes, ControllerContext $controllerContext,
278
330
* @param null|string $nodeTypeFilter
279
331
* @return array
280
332
*/
281
- public function renderNodesWithParents (array $ nodes , ControllerContext $ controllerContext , ?string $ nodeTypeFilter = null ): array
282
- {
333
+ public function renderNodesWithParents (
334
+ array $ nodes ,
335
+ ControllerContext $ controllerContext ,
336
+ ?string $ nodeTypeFilter = null ,
337
+ bool $ includeContentChildNodes = true
338
+ ): array {
283
339
// For search operation we want to include all nodes, not respecting the "baseNodeType" setting
284
340
$ baseNodeTypeOverride = $ this ->documentNodeTypeRole ;
285
341
$ renderedNodes = [];
342
+ $ includedNodeTypes = $ this ->getIncludedNodeTypes ($ controllerContext , $ nodeTypeFilter ?? $ baseNodeTypeOverride );
343
+ $ excludedNodeTypes = $ this ->nodeTypeStringsToList ($ this ->ignoredNodeTypeRole );
344
+ $ nodeTypeFilterString = $ this ->buildNodeTypeFilterString ($ includedNodeTypes , $ excludedNodeTypes );
286
345
287
346
/** @var NodeInterface $node */
288
347
foreach ($ nodes as $ node ) {
289
348
if (array_key_exists ($ node ->getPath (), $ renderedNodes )) {
290
349
$ renderedNodes [$ node ->getPath ()]['matched ' ] = true ;
291
- } elseif ($ renderedNode = $ this ->renderNodeWithMinimalPropertiesAndChildrenInformation ($ node , $ controllerContext , $ nodeTypeFilter ?? $ baseNodeTypeOverride )) {
350
+ } elseif ($ renderedNode = $ this ->renderNodeWithMinimalPropertiesAndChildrenInformation (
351
+ $ node ,
352
+ $ controllerContext ,
353
+ $ nodeTypeFilterString ,
354
+ $ includeContentChildNodes
355
+ )) {
292
356
$ renderedNode ['matched ' ] = true ;
293
357
$ renderedNodes [$ node ->getPath ()] = $ renderedNode ;
294
358
} else {
@@ -311,7 +375,12 @@ public function renderNodesWithParents(array $nodes, ControllerContext $controll
311
375
if (array_key_exists ($ parentNode ->getPath (), $ renderedNodes )) {
312
376
$ renderedNodes [$ parentNode ->getPath ()]['intermediate ' ] = true ;
313
377
} else {
314
- $ renderedParentNode = $ this ->renderNodeWithMinimalPropertiesAndChildrenInformation ($ parentNode , $ controllerContext , $ baseNodeTypeOverride );
378
+ $ renderedParentNode = $ this ->renderNodeWithMinimalPropertiesAndChildrenInformation (
379
+ $ parentNode ,
380
+ $ controllerContext ,
381
+ $ baseNodeTypeOverride ,
382
+ $ includeContentChildNodes
383
+ );
315
384
if ($ renderedParentNode ) {
316
385
$ renderedParentNode ['intermediate ' ] = true ;
317
386
$ renderedNodes [$ parentNode ->getPath ()] = $ renderedParentNode ;
@@ -368,6 +437,27 @@ public function defaultNodesForBackend(NodeInterface $site, NodeInterface $docum
368
437
];
369
438
}
370
439
440
+ public function previewUri (
441
+ NodeInterface $ node ,
442
+ ControllerContext $ controllerContext
443
+ ): string {
444
+ /* @var $contentContext ContentContext */
445
+ $ contentContext = $ node ->getContext ();
446
+ $ siteNode = $ contentContext ->getCurrentSiteNode ();
447
+
448
+ $ sitePreviewUri = $ this ->sitePreviewUris [$ siteNode ->getContextPath ()] ?? null ;
449
+ if (!$ sitePreviewUri ) {
450
+ $ sitePreviewUri = new Uri ($ this ->uri ($ siteNode , $ controllerContext ));
451
+ $ this ->sitePreviewUris [$ siteNode ->getContextPath ()] = $ sitePreviewUri ;
452
+ }
453
+
454
+ $ arguments = UriHelper::parseQueryIntoArguments ($ sitePreviewUri );
455
+ return (string )UriHelper::uriWithArguments (
456
+ $ sitePreviewUri ,
457
+ [...$ arguments , 'node ' => $ node ->getContextPath ()],
458
+ );
459
+ }
460
+
371
461
/**
372
462
* Creates a URL that will redirect to the given $node in live or base workspace, or returns an empty string if that doesn't exist or is inaccessible
373
463
*
0 commit comments