Passed
Push — renovate/configure ( c923d4...2c70da )
by
unknown
20:13
created

display   B

Complexity

Total Complexity 49

Size/Duplication

Total Lines 323
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 98
dl 0
loc 323
rs 8.48
c 1
b 0
f 0
wmc 49

19 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A set_params() 0 4 3
A get_full_url() 0 9 2
A get_parental_depth() 0 4 2
A set_current_item() 0 22 3
A get_leaf_node() 0 3 4
A is_current_item() 0 3 2
A should_skip_branch() 0 3 2
A default_current_item() 0 11 2
A prepare_items() 0 39 4
A set_depth_limits() 0 4 3
A adjust_right_id() 0 5 2
A adjust_depth() 0 7 3
A get_current_item() 0 11 2
A display_navlist() 0 28 3
A get_current_path() 0 8 1
A needs_adjustment() 0 3 3
A must_not_expand() 0 3 4
A is_parent_of_current_item() 0 3 3

How to fix   Complexity   

Complex Class

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
2
3
/**
4
 *
5
 * @package sitemaker
6
 * @copyright (c) 2013 Daniel A. (blitze)
7
 * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
8
 *
9
 */
10
11
namespace blitze\sitemaker\services\menus;
12
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
	 * @return array
61
	 */
62
	public function display_navlist(array $data)
63
	{
64
		$this->set_current_item($data);
65
		$this->prepare_items($data['items']);
66
67
		if (sizeof($data['items']))
68
		{
69
			$this_depth = 0;
70
71
			$nodes = [];
72
			foreach ($data['items'] as $row)
73
			{
74
				$prev_depth = (int) $row['prev_depth'];
75
				$this_depth = (int) $row['this_depth'];
76
				$row['num_kids'] = $this->count_descendants($row);
77
78
				$nodes[] = array_merge(array_change_key_case($row, CASE_UPPER),
79
					array('close' => array_fill(0, abs($prev_depth - $this_depth), ''))
0 ignored issues
show
Bug introduced by
It seems like abs($prev_depth - $this_depth) can also be of type double; however, parameter $num of array_fill() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

79
					array('close' => array_fill(0, /** @scrutinizer ignore-type */ abs($prev_depth - $this_depth), ''))
Loading history...
80
				);
81
			}
82
83
			return array(
84
				'tree'	=> $nodes,
85
				'close'	=> array_fill(0, abs($this_depth - $this->min_depth), '')
86
			);
87
		}
88
89
		return [];
90
	}
91
92
	/**
93
	 * @param array $data
94
	 * @return bool
95
	 */
96
	protected function set_current_item(array $data)
97
	{
98
		$paths = (array) $data['paths'];
99
		$this->min_depth = 0;
100
101
		arsort($paths);
102
103
		$curr_path = $this->get_current_path();
104
		foreach ($paths as $item_id => $test_url)
105
		{
106
			if (strpos($curr_path, $test_url) !== false)
107
			{
108
				$row = $data['items'][$item_id];
109
				$this->adjust_depth($row);
110
				$this->current_item = $row;
111
112
				return true;
113
			}
114
		}
115
116
		$this->current_item = $this->default_current_item();
117
		return false;
118
	}
119
120
	/**
121
	 * @return string
122
	 */
123
	protected function get_current_path()
124
	{
125
		$curr_page = '/' . ltrim($this->user->page['page_dir'] . '/' . $this->user->page['page_name'], './');
126
		$curr_parts = explode('&', $this->user->page['query_string']);
127
128
		sort($curr_parts);
129
130
		return $curr_page . '?' . join('&', $curr_parts);
131
	}
132
133
	/**
134
	 * return void
135
	 */
136
	protected function default_current_item()
137
	{
138
		$this->max_depth = ($this->expanded) ? $this->max_depth : 0;
139
		$this->min_depth = 0;
140
141
		return array(
142
			$this->column_item_id	=> 0,
143
			$this->column_parent_id	=> 0,
144
			$this->column_left_id	=> 0,
145
			$this->column_right_id	=> 0,
146
			$this->column_depth		=> 0,
147
		);
148
	}
149
150
	/**
151
	 * @param array $data
152
	 * @return void
153
	 */
154
	protected function prepare_items(array &$data)
155
	{
156
		$leaf = array();
157
		$prev_depth = $this->min_depth;
158
		$this->parental_depth = array(0 => -1);
159
160
		foreach ($data as $item_id => $row)
161
		{
162
			// Skip branch
163
			if ($this->should_skip_branch($row, $leaf))
164
			{
165
				$this->adjust_right_id($leaf[$this->column_item_id], $data, $leaf);
166
				unset($data[$item_id]);
167
				continue;
168
			}
169
170
			[$is_current_item, $is_parent] = $this->get_current_item($row);
171
			$this_depth	= $this->get_parental_depth($row) + 1;
172
			$leaf = $this->get_leaf_node($row, $is_current_item, $is_parent);
173
174
			$this->parental_depth[$row[$this->pk]] = $this_depth;
175
176
			if ($row[$this->column_depth] < $this->min_depth)
177
			{
178
				unset($data[$item_id]);
179
				continue;
180
			}
181
182
			$data[$item_id] = array_merge($data[$item_id], array(
183
				'prev_depth'	=> $prev_depth,
184
				'this_depth'	=> $this_depth,
185
				'is_current'	=> $is_current_item,
186
				'is_parent'		=> $is_parent,
187
				'full_url'		=> $this->get_full_url($row),
188
			));
189
190
			$prev_depth = $this_depth;
191
		}
192
		unset($this->parental_depth, $data);
193
	}
194
195
	/**
196
	 * @param array $row
197
	 * @return int
198
	 */
199
	protected function get_parental_depth(array $row)
200
	{
201
		$parent_id = $row[$this->column_parent_id];
202
		return isset($this->parental_depth[$parent_id]) ? $this->parental_depth[$parent_id] : -1;
203
	}
204
205
	/**
206
	 * @param array $row
207
	 * @param array $leaf
208
	 * @return bool
209
	 */
210
	protected function should_skip_branch(array $row, array $leaf)
211
	{
212
		return (sizeof($leaf) && $row[$this->column_left_id] < $leaf[$this->column_right_id]);
213
	}
214
215
	/**
216
	 * @param array $row
217
	 * @return array
218
	 */
219
	protected function get_current_item(array $row)
220
	{
221
		$is_current_item = $is_parent = false;
222
223
		if (sizeof($this->current_item))
224
		{
225
			$is_current_item = $this->is_current_item($row);
226
			$is_parent = $this->is_parent_of_current_item($row);
227
		}
228
229
		return [$is_current_item, $is_parent];
230
	}
231
232
	/**
233
	 * @param array $row
234
	 * @return bool
235
	 */
236
	protected function is_current_item(array $row)
237
	{
238
		return ($row[$this->column_item_id] === $this->current_item[$this->column_item_id]) ? true : false;
239
	}
240
241
	/**
242
	 * @param array $row
243
	 * @return bool
244
	 */
245
	protected function is_parent_of_current_item(array $row)
246
	{
247
		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;
248
	}
249
250
	/**
251
	 * Does the branch end here?
252
	 *
253
	 * @param array $row
254
	 * @param bool $is_current_item
255
	 * @param bool $is_current_items_parent
256
	 * @return array
257
	 */
258
	protected function get_leaf_node(array $row, $is_current_item, $is_current_items_parent)
259
	{
260
		return ($this->must_not_expand($row, $is_current_items_parent) && !$is_current_item && $row['is_expandable']) ? $row : array();
261
	}
262
263
	/**
264
	 * @param array $row
265
	 * @param bool $is_current_items_parent
266
	 * @return bool
267
	 */
268
	protected function must_not_expand(array $row, $is_current_items_parent)
269
	{
270
		return ($row[$this->column_depth] === $this->max_depth || !$is_current_items_parent && !$this->expanded) ? true : false;
271
	}
272
273
	/**
274
	 * @param int $items_depth
275
	 * return bool
276
	 * @return bool
277
	 */
278
	protected function needs_adjustment($items_depth)
279
	{
280
		return (!$this->expanded && $items_depth >= $this->max_depth) ? true : false;
281
	}
282
283
	/**
284
	 * @param array $row
285
	 * @return void
286
	 */
287
	protected function adjust_depth(array $row)
288
	{
289
		$depth = (int) $row[$this->column_depth];
290
		if ($this->needs_adjustment($depth))
291
		{
292
			$adjustment = ($this->count_descendants($row)) ? 1 : 0;
293
			$this->set_depth_limits($depth, $adjustment);
294
		}
295
	}
296
297
	/**
298
	 * @param int $item_id
299
	 * @param array $data
300
	 * @param array $leaf
301
	 * @return void
302
	 */
303
	protected function adjust_right_id($item_id, array &$data, array $leaf)
304
	{
305
		if (isset($data[$item_id]))
306
		{
307
			$data[$leaf[$this->column_item_id]][$this->column_right_id] -= 2;
308
		}
309
	}
310
311
	/**
312
	 * Append session id to local, non-directory paths
313
	 *
314
	 * @param array $row
315
	 * @return string
316
	 */
317
	protected function get_full_url(array $row)
318
	{
319
		$full_url = $row['full_url'];
320
		if ($row['is_navigable'])
321
		{
322
			$full_url = append_sid($row['full_url'], false, false);
323
		}
324
325
		return $full_url;
326
	}
327
328
	/**
329
	 * @param int $depth
330
	 * @param int $adjustment
331
	 */
332
	protected function set_depth_limits($depth, $adjustment)
333
	{
334
		$this->min_depth = ($this->max_depth && $depth >= $this->max_depth) ? $depth - $this->max_depth + $adjustment : 0;
335
		$this->max_depth = $depth + $adjustment;
336
	}
337
}
338