Completed
Push — develop ( f9723d...671ae6 )
by Daniel
08:23
created

display   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 290
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 6
Bugs 3 Features 1
Metric Value
wmc 43
c 6
b 3
f 1
lcom 1
cbo 1
dl 0
loc 290
ccs 128
cts 128
cp 1
rs 8.3157

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A set_params() 0 5 1
A display_navlist() 0 20 3
A generate_breadcrumb() 0 4 1
B prepare_items() 0 47 6
A set_current_item() 0 20 3
A default_current_item() 0 13 2
A is_current_path() 0 4 4
A is_current_item() 0 4 2
B set_parental_depth() 0 11 6
A close_open_tags() 0 7 2
A adjust_right_id() 0 7 2
A find_parents() 0 13 3
A needs_adjustment() 0 4 2
B adjust_depth() 0 10 5

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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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
 * @package sitemaker
5
 * @copyright (c) 2013 Daniel A. (blitze)
6
 * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
7
 *
8
 */
9
10
namespace blitze\sitemaker\services\menus;
11
12
class display extends \blitze\sitemaker\services\tree\display
13
{
14
	/** @var \phpbb\template\template */
15
	protected $template;
16
17
	/** @var \phpbb\user */
18
	protected $user;
19
20
	/** @var bool */
21
	private $expanded = false;
22
23
	/** @var integer */
24
	private $max_depth = 0;
25
26
	/** @var integer */
27
	private $min_depth = 0;
28
29
	/** @var array */
30
	private $parental_depth;
31
32
	/** @var array */
33
	private $current_item;
34
35
	/**
36
	 * Construct
37
	 *
38
	 * @param \phpbb\db\driver\driver_interface		$db             	Database connection
39
	 * @param \phpbb\template\template				$template			Template object
40
	 * @param \phpbb\user							$user				User Object
41
	 * @param string								$menu_items_table	Menu Items table
42
	 * @param string								$pk					Primary key
43
	 */
44 18
	public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\template\template $template, \phpbb\user $user, $menu_items_table, $pk)
45
	{
46 18
		parent::__construct($db, $menu_items_table, $pk);
47
48 18
		$this->template = $template;
49 18
		$this->user = $user;
50 18
	}
51
52
	/**
53
	 * @param array $params
54
	 * @return void
55
	 */
56 7
	public function set_params(array $params)
57
	{
58 7
		$this->expanded = (bool) $params['expanded'];
59 7
		$this->max_depth = (int) $params['max_depth'];
60 7
	}
61
62
	/**
63
	 * @param array $data
64
	 * @param \phpbb\template\twig\twig $template
65
	 * @param string $handle
66
	 * @return void
67
	 */
68 7
	public function display_navlist(array $data, \phpbb\template\twig\twig &$template, $handle = 'tree')
69
	{
70 7
		$this->prepare_items($data);
71
72 7
		if (sizeof($data))
73 7
		{
74 7
			$this_depth = 0;
75 7
			foreach ($data as $row)
76
			{
77 7
				$prev_depth = $row['prev_depth'];
78 7
				$this_depth = $row['this_depth'];
79 7
				$row['num_kids'] = $this->count_descendants($row);
80
81 7
				$template->assign_block_vars($handle, array_change_key_case($row, CASE_UPPER));
82 7
				$this->close_open_tags($template, $handle . '.close', abs($prev_depth - $this_depth));
83 7
			}
84
85 7
			$this->close_open_tags($template, 'close_' . $handle, ($this_depth - $this->min_depth));
86 7
		}
87 7
	}
88
89
	/**
90
	 * @param array $data
91
	 * @return void
92
	 */
93 5
	public function generate_breadcrumb(array $data)
94
	{
95 5
		$this->find_parents($data, $this->current_item['parent_id']);
96 5
	}
97
98
	/**
99
	 * @param array $data
100
	 * @return void
101
	 */
102 7
	protected function prepare_items(array &$data)
103
	{
104 7
		$this->set_current_item($data);
105
106 7
		$prev_depth = $this->min_depth;
107 7
		$this->parental_depth = array(0 => -1);
108
109 7
		foreach ($data as $item_id => $row)
110
		{
111
			// Skip branch
112 7
			if (isset($leaf))
113 7
			{
114 6
				if ($row['left_id'] < $leaf['right_id'])
115 6
				{
116 4
					$this->adjust_right_id($leaf['item_id'], $data, $leaf);
117 4
					unset($data[$item_id]);
118 4
					continue;
119
				}
120 6
				unset($leaf);
121 6
			}
122
123 7
			$is_current_item = $this->is_current_item($row);
124 7
			$this_depth	= $this->parental_depth[$row['parent_id']] + 1;
125
126 7
			$this->set_parental_depth($row, $this_depth, $leaf, $is_current_item);
127
128 7
			if ($row['depth'] == $this->max_depth)
129 7
			{
130 6
				$leaf = $row;
131 6
			}
132
133 7
			if ($row['depth'] < $this->min_depth)
134 7
			{
135 2
				unset($data[$item_id]);
136 2
				continue;
137
			}
138
139 7
			$data[$item_id] = array_merge($data[$item_id], array(
140 7
				'prev_depth'	=> $prev_depth,
141 7
				'this_depth'	=> $this_depth,
142 7
				'is_current'	=> $is_current_item,
143 7
				'full_url'		=> append_sid($row['full_url']),
144 7
			));
145
146 7
			$prev_depth = $this_depth;
147 7
		}
148 7
	}
149
150
	/**
151
	 * @param array $data
152
	 * @return bool
153
	 */
154 7
	protected function set_current_item(array $data)
155
	{
156 7
		$curr_page = $this->user->page['page_name'];
157 7
		$curr_parts = explode('&', $this->user->page['query_string']);
158
159 7
		$data = array_values($data);
160 7
		for ($i = 0, $size = sizeof($data); $i < $size; $i++)
161
		{
162 7
			$row = $data[$i];
163 7
			if ($this->is_current_path($curr_page, $curr_parts, $row))
164 7
			{
165 6
				$this->adjust_depth($row);
166 6
				$this->current_item = $row;
167 6
				return true;
168
			}
169 4
		}
170
171 1
		$this->current_item = $this->default_current_item();
172 1
		return false;
173
	}
174
175
	/**
176
	 * return void
177
	 */
178 1
	protected function default_current_item()
179
	{
180 1
		$this->max_depth = ($this->expanded) ? $this->max_depth : 0;
181 1
		$this->min_depth = 0;
182
183
		return array(
184 1
			'item_id'	=> 0,
185 1
			'parent_id'	=> 0,
186 1
			'left_id'	=> 0,
187 1
			'right_id'	=> 0,
188 1
			'depth'		=> 0,
189 1
		);
190
	}
191
192
	/**
193
	 * @param string $curr_page
194
	 * @param array $curr_parts
195
	 * @param array $row
196
	 * @return bool
197
	 */
198 7
	protected function is_current_path($curr_page, array $curr_parts, array $row)
199
	{
200 7
		return ($curr_page == $row['url_path'] && (!sizeof($row['url_query']) || sizeof(array_intersect($row['url_query'], $curr_parts)))) ? true : false;
201
	}
202
203
	/**
204
	 * @param array $row
205
	 * @return bool
206
	 */
207 7
	protected function is_current_item(array $row)
208
	{
209 7
		return ($row['item_id'] === $this->current_item['item_id']) ? true : false;
210
	}
211
212
	/**
213
	 * @param array $row
214
	 * @param int $depth
215
	 * @param array|null $leaf
216
	 * @param bool $is_current_item
217
	 * @return void
218
	 */
219 7
	protected function set_parental_depth(array $row, $depth, &$leaf, $is_current_item)
220
	{
221 7
		if ($is_current_item || $this->expanded || !$row['item_url'] || ($row['left_id'] < $this->current_item['left_id'] && $row['right_id'] > $this->current_item['right_id']))
222 7
		{
223 6
			$this->parental_depth[$row[$this->pk]] = $depth;
224 6
		}
225
		else
226
		{
227 4
			$leaf = $row;
228
		}
229 7
	}
230
231
	/**
232
	 * @param \phpbb\template\twig\twig $template
233
	 * @param string $handle
234
	 * @param int $repeat
235
	 * @return void
236
	 */
237 7
	protected function close_open_tags(\phpbb\template\twig\twig &$template, $handle, $repeat)
238
	{
239 7
		for ($i = 0; $i < $repeat; $i++)
240
		{
241 5
			$template->assign_block_vars($handle, array());
242 5
		}
243 7
	}
244
245
	/**
246
	 * @param int $items_depth
247
	 * return bool
248
	 */
249 6
	protected function needs_adjustment($items_depth)
250
	{
251 6
		return ($items_depth >= $this->max_depth) ? true : false;
252
	}
253
254
	/**
255
	 * @param array $row
256
	 * @return void
257
	 */
258 6
	protected function adjust_depth(array $row)
259
	{
260 6
		$depth = (int) $row['depth'];
261 6
		if ($this->needs_adjustment($depth))
262 6
		{
263 3
			$adjustment = ($this->count_descendants($row)) ? 1 : 0;
264 3
			$this->min_depth = ($this->max_depth && $depth >= $this->max_depth) ? $depth - $this->max_depth + $adjustment : 0;
265 3
			$this->max_depth = $depth + $adjustment;
266 3
		}
267 6
	}
268
269
	/**
270
	 * @param int $item_id
271
	 * @param array $data
272
	 * @param array $leaf
273
	 * @return void
274
	 */
275 4
	protected function adjust_right_id($item_id, array &$data, array $leaf)
276
	{
277 4
		if (isset($data[$item_id]))
278 4
		{
279 4
			$data[$leaf['item_id']]['right_id'] -= 2;
280 4
		}
281 4
	}
282
283
	/**
284
	 * @param array $data
285
	 * @param int $parent_id
286
	 * @return void
287
	 */
288 5
	protected function find_parents(array $data, $parent_id)
289
	{
290 5
		if (isset($data[$parent_id]) && $data[$parent_id]['item_url'] !== 'index.php')
291 5
		{
292 2
			$row = $data[$parent_id];
293 2
			$this->template->alter_block_array('navlinks', array(
294 2
				'FORUM_NAME'	=> $row['item_title'],
295 2
				'U_VIEW_FORUM'	=> $row['full_url'],
296 2
			));
297
298 2
			$this->find_parents($data, $row['parent_id']);
299 2
		}
300 5
	}
301
}
302