@@ -50,6 +50,7 @@ public function convert($source): array
50
50
private function convertTypes (\DOMDocument $ source ): array
51
51
{
52
52
$ typesData = [];
53
+ $ parentChildData = [];
53
54
/** @var \DOMNodeList $contentTypes */
54
55
$ contentTypes = $ source ->getElementsByTagName ('type ' );
55
56
/** @var \DOMNode $contentType */
@@ -66,12 +67,16 @@ private function convertTypes(\DOMDocument $source): array
66
67
$ typesData [$ name ][$ childNode ->nodeName ] = $ this ->convertAppearancesData ($ childNode );
67
68
} elseif ('additional_data ' === $ childNode ->nodeName ) {
68
69
$ typesData [$ name ][$ childNode ->nodeName ] = $ this ->convertAdditionalData ($ childNode );
69
- } elseif ('allowed_parents ' === $ childNode ->nodeName ) {
70
- $ parents = [];
71
- foreach ($ childNode ->getElementsByTagName ('parent ' ) as $ parentNode ) {
72
- $ parents [] = $ parentNode ->attributes ->getNamedItem ('name ' )->nodeValue ;
73
- }
74
- $ typesData [$ name ][$ childNode ->nodeName ] = $ parents ;
70
+ } elseif ('parents ' === $ childNode ->nodeName ) {
71
+ $ parentChildData [$ name ][$ childNode ->nodeName ] = [
72
+ 'defaultPolicy ' => $ this ->getAttributeValue ($ childNode , 'default_policy ' ),
73
+ 'types ' => $ this ->convertParentChildData ($ childNode , 'parent ' )
74
+ ];
75
+ } elseif ('children ' === $ childNode ->nodeName ) {
76
+ $ parentChildData [$ name ][$ childNode ->nodeName ] = [
77
+ 'defaultPolicy ' => $ this ->getAttributeValue ($ childNode , 'default_policy ' ),
78
+ 'types ' => $ this ->convertParentChildData ($ childNode , 'child ' )
79
+ ];
75
80
} else {
76
81
$ typesData [$ name ][$ childNode ->nodeName ] = $ childNode ->nodeValue ;
77
82
}
@@ -83,7 +88,9 @@ private function convertTypes(\DOMDocument $source): array
83
88
return (int )$ firstElement ['sortOrder ' ] <=> (int )$ secondElement ['sortOrder ' ];
84
89
});
85
90
86
- return $ typesData ;
91
+ $ allowedParents = $ this ->convertParentChildDataToAllowedParents (array_keys ($ typesData ), $ parentChildData );
92
+
93
+ return array_merge_recursive ($ typesData , $ allowedParents );
87
94
}
88
95
89
96
/**
@@ -203,10 +210,7 @@ private function convertDataMapping(\DOMElement $childNode): array
203
210
$ elementData = [];
204
211
foreach ($ childNode ->getElementsByTagName ('element ' ) as $ elementNode ) {
205
212
$ elementName = $ elementNode ->attributes ->getNamedItem ('name ' )->nodeValue ;
206
- $ elementPath = ($ elementNode ->attributes ->getNamedItem ('path ' )
207
- ? $ elementNode ->attributes ->getNamedItem ('path ' )->nodeValue : '' );
208
213
$ elementData [$ elementName ] = [
209
- 'path ' => $ elementPath ,
210
214
'style ' => $ this ->convertProperties ($ elementNode ),
211
215
'attributes ' => $ this ->convertAttributes ($ elementNode ),
212
216
'html ' => $ this ->convertHtml ($ elementNode ),
@@ -267,7 +271,7 @@ private function convertProperties(\DOMElement $elementNode): array
267
271
if ($ propertiesNode ) {
268
272
foreach ($ propertiesNode ->getElementsByTagName ('property ' ) as $ propertyNode ) {
269
273
$ propertiesData [] = [
270
- 'var ' => $ this ->getAttributeValue ($ propertyNode, ' name ' ),
274
+ 'var ' => $ this ->extractVariableName ($ propertyNode ),
271
275
'name ' => $ this ->getAttributeValue ($ propertyNode , 'source ' ),
272
276
'converter ' => $ this ->getAttributeValue ($ propertyNode , 'converter ' ),
273
277
'preview_converter ' => $ this ->getAttributeValue ($ propertyNode , 'preview_converter ' ),
@@ -277,7 +281,7 @@ private function convertProperties(\DOMElement $elementNode): array
277
281
}
278
282
foreach ($ propertiesNode ->getElementsByTagName ('complex_property ' ) as $ propertyNode ) {
279
283
$ propertiesData [] = [
280
- 'var ' => $ this ->getAttributeValue ($ propertyNode, ' name ' ),
284
+ 'var ' => $ this ->extractVariableName ($ propertyNode ),
281
285
'reader ' => $ this ->getAttributeValue ($ propertyNode , 'reader ' ),
282
286
'converter ' => $ this ->getAttributeValue ($ propertyNode , 'converter ' ),
283
287
'preview_converter ' => $ this ->getAttributeValue ($ propertyNode , 'preview_converter ' ),
@@ -309,7 +313,7 @@ private function convertAttributes(\DOMElement $elementNode): array
309
313
if ($ attributesNode ) {
310
314
foreach ($ attributesNode ->getElementsByTagName ('attribute ' ) as $ attributeNode ) {
311
315
$ attributesData [] = [
312
- 'var ' => $ this ->getAttributeValue ($ attributeNode, ' name ' ),
316
+ 'var ' => $ this ->extractVariableName ($ attributeNode ),
313
317
'name ' => $ this ->getAttributeValue ($ attributeNode , 'source ' ),
314
318
'converter ' => $ this ->getAttributeValue ($ attributeNode , 'converter ' ),
315
319
'preview_converter ' => $ this ->getAttributeValue ($ attributeNode , 'preview_converter ' ),
@@ -326,7 +330,7 @@ private function convertAttributes(\DOMElement $elementNode): array
326
330
}
327
331
foreach ($ attributesNode ->getElementsByTagName ('complex_attribute ' ) as $ attributeNode ) {
328
332
$ attributesData [] = [
329
- 'var ' => $ this ->getAttributeValue ($ attributeNode, ' name ' ),
333
+ 'var ' => $ this ->extractVariableName ($ attributeNode ),
330
334
'reader ' => $ this ->getAttributeValue ($ attributeNode , 'reader ' ),
331
335
'converter ' => $ this ->getAttributeValue ($ attributeNode , 'converter ' ),
332
336
'preview_converter ' => $ this ->getAttributeValue ($ attributeNode , 'preview_converter ' ),
@@ -431,6 +435,120 @@ private function convertConvertersData(\DOMElement $childNode): array
431
435
return $ converters ;
432
436
}
433
437
438
+ /**
439
+ * Convert parent and child data to correct format
440
+ *
441
+ * @param \DOMElement $elementNode
442
+ * @param string $tagName
443
+ * @return array
444
+ */
445
+ private function convertParentChildData (\DOMElement $ elementNode , string $ tagName ): array
446
+ {
447
+ $ data = [];
448
+ foreach ($ elementNode ->getElementsByTagName ($ tagName ) as $ node ) {
449
+ $ name = $ node ->attributes ->getNamedItem ('name ' )->nodeValue ;
450
+ $ data [$ node ->attributes ->getNamedItem ('policy ' )->nodeValue ][] = $ name ;
451
+ }
452
+ return $ data ;
453
+ }
454
+
455
+ /**
456
+ * Convert parent and child data to allowed parents
457
+ *
458
+ * @param array $types
459
+ * @param array $parentChildData
460
+ * @return array
461
+ */
462
+ private function convertParentChildDataToAllowedParents (array $ types , array $ parentChildData ): array
463
+ {
464
+ $ allowedParentsData = [];
465
+
466
+ // convert children
467
+ $ allowedParents = $ this ->convertChildrenToAllowedParents ($ parentChildData , $ types );
468
+ foreach ($ types as $ type ) {
469
+ $ allowedParentsData [$ type ]['allowed_parents ' ] = $ allowedParents [$ type ];
470
+ }
471
+
472
+ // convert parents
473
+ $ allowedParentsData = $ this ->convertParentsToAllowedParents ($ parentChildData , $ types , $ allowedParentsData );
474
+
475
+ return $ allowedParentsData ;
476
+ }
477
+
478
+ /**
479
+ * Convert children data to allow parents
480
+ *
481
+ * @param array $parentChildData
482
+ * @param array $types
483
+ * @return array
484
+ */
485
+ private function convertChildrenToAllowedParents (array $ parentChildData , array $ types ): array
486
+ {
487
+ $ allowedParents = [];
488
+
489
+ // setup allowed parents array
490
+ foreach ($ types as $ type ) {
491
+ $ allowedParents [$ type ] = [];
492
+ }
493
+
494
+ foreach ($ parentChildData as $ key => $ value ) {
495
+ $ children = $ value ['children ' ] ?? [];
496
+
497
+ if (empty ($ children )) {
498
+ continue ;
499
+ }
500
+
501
+ foreach ($ allowedParents as $ type => $ parents ) {
502
+ $ typeAllowed = in_array ($ type , $ children ['types ' ]['allow ' ] ?? []);
503
+ $ typeDenied = in_array ($ type , $ children ['types ' ]['deny ' ] ?? []);
504
+ if (($ children ['defaultPolicy ' ] === 'deny ' && !$ typeAllowed ) || $ typeDenied ) {
505
+ $ allowedParents [$ type ] = $ this ->removeDataInArray ($ key , $ parents );
506
+ } else {
507
+ $ allowedParents [$ type ][] = $ key ;
508
+ }
509
+ }
510
+ }
511
+
512
+ return $ allowedParents ;
513
+ }
514
+
515
+ /**
516
+ * Convert parents data to allowed parents
517
+ *
518
+ * @param array $parentChildData
519
+ * @param array $types
520
+ * @param array $allowedParentsData
521
+ * @return array
522
+ */
523
+ private function convertParentsToAllowedParents (
524
+ array $ parentChildData ,
525
+ array $ types ,
526
+ array $ allowedParentsData
527
+ ): array {
528
+ foreach ($ parentChildData as $ key => $ value ) {
529
+ $ parent = $ value ['parents ' ] ?? [];
530
+
531
+ if (empty ($ parent )) {
532
+ continue ;
533
+ }
534
+
535
+ $ allowedTypes = $ parent ['types ' ]['allow ' ] ?? [];
536
+ $ deniedTypes = $ parent ['types ' ]['deny ' ] ?? [];
537
+
538
+ if ($ parent ['defaultPolicy ' ] === 'deny ' ) {
539
+ $ allowedParents = $ allowedTypes ;
540
+ } else {
541
+ $ allowedParents = array_merge ($ types , $ allowedTypes );
542
+ foreach ($ deniedTypes as $ type ) {
543
+ $ allowedParents = $ this ->removeDataInArray ($ type , $ allowedParents );
544
+ }
545
+ }
546
+ $ allowedParentsData [$ key ]['allowed_parents ' ] = $ allowedParents ;
547
+ }
548
+
549
+ return $ allowedParentsData ;
550
+ }
551
+
434
552
/**
435
553
* Check if node is configuration node
436
554
*
@@ -458,4 +576,32 @@ private function getAttributeValue(\DOMElement $attributeNode, $attributeName)
458
576
? $ attributeNode ->attributes ->getNamedItem ($ attributeName )->nodeValue
459
577
: null ;
460
578
}
579
+
580
+ /**
581
+ * Extract variable name from property and attribute nodes
582
+ *
583
+ * @param \DOMElement $node
584
+ * @return string
585
+ */
586
+ private function extractVariableName (\DOMElement $ node ): string
587
+ {
588
+ return $ this ->getAttributeValue ($ node , 'storage_key ' )
589
+ ?: $ this ->getAttributeValue ($ node , 'name ' );
590
+ }
591
+
592
+ /**
593
+ * Remove data from array
594
+ *
595
+ * @param $searchValue
596
+ * @param $data
597
+ * @return array
598
+ */
599
+ private function removeDataInArray (string $ searchValue , array $ data ): array
600
+ {
601
+ $ removeKey = array_search ($ searchValue , $ data );
602
+ if ($ removeKey !== false ) {
603
+ unset($ data [$ removeKey ]);
604
+ }
605
+ return array_values ($ data );
606
+ }
461
607
}
0 commit comments