15
15
*/
16
16
class ExtractDataFromCategoryTree
17
17
{
18
+ const START_CATEGORY_FETCH_LEVEL = 1 ;
19
+
18
20
/**
19
21
* @var Hydrator
20
22
*/
21
23
private $ categoryHydrator ;
22
24
25
+ /**
26
+ * @var CategoryInterface;
27
+ */
28
+ private $ iteratingCategory ;
29
+
23
30
/**
24
31
* @param Hydrator $categoryHydrator
25
32
*/
@@ -42,14 +49,61 @@ public function execute(\Iterator $iterator): array
42
49
/** @var CategoryInterface $category */
43
50
$ category = $ iterator ->current ();
44
51
$ iterator ->next ();
45
- $ nextCategory = $ iterator ->current ();
46
- $ tree [$ category ->getId ()] = $ this ->categoryHydrator ->hydrateCategory ($ category );
47
- $ tree [$ category ->getId ()]['model ' ] = $ category ;
48
- if ($ nextCategory && (int ) $ nextCategory ->getLevel () !== (int ) $ category ->getLevel ()) {
49
- $ tree [$ category ->getId ()]['children ' ] = $ this ->execute ($ iterator );
52
+
53
+ $ pathElements = explode ("/ " , $ category ->getPath ());
54
+ $ this ->iteratingCategory = $ category ;
55
+
56
+ $ currentLevelTree = $ this ->generateLevelTree ($ pathElements , self ::START_CATEGORY_FETCH_LEVEL );
57
+ if (empty ($ tree )) {
58
+ $ tree = $ currentLevelTree ;
50
59
}
60
+ $ tree = $ this ->mergeCategoriesTrees ($ currentLevelTree , $ tree );
51
61
}
52
62
53
63
return $ tree ;
54
64
}
65
+
66
+ /**
67
+ * Merge together complex categories tree
68
+ *
69
+ * @param array $tree1
70
+ * @param array $tree2
71
+ * @return array
72
+ */
73
+ private function mergeCategoriesTrees (array &$ tree1 , array &$ tree2 ): array
74
+ {
75
+ $ mergedTree = $ tree1 ;
76
+ foreach ($ tree2 as $ currentKey => &$ value ) {
77
+ if (is_array ($ value ) && isset ($ mergedTree [$ currentKey ]) && is_array ($ mergedTree [$ currentKey ])) {
78
+ $ mergedTree [$ currentKey ] = $ this ->mergeCategoriesTrees ($ mergedTree [$ currentKey ], $ value );
79
+ } else {
80
+ $ mergedTree [$ currentKey ] = $ value ;
81
+ }
82
+ }
83
+ return $ mergedTree ;
84
+ }
85
+
86
+ /**
87
+ * Recursive method to generate tree for one category path
88
+ *
89
+ * @param $elements
90
+ * @param $index
91
+ * @return array
92
+ */
93
+ private function generateLevelTree ($ elements , $ index ): array
94
+ {
95
+
96
+ $ tree = [];
97
+ $ tree [$ elements [$ index ]]['id ' ] = $ elements [$ index ];
98
+ if ($ index === count ($ elements ) - 1 ) {
99
+ $ tree [$ elements [$ index ]] = $ this ->categoryHydrator ->hydrateCategory ($ this ->iteratingCategory );
100
+ $ tree [$ elements [$ index ]]['model ' ] = $ this ->iteratingCategory ;
101
+ }
102
+ $ currentIndex = $ index ;
103
+ $ index ++;
104
+ if (isset ($ elements [$ index ])) {
105
+ $ tree [$ elements [$ currentIndex ]]['children ' ] = $ this ->generateLevelTree ($ elements , $ index );
106
+ }
107
+ return $ tree ;
108
+ }
55
109
}
0 commit comments