@@ -66,6 +66,16 @@ private function convertTypes(\DOMDocument $source): array
66
66
$ typesData [$ name ][$ childNode ->nodeName ] = $ this ->convertAppearancesData ($ childNode );
67
67
} elseif ('additional_data ' === $ childNode ->nodeName ) {
68
68
$ typesData [$ name ][$ childNode ->nodeName ] = $ this ->convertAdditionalData ($ childNode );
69
+ } elseif ('parents ' === $ childNode ->nodeName ) {
70
+ $ typesData [$ name ][$ childNode ->nodeName ] = [
71
+ 'defaultPolicy ' => $ this ->getAttributeValue ($ childNode , 'default_policy ' ),
72
+ 'types ' => $ this ->convertParentChildData ($ childNode , 'parent ' )
73
+ ];
74
+ } elseif ('children ' === $ childNode ->nodeName ) {
75
+ $ typesData [$ name ][$ childNode ->nodeName ] = [
76
+ 'defaultPolicy ' => $ this ->getAttributeValue ($ childNode , 'default_policy ' ),
77
+ 'types ' => $ this ->convertParentChildData ($ childNode , 'child ' )
78
+ ];
69
79
} elseif ('allowed_parents ' === $ childNode ->nodeName ) {
70
80
$ parents = [];
71
81
foreach ($ childNode ->getElementsByTagName ('parent ' ) as $ parentNode ) {
@@ -83,6 +93,8 @@ private function convertTypes(\DOMDocument $source): array
83
93
return (int )$ firstElement ['sortOrder ' ] <=> (int )$ secondElement ['sortOrder ' ];
84
94
});
85
95
96
+ $ this ->convertParentChildDataToAllowedParents ($ typesData );
97
+
86
98
return $ typesData ;
87
99
}
88
100
@@ -431,6 +443,142 @@ private function convertConvertersData(\DOMElement $childNode): array
431
443
return $ converters ;
432
444
}
433
445
446
+ /**
447
+ * Convert parent and child data to correct format
448
+ *
449
+ * @param \DOMElement $elementNode
450
+ * @param string $tagName
451
+ * @return array
452
+ */
453
+ private function convertParentChildData (\DOMElement $ elementNode , string $ tagName ): array
454
+ {
455
+ $ data = [];
456
+ foreach ($ elementNode ->getElementsByTagName ($ tagName ) as $ node ) {
457
+ $ data [] = [
458
+ 'name ' => $ node ->attributes ->getNamedItem ('name ' )->nodeValue ,
459
+ 'policy ' => $ node ->attributes ->getNamedItem ('policy ' )->nodeValue
460
+ ];
461
+ }
462
+ return $ data ;
463
+ }
464
+
465
+ /**
466
+ * Convert parent and child data to allowed parents
467
+ *
468
+ * @param array $typesData
469
+ */
470
+ private function convertParentChildDataToAllowedParents (array &$ typesData )
471
+ {
472
+ // get an array of all content type names
473
+ $ types = array_keys ($ typesData );
474
+
475
+ // convert children
476
+ $ allowedParents = $ this ->convertChildrenToAllowedParents ($ typesData , $ types );
477
+ foreach ($ typesData as $ key => &$ typeData ) {
478
+ $ typeData ['allowed_parents_new ' ] = $ allowedParents [$ key ];
479
+ }
480
+
481
+ // convert parents
482
+ $ typesData = $ this ->convertParentsToAllowedParents ($ typesData , $ types );
483
+ }
484
+
485
+ /**
486
+ * Convert children data to allow parents
487
+ *
488
+ * @param array $typesData
489
+ * @param array $allowedParents
490
+ * @return array
491
+ */
492
+ private function convertChildrenToAllowedParents (array $ typesData , array $ types ): array
493
+ {
494
+ $ allowedParents = [];
495
+
496
+ // setup allowed parents array
497
+ foreach ($ types as $ type ) {
498
+ $ allowedParents [$ type ] = [];
499
+ }
500
+
501
+ foreach ($ typesData as $ key => $ value ) {
502
+ $ children = $ value ['children ' ] ?? [];
503
+
504
+ if (empty ($ children )) {
505
+ continue ;
506
+ }
507
+
508
+ if ($ children ['defaultPolicy ' ] === 'deny ' ) {
509
+ $ allow = $ this ->getContentTypesByPolicy ($ children ['types ' ], 'allow ' );
510
+ foreach ($ allowedParents as $ type => $ parents ) {
511
+ if (!in_array ($ type , $ allow )) {
512
+ $ allowedParents [$ type ] = $ this ->removeDataInArray ($ key , $ parents );
513
+ } else {
514
+ $ allowedParents [$ type ][] = $ key ;
515
+ }
516
+ }
517
+ } else {
518
+ $ deny = $ this ->getContentTypesByPolicy ($ children ['types ' ], 'deny ' );
519
+ foreach ($ allowedParents as $ type => $ parents ) {
520
+ if (in_array ($ type , $ deny )) {
521
+ $ allowedParents [$ type ] = $ this ->removeDataInArray ($ key , $ parents );
522
+ } else {
523
+ $ allowedParents [$ type ][] = $ key ;
524
+ }
525
+ }
526
+ }
527
+ }
528
+
529
+ return $ allowedParents ;
530
+ }
531
+
532
+ /**
533
+ * Convert parents data to allowed parents
534
+ *
535
+ * @param array $typesData
536
+ * @param array $types
537
+ * @return array
538
+ */
539
+ private function convertParentsToAllowedParents (array $ typesData , array $ types ): array
540
+ {
541
+ foreach ($ typesData as $ key => $ value ) {
542
+ $ parent = $ value ['parents ' ] ?? [];
543
+
544
+ if (empty ($ parent )) {
545
+ continue ;
546
+ }
547
+
548
+ if ($ parent ['defaultPolicy ' ] === 'deny ' ) {
549
+ $ allowedParents = $ this ->getContentTypesByPolicy ($ parent ['types ' ], 'allow ' );
550
+ } else {
551
+ $ allowedParents = $ types ;
552
+ foreach ($ parent ['types ' ] as $ type ) {
553
+ if ($ type ['policy ' ] === 'deny ' ) {
554
+ $ allowedParents = $ this ->removeDataInArray ($ type ['name ' ], $ allowedParents );
555
+ }
556
+ }
557
+ }
558
+ $ typesData [$ key ]['allowed_parents_new ' ] = $ allowedParents ;
559
+ }
560
+
561
+ return $ typesData ;
562
+ }
563
+
564
+ /**
565
+ * Get an array of content type names by policy (allow or deny)
566
+ *
567
+ * @param array $contentTypes
568
+ * @param string $policy
569
+ * @return array
570
+ */
571
+ private function getContentTypesByPolicy (array $ contentTypes , string $ policy ): array
572
+ {
573
+ $ data = [];
574
+ foreach ($ contentTypes as $ type ) {
575
+ if ($ type ['policy ' ] === $ policy ) {
576
+ $ data [] = $ type ['name ' ];
577
+ }
578
+ }
579
+ return $ data ;
580
+ }
581
+
434
582
/**
435
583
* Check if node is configuration node
436
584
*
@@ -458,4 +606,20 @@ private function getAttributeValue(\DOMElement $attributeNode, $attributeName)
458
606
? $ attributeNode ->attributes ->getNamedItem ($ attributeName )->nodeValue
459
607
: null ;
460
608
}
609
+
610
+ /**
611
+ * Remove data from arra
612
+ *
613
+ * @param $searchValue
614
+ * @param $data
615
+ * @return array
616
+ */
617
+ private function removeDataInArray (string $ searchValue , array $ data ): array
618
+ {
619
+ $ removeKey = array_search ($ searchValue , $ data );
620
+ if ($ removeKey !== false ) {
621
+ unset($ data [$ removeKey ]);
622
+ }
623
+ return $ data ;
624
+ }
461
625
}
0 commit comments