Total Complexity | 51 |
Total Lines | 331 |
Duplicated Lines | 0 % |
Changes | 1 | ||
Bugs | 0 | Features | 0 |
Complex classes like display often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use display, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
13 | class display extends \blitze\sitemaker\services\tree\display |
||
14 | { |
||
15 | /** @var \phpbb\user */ |
||
16 | protected $user; |
||
17 | |||
18 | /** @var bool */ |
||
19 | private $expanded = true; |
||
20 | |||
21 | /** @var integer */ |
||
22 | private $max_depth = 100; |
||
23 | |||
24 | /** @var integer */ |
||
25 | private $min_depth = 0; |
||
26 | |||
27 | /** @var array */ |
||
28 | private $parental_depth; |
||
29 | |||
30 | /** @var array */ |
||
31 | private $current_item; |
||
32 | |||
33 | /** |
||
34 | * Construct |
||
35 | * |
||
36 | * @param \phpbb\db\driver\driver_interface $db Database connection |
||
37 | * @param \phpbb\user $user User Object |
||
38 | * @param string $menu_items_table Menu Items table |
||
39 | * @param string $pk Primary key |
||
40 | */ |
||
41 | public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, $menu_items_table, $pk) |
||
42 | { |
||
43 | parent::__construct($db, $menu_items_table, $pk); |
||
44 | |||
45 | $this->user = $user; |
||
46 | } |
||
47 | |||
48 | /** |
||
49 | * @param array $params |
||
50 | * @return void |
||
51 | */ |
||
52 | public function set_params(array $params) |
||
53 | { |
||
54 | $this->expanded = (bool) ((isset($params['expanded'])) ? $params['expanded'] : true); |
||
55 | $this->max_depth = (int) ((isset($params['max_depth'])) ? $params['max_depth'] : 100); |
||
56 | } |
||
57 | |||
58 | /** |
||
59 | * @param array $data |
||
60 | * @param \phpbb\template\twig\twig $template |
||
61 | * @param string $handle |
||
62 | * @return void |
||
63 | */ |
||
64 | public function display_navlist(array $data, \phpbb\template\twig\twig &$template, $handle = 'tree') |
||
65 | { |
||
66 | $this->set_current_item($data); |
||
67 | $this->prepare_items($data['items']); |
||
68 | |||
69 | if (sizeof($data['items'])) |
||
70 | { |
||
71 | $this_depth = 0; |
||
72 | foreach ($data['items'] as $row) |
||
73 | { |
||
74 | $prev_depth = $row['prev_depth']; |
||
75 | $this_depth = $row['this_depth']; |
||
76 | $row['num_kids'] = $this->count_descendants($row); |
||
77 | |||
78 | $template->assign_block_vars($handle, array_change_key_case($row, CASE_UPPER)); |
||
79 | $this->close_open_tags($template, $handle . '.close', (int) abs($prev_depth - $this_depth)); |
||
80 | } |
||
81 | |||
82 | $this->close_open_tags($template, 'close_' . $handle, ($this_depth - $this->min_depth)); |
||
83 | } |
||
84 | } |
||
85 | |||
86 | /** |
||
87 | * @param array $data |
||
88 | * @return bool |
||
89 | */ |
||
90 | protected function set_current_item(array $data) |
||
91 | { |
||
92 | $paths = (array) $data['paths']; |
||
93 | $this->min_depth = 0; |
||
94 | |||
95 | arsort($paths); |
||
96 | |||
97 | $curr_path = $this->get_current_path(); |
||
98 | foreach ($paths as $item_id => $test_url) |
||
99 | { |
||
100 | if (strpos($curr_path, $test_url) !== false) |
||
101 | { |
||
102 | $row = $data['items'][$item_id]; |
||
103 | $this->adjust_depth($row); |
||
104 | $this->current_item = $row; |
||
105 | |||
106 | return true; |
||
107 | } |
||
108 | } |
||
109 | |||
110 | $this->current_item = $this->default_current_item(); |
||
111 | return false; |
||
112 | } |
||
113 | |||
114 | /** |
||
115 | * @return string |
||
116 | */ |
||
117 | protected function get_current_path() |
||
118 | { |
||
119 | $curr_page = '/' . ltrim($this->user->page['page_dir'] . '/' . $this->user->page['page_name'], './'); |
||
120 | $curr_parts = explode('&', $this->user->page['query_string']); |
||
121 | |||
122 | sort($curr_parts); |
||
123 | |||
124 | return $curr_page . '?' . join('&', $curr_parts); |
||
125 | } |
||
126 | |||
127 | /** |
||
128 | * return void |
||
129 | */ |
||
130 | protected function default_current_item() |
||
131 | { |
||
132 | $this->max_depth = ($this->expanded) ? $this->max_depth : 0; |
||
133 | $this->min_depth = 0; |
||
134 | |||
135 | return array( |
||
136 | $this->column_item_id => 0, |
||
137 | $this->column_parent_id => 0, |
||
138 | $this->column_left_id => 0, |
||
139 | $this->column_right_id => 0, |
||
140 | $this->column_depth => 0, |
||
141 | ); |
||
142 | } |
||
143 | |||
144 | /** |
||
145 | * @param array $data |
||
146 | * @return void |
||
147 | */ |
||
148 | protected function prepare_items(array &$data) |
||
149 | { |
||
150 | $leaf = array(); |
||
151 | $prev_depth = $this->min_depth; |
||
152 | $this->parental_depth = array(0 => -1); |
||
153 | |||
154 | foreach ($data as $item_id => $row) |
||
155 | { |
||
156 | // Skip branch |
||
157 | if ($this->should_skip_branch($row, $leaf)) |
||
158 | { |
||
159 | $this->adjust_right_id($leaf[$this->column_item_id], $data, $leaf); |
||
160 | unset($data[$item_id]); |
||
161 | continue; |
||
162 | } |
||
163 | |||
164 | [$is_current_item, $is_parent] = $this->get_current_item($row); |
||
165 | $this_depth = $this->get_parental_depth($row) + 1; |
||
166 | $leaf = $this->get_leaf_node($row, $is_current_item, $is_parent); |
||
167 | |||
168 | $this->parental_depth[$row[$this->pk]] = $this_depth; |
||
169 | |||
170 | if ($row[$this->column_depth] < $this->min_depth) |
||
171 | { |
||
172 | unset($data[$item_id]); |
||
173 | continue; |
||
174 | } |
||
175 | |||
176 | $data[$item_id] = array_merge($data[$item_id], array( |
||
177 | 'prev_depth' => $prev_depth, |
||
178 | 'this_depth' => $this_depth, |
||
179 | 'is_current' => $is_current_item, |
||
180 | 'is_parent' => $is_parent, |
||
181 | 'full_url' => $this->get_full_url($row), |
||
182 | )); |
||
183 | |||
184 | $prev_depth = $this_depth; |
||
185 | } |
||
186 | unset($this->parental_depth, $data); |
||
187 | } |
||
188 | |||
189 | /** |
||
190 | * @param array $row |
||
191 | * @return int |
||
192 | */ |
||
193 | protected function get_parental_depth(array $row) |
||
194 | { |
||
195 | $parent_id = $row[$this->column_parent_id]; |
||
196 | return isset($this->parental_depth[$parent_id]) ? $this->parental_depth[$parent_id] : -1; |
||
197 | } |
||
198 | |||
199 | /** |
||
200 | * @param array $row |
||
201 | * @param array $leaf |
||
202 | * @return bool |
||
203 | */ |
||
204 | protected function should_skip_branch(array $row, array $leaf) |
||
205 | { |
||
206 | return (sizeof($leaf) && $row[$this->column_left_id] < $leaf[$this->column_right_id]); |
||
207 | } |
||
208 | |||
209 | /** |
||
210 | * @param array $row |
||
211 | * @return array |
||
212 | */ |
||
213 | protected function get_current_item(array $row) |
||
214 | { |
||
215 | $is_current_item = $is_parent = false; |
||
216 | |||
217 | if ($this->current_item) |
||
|
|||
218 | { |
||
219 | $is_current_item = $this->is_current_item($row); |
||
220 | $is_parent = $this->is_parent_of_current_item($row); |
||
221 | } |
||
222 | |||
223 | return [$is_current_item, $is_parent]; |
||
224 | } |
||
225 | |||
226 | /** |
||
227 | * @param array $row |
||
228 | * @return bool |
||
229 | */ |
||
230 | protected function is_current_item(array $row) |
||
231 | { |
||
232 | return ($row[$this->column_item_id] === $this->current_item[$this->column_item_id]) ? true : false; |
||
233 | } |
||
234 | |||
235 | /** |
||
236 | * @param array $row |
||
237 | * @return bool |
||
238 | */ |
||
239 | protected function is_parent_of_current_item(array $row) |
||
240 | { |
||
241 | return ($row[$this->column_left_id] < $this->current_item[$this->column_left_id] && $row[$this->column_right_id] > $this->current_item[$this->column_right_id]) ? true : false; |
||
242 | } |
||
243 | |||
244 | /** |
||
245 | * Does the branch end here? |
||
246 | * |
||
247 | * @param array $row |
||
248 | * @param bool $is_current_item |
||
249 | * @param bool $is_current_items_parent |
||
250 | * @return array |
||
251 | */ |
||
252 | protected function get_leaf_node(array $row, $is_current_item, $is_current_items_parent) |
||
253 | { |
||
254 | return ($this->must_not_expand($row, $is_current_items_parent) && !$is_current_item && $row['is_expandable']) ? $row : array(); |
||
255 | } |
||
256 | |||
257 | /** |
||
258 | * @param array $row |
||
259 | * @param bool $is_current_items_parent |
||
260 | * @return bool |
||
261 | */ |
||
262 | protected function must_not_expand(array $row, $is_current_items_parent) |
||
263 | { |
||
264 | return ($row[$this->column_depth] === $this->max_depth || !$is_current_items_parent && !$this->expanded) ? true : false; |
||
265 | } |
||
266 | |||
267 | /** |
||
268 | * @param \phpbb\template\twig\twig $template |
||
269 | * @param string $handle |
||
270 | * @param int $repeat |
||
271 | * @return void |
||
272 | */ |
||
273 | protected function close_open_tags(\phpbb\template\twig\twig &$template, $handle, $repeat) |
||
274 | { |
||
275 | for ($i = 0; $i < $repeat; $i++) |
||
276 | { |
||
277 | $template->assign_block_vars($handle, array()); |
||
278 | } |
||
279 | } |
||
280 | |||
281 | /** |
||
282 | * @param int $items_depth |
||
283 | * return bool |
||
284 | * @return bool |
||
285 | */ |
||
286 | protected function needs_adjustment($items_depth) |
||
287 | { |
||
288 | return (!$this->expanded && $items_depth >= $this->max_depth) ? true : false; |
||
289 | } |
||
290 | |||
291 | /** |
||
292 | * @param array $row |
||
293 | * @return void |
||
294 | */ |
||
295 | protected function adjust_depth(array $row) |
||
296 | { |
||
297 | $depth = (int) $row[$this->column_depth]; |
||
298 | if ($this->needs_adjustment($depth)) |
||
299 | { |
||
300 | $adjustment = ($this->count_descendants($row)) ? 1 : 0; |
||
301 | $this->set_depth_limits($depth, $adjustment); |
||
302 | } |
||
303 | } |
||
304 | |||
305 | /** |
||
306 | * @param int $item_id |
||
307 | * @param array $data |
||
308 | * @param array $leaf |
||
309 | * @return void |
||
310 | */ |
||
311 | protected function adjust_right_id($item_id, array &$data, array $leaf) |
||
312 | { |
||
313 | if (isset($data[$item_id])) |
||
314 | { |
||
315 | $data[$leaf[$this->column_item_id]][$this->column_right_id] -= 2; |
||
316 | } |
||
317 | } |
||
318 | |||
319 | /** |
||
320 | * Append session id to local, non-directory paths |
||
321 | * |
||
322 | * @param array $row |
||
323 | * @return string |
||
324 | */ |
||
325 | protected function get_full_url(array $row) |
||
334 | } |
||
335 | |||
336 | /** |
||
337 | * @param int $depth |
||
338 | * @param int $adjustment |
||
339 | */ |
||
340 | protected function set_depth_limits($depth, $adjustment) |
||
341 | { |
||
342 | $this->min_depth = ($this->max_depth && $depth >= $this->max_depth) ? $depth - $this->max_depth + $adjustment : 0; |
||
343 | $this->max_depth = $depth + $adjustment; |
||
344 | } |
||
345 | } |
||
346 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.