Completed
Push — master ( 2f974b...edb932 )
by Daniel
08:50
created

display::set_params()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 3
Bugs 1 Features 1
Metric Value
c 3
b 1
f 1
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 9.4286
cc 1
eloc 3
nc 1
nop 1
crap 1
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 12
	public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\template\template $template, \phpbb\user $user, $menu_items_table, $pk)
45
	{
46 12
		parent::__construct($db, $menu_items_table, $pk);
47
48 12
		$this->template = $template;
49 12
		$this->user = $user;
50 12
	}
51
52 7
	public function set_params(array $params)
53
	{
54 7
		$this->expanded = (bool) $params['expanded'];
55 7
		$this->max_depth = (int) $params['max_depth'];
56 7
	}
57
58
	/**
59
	 *
60
	 */
61 7
	public function display_list(array $data, \phpbb\template\twig\twig &$template, $handle = 'tree')
62
	{
63 7
		$this->prepare_items($data);
64
65 7
		if (sizeof($data))
66 7
		{
67 7
			foreach ($data as $row)
68
			{
69 7
				$prev_depth = $row['prev_depth'];
70 7
				$this_depth = $row['this_depth'];
71 7
				$row['num_kids'] = $this->count_descendants($row);
72
73 7
				$template->assign_block_vars($handle, array_change_key_case($row, CASE_UPPER));
74 7
				$this->close_open_tags($template, $handle . '.close', abs($prev_depth - $this_depth));
75 7
			}
76
77 7
			$this->close_open_tags($template, 'close_' . $handle, ($this_depth - $this->min_depth));
0 ignored issues
show
Bug introduced by
The variable $this_depth does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
78 7
		}
79 7
	}
80
81 5
	public function generate_breadcrumb(array $data)
82
	{
83 5
		$this->find_parents($data, $this->current_item['parent_id']);
84 5
	}
85
86 7
	protected function prepare_items(array &$data)
87
	{
88 7
		$this->set_current_item($data);
89
90 7
		$prev_depth = $this->min_depth;
91 7
		$this->parental_depth = array(0 => -1);
92
93 7
		foreach ($data as $item_id => $row)
94
		{
95
			// Skip branch
96 7
			if (isset($leaf))
97 7
			{
98 6
				if ($row['left_id'] < $leaf['right_id'])
99 6
				{
100 4
					$this->adjust_right_id($leaf['item_id'], $data, $leaf);
101 4
					unset($data[$item_id]);
102 4
					continue;
103
				}
104 6
				unset($leaf);
105 6
			}
106
107 7
			$is_current_item = $this->is_current_item($row);
108 7
			$this_depth	= $this->parental_depth[$row['parent_id']] + 1;
109
110 7
			$this->set_parental_depth($row, $this_depth, $is_current_item);
111
112 7
			if ($row['depth'] == $this->max_depth)
113 7
			{
114 7
				$leaf = $row;
115 7
			}
116
117 7
			if ($row['depth'] < $this->min_depth)
118 7
			{
119 2
				unset($data[$item_id]);
120 2
				continue;
121
			}
122
123
			$data[$item_id] += array(
124 7
				'prev_depth'	=> $prev_depth,
125 7
				'this_depth'	=> $this_depth,
126 7
				'is_current'	=> $is_current_item,
127 7
				'full_url'		=> append_sid($row['full_url']),
128
			);
129
130 7
			$prev_depth = $this_depth;
131 7
		}
132 7
	}
133
134 7
	protected function set_current_item($data)
135
	{
136 7
		$curr_page = $this->user->page['page_name'];
137 7
		$curr_parts = explode('&', $this->user->page['query_string']);
138
139 7
		$data = array_values($data);
140 7
		for ($i = 0, $size = sizeof($data); $i < $size; $i++)
141
		{
142 7
			$row = $data[$i];
143 7
			if ($this->is_current_path($curr_page, $curr_parts, $row))
144 7
			{
145 6
				$this->adjust_depth($row);
146 6
				$this->current_item = $row;
147 6
				return true;
148
			}
149 4
		}
150
151 1
		$this->current_item = $this->default_current_item();
152 1
		return false;
153
	}
154
155 1
	protected function default_current_item()
156
	{
157 1
		$this->max_depth = ($this->expanded) ? $this->max_depth : 0;
158 1
		$this->min_depth = 0;
159
160
		return array(
161 1
			'item_id'	=> 0,
162 1
			'parent_id'	=> 0,
163 1
			'left_id'	=> 0,
164 1
			'right_id'	=> 0,
165 1
			'depth'		=> 0,
166 1
		);
167
	}
168
169 7
	protected function is_current_path($curr_page, array $curr_parts, array $row)
170
	{
171 7
		return ($curr_page == $row['url_path'] && (!sizeof($row['url_query']) || sizeof(array_intersect($row['url_query'], $curr_parts)))) ? true : false;
172
	}
173
174 7
	protected function is_current_item(array $row)
175
	{
176 7
		return ($row['item_id'] === $this->current_item['item_id']) ? true : false;
177
	}
178
179 7
	protected function set_parental_depth($row, $depth, $is_current_item)
180
	{
181 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']))
182 7
		{
183 6
			$this->parental_depth[$row[$this->pk]] = $depth;
184 6
		}
185 7
	}
186
187 7
	protected function close_open_tags(\phpbb\template\twig\twig &$template, $handle, $repeat)
188
	{
189 7
		for ($i = 0; $i < $repeat; $i++)
190
		{
191 5
			$template->assign_block_vars($handle, array());
192 5
		}
193 7
	}
194
195 6
	protected function needs_adjustment($items_depth)
196
	{
197 6
		return ($items_depth >= $this->max_depth || !$this->expanded) ? true : false;
198
	}
199
200 6
	protected function adjust_depth(array $row)
201
	{
202 6
		if ($this->needs_adjustment($row['depth']))
203 6
		{
204 5
			$adjustment = ($this->count_descendants($row)) ? 1 : 0;
205 5
			$this->min_depth = ($row['depth']) ? $row['depth'] - $this->max_depth + $adjustment : 0;
0 ignored issues
show
Documentation Bug introduced by
It seems like $row['depth'] ? $row['de...depth + $adjustment : 0 can also be of type double. However, the property $min_depth is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
206 5
			$this->max_depth = $row['depth'] + $adjustment;
207 5
		}
208 6
	}
209
210 4
	protected function adjust_right_id($item_id, array &$data, array $leaf)
211
	{
212 4
		if (isset($data[$item_id]))
213 4
		{
214 4
			$data[$leaf['item_id']]['right_id'] -= 2;
215 4
		}
216 4
	}
217
218 5
	protected function find_parents(array $data, $parent_id)
219
	{
220 5
		if (isset($data[$parent_id]) && $data[$parent_id]['item_url'] !== 'index.php')
221 5
		{
222 2
			$row = $data[$parent_id];
223 2
			$this->template->alter_block_array('navlinks', array(
224 2
				'FORUM_NAME'	=> $row['item_title'],
225 2
				'U_VIEW_FORUM'	=> $row['full_url'],
226 2
			));
227
228 2
			$this->find_parents($data, $row['parent_id']);
229 2
		}
230 5
	}
231
}
232