Passed
Push — renovate/configure ( 3d37a9...8f147e )
by
unknown
19:53
created

display::get_current_item()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 11
rs 10
c 0
b 0
f 0
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
	 * @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)
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->current_item of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
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)
326
	{
327
		$full_url = $row['full_url'];
328
		if ($row['is_navigable'])
329
		{
330
			$full_url = append_sid($row['full_url'], false, false);
331
		}
332
333
		return $full_url;
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