These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Kunstmaan\AdminBundle\Helper\Menu; |
||
4 | |||
5 | use Symfony\Component\DependencyInjection\ContainerInterface; |
||
6 | use Symfony\Component\HttpFoundation\Request; |
||
7 | use Symfony\Component\HttpFoundation\RequestStack; |
||
8 | |||
9 | /** |
||
10 | * The MenuBuilder will build the top menu and the side menu of the admin interface |
||
11 | */ |
||
12 | class MenuBuilder |
||
13 | { |
||
14 | /** |
||
15 | * @var MenuAdaptorInterface[] |
||
16 | */ |
||
17 | private $adaptors = []; |
||
18 | |||
19 | /** |
||
20 | * @var MenuAdaptorInterface[] |
||
21 | */ |
||
22 | private $sorted = []; |
||
23 | |||
24 | /** |
||
25 | * @var TopMenuItem[] |
||
26 | */ |
||
27 | private $topMenuItems = null; |
||
28 | |||
29 | /** |
||
30 | * @var ContainerInterface |
||
31 | */ |
||
32 | private $container; |
||
33 | |||
34 | /** |
||
35 | * @var MenuItem|null |
||
36 | */ |
||
37 | private $currentCache = null; |
||
38 | |||
39 | /** @var RequestStack */ |
||
40 | private $requestStack; |
||
41 | |||
42 | /** |
||
43 | * @param ContainerInterface|RequestStack $requestStack |
||
44 | */ |
||
45 | 7 | View Code Duplication | public function __construct(/* RequestStack */ $requestStack) |
46 | { |
||
47 | 7 | if ($requestStack instanceof ContainerInterface) { |
|
48 | 1 | @trigger_error(sprintf('Passing the container as the first argument of "%s" is deprecated in KunstmaanAdminBundle 5.4 and will be removed in KunstmaanAdminBundle 6.0. Inject the "request_stack" service instead.', __CLASS__), E_USER_DEPRECATED); |
|
49 | |||
50 | 1 | $this->container = $requestStack; |
|
51 | 1 | $this->requestStack = $this->container->get('request_stack'); |
|
52 | |||
53 | 1 | return; |
|
54 | } |
||
55 | |||
56 | 6 | $this->requestStack = $requestStack; |
|
57 | 6 | } |
|
58 | |||
59 | /** |
||
60 | * Add menu adaptor |
||
61 | */ |
||
62 | 2 | public function addAdaptMenu(MenuAdaptorInterface $adaptor, $priority = 0) |
|
63 | { |
||
64 | 2 | $this->adaptors[$priority][] = $adaptor; |
|
65 | 2 | unset($this->sorted); |
|
66 | 2 | } |
|
67 | |||
68 | /** |
||
69 | * Get current menu item |
||
70 | * |
||
71 | * @return MenuItem|null |
||
72 | */ |
||
73 | 4 | public function getCurrent() |
|
74 | { |
||
75 | 4 | if ($this->currentCache !== null) { |
|
76 | 1 | return $this->currentCache; |
|
77 | } |
||
78 | /* @var $active MenuItem */ |
||
79 | 4 | $active = null; |
|
80 | do { |
||
81 | /* @var MenuItem[] $children */ |
||
82 | 4 | $children = $this->getChildren($active); |
|
83 | 4 | $foundActiveChild = false; |
|
84 | 4 | foreach ($children as $child) { |
|
85 | 4 | if ($child->getActive()) { |
|
86 | 3 | $foundActiveChild = true; |
|
87 | 3 | $active = $child; |
|
88 | |||
89 | 3 | break; |
|
90 | } |
||
91 | } |
||
92 | 4 | } while ($foundActiveChild); |
|
93 | 4 | $this->currentCache = $active; |
|
94 | |||
95 | 4 | return $active; |
|
96 | } |
||
97 | |||
98 | /** |
||
99 | * Get breadcrumb path for current menu item |
||
100 | * |
||
101 | * @return MenuItem[] |
||
102 | */ |
||
103 | 1 | public function getBreadCrumb() |
|
104 | { |
||
105 | 1 | $result = []; |
|
106 | 1 | $current = $this->getCurrent(); |
|
107 | 1 | while (!\is_null($current)) { |
|
108 | 1 | array_unshift($result, $current); |
|
109 | 1 | $current = $current->getParent(); |
|
110 | } |
||
111 | |||
112 | 1 | return $result; |
|
113 | } |
||
114 | |||
115 | /** |
||
116 | * Get top parent menu of current menu item |
||
117 | * |
||
118 | * @return TopMenuItem|null |
||
119 | */ |
||
120 | 3 | public function getLowestTopChild() |
|
121 | { |
||
122 | 3 | $current = $this->getCurrent(); |
|
123 | 3 | while (!\is_null($current)) { |
|
124 | 2 | if ($current instanceof TopMenuItem) { |
|
125 | 2 | return $current; |
|
126 | } |
||
127 | 1 | $current = $current->getParent(); |
|
128 | } |
||
129 | |||
130 | 1 | return null; |
|
131 | } |
||
132 | |||
133 | /** |
||
134 | * Get all top menu items |
||
135 | * |
||
136 | * @return MenuItem[] |
||
137 | */ |
||
138 | 2 | public function getTopChildren() |
|
139 | { |
||
140 | 2 | if (\is_null($this->topMenuItems)) { |
|
141 | /* @var $request Request */ |
||
142 | 2 | $request = $this->requestStack->getCurrentRequest(); |
|
143 | 2 | $this->topMenuItems = []; |
|
144 | 2 | foreach ($this->getAdaptors() as $menuAdaptor) { |
|
0 ignored issues
–
show
|
|||
145 | 2 | $menuAdaptor->adaptChildren($this, $this->topMenuItems, null, $request); |
|
146 | } |
||
147 | } |
||
148 | |||
149 | 2 | return $this->topMenuItems; |
|
150 | } |
||
151 | |||
152 | /** |
||
153 | * Get immediate children of the specified menu item |
||
154 | * |
||
155 | * @param MenuItem $parent |
||
156 | * |
||
157 | * @return MenuItem[] |
||
158 | */ |
||
159 | 1 | public function getChildren(MenuItem $parent = null) |
|
160 | { |
||
161 | 1 | if ($parent === null) { |
|
162 | 1 | return $this->getTopChildren(); |
|
163 | } |
||
164 | /* @var $request Request */ |
||
165 | 1 | $request = $this->requestStack->getCurrentRequest(); |
|
166 | 1 | $result = []; |
|
167 | 1 | foreach ($this->getAdaptors() as $menuAdaptor) { |
|
0 ignored issues
–
show
The expression
$this->getAdaptors() of type null|array<integer,objec...\MenuAdaptorInterface>> is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
Loading history...
|
|||
168 | 1 | $menuAdaptor->adaptChildren($this, $result, $parent, $request); |
|
169 | } |
||
170 | |||
171 | 1 | return $result; |
|
172 | } |
||
173 | |||
174 | 2 | private function getAdaptors() |
|
175 | { |
||
176 | 2 | if (!isset($this->sorted)) { |
|
177 | 2 | $this->sortAdaptors(); |
|
178 | } |
||
179 | |||
180 | 2 | return $this->sorted; |
|
181 | } |
||
182 | |||
183 | /** |
||
184 | * Sorts the internal list of adaptors by priority. |
||
185 | */ |
||
186 | 2 | View Code Duplication | private function sortAdaptors() |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
187 | { |
||
188 | 2 | $this->sorted = []; |
|
189 | |||
190 | 2 | if (isset($this->adaptors)) { |
|
191 | 2 | krsort($this->adaptors); |
|
192 | 2 | $this->sorted = array_merge(...$this->adaptors); |
|
193 | } |
||
194 | 2 | } |
|
195 | } |
||
196 |
There are different options of fixing this problem.
If you want to be on the safe side, you can add an additional type-check:
If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:
Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.