Completed
Push — master ( edb932...4a8b55 )
by Daniel
08:30
created

display::display_list()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 34
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 4.0105

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 34
ccs 21
cts 23
cp 0.913
rs 8.5806
cc 4
eloc 19
nc 6
nop 3
crap 4.0105
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\tree;
11
12
/**
13
* Display nested sets
14
*/
15
abstract class display
16
{
17
	/** @var \phpbb\db\driver\driver_interface */
18
	protected $db;
19
20
	/** @var string */
21
	protected $items_table;
22
23
	/** @var string */
24
	protected $pk;
25
26
	/** @var string */
27
	protected $sql_where;
28
29
	/** @var array */
30
	protected $errors = array();
31
32
	/** @var array */
33
	protected $data = array();
34
35
	/**
36
	* Construct
37
	*
38
	* @param \phpbb\db\driver\driver_interface		$db             Database connection
39
	* @param string									$items_table	Table name
40
	* @param string									$pk				Primary key
41
	* @param string									$sql_where		Column restriction
42
	*/
43 18
	public function __construct(\phpbb\db\driver\driver_interface $db, $items_table, $pk, $sql_where = '')
44
	{
45 18
		$this->db = $db;
46 18
		$this->pk = $pk;
47 18
		$this->items_table = $items_table;
48 18
		$this->sql_where = $sql_where;
49 18
	}
50
51
	/**
52
	 * Is subject node an ancestor of the object node?
53
	 */
54
	public function is_in_path($object, $subject)
55
	{
56
		return ($subject['left_id'] < $object['left_id'] && $subject['right_id'] > $object['right_id']) ? true : false;
57
	}
58
59
	/**
60
	 * Count node descendants
61
	 */
62 8
	public function count_descendants($row)
63
	{
64 8
		return ($row['right_id'] - $row['left_id'] - 1) / 2;
65
	}
66
67
	/**
68
	 * Get node row
69
	 */
70
	public function get_node_info($node_id)
71
	{
72
		$sql = "SELECT *
73
			FROM $this->items_table
74
			WHERE $this->pk = " . (int) $node_id ;
75
		$result = $this->db->sql_query($sql);
76
		$row = $this->db->sql_fetchrow($result);
77
		$this->db->sql_freeresult($result);
78
79
		return $row;
80
	}
81
82
	/**
83
	 * Get Tree Query
84
	 *
85
	 * @param	integer	$start			Starting level
86
	 * @param	integer $level			Max depth
87
	 * @param	array	$sql_array		Array of elements to merge into query
88
	 * 										array(
89
	 * 											'SELECT'	=> array('p.*'),
90
	 * 											'WHERE'		=> array('p.post_id = 2'),
91
	 * 										)
92
	 * @return	string		The sql query
93
	 */
94
	public function qet_tree_sql($start = 0, $level = 0, $sql_array = array())
95
	{
96
		$sql_array = array_merge_recursive(
97
			array(
98
				'SELECT'	=> array('t.*'),
99
				'FROM'		=> array(
100
					$this->items_table => ' t'
101
				),
102
				'WHERE'		=> array(
103
					't.depth ' . (($level) ? " BETWEEN $start AND " . ($start + $level) : ' >= ' . $start),
104
					(($this->sql_where) ? 't.' . $this->sql_where : ''),
105
				),
106
				'ORDER_BY'	=> 't.left_id ASC',
107
			),
108
			$sql_array
109
		);
110
111
		$sql_array['SELECT'] = join(', ', array_filter($sql_array['SELECT']));
112
		$sql_array['WHERE'] = join(' AND ', array_filter($sql_array['WHERE']));
113
114
		return $this->db->sql_build_query('SELECT', $sql_array);
115
	}
116
117
	public function get_tree_array($start = 0, $level = 0, $sql_array = array())
118
	{
119
		$sql = $this->qet_tree_sql($start, $level, $sql_array);
120
		$result = $this->db->sql_query($sql);
121
122
		$data = array();
123
		while ($row = $this->db->sql_fetchrow($result))
124
		{
125
			$data[$row[$this->pk]] = $row;
126
		}
127
		$this->db->sql_freeresult($result);
128
129
		return $data;
130
	}
131
132 1
	public function display_list(array $data, \phpbb\template\twig\twig &$template, $handle = 'tree')
133
	{
134 1
		$prev_depth = 0;
135 1
		$parental_depth = array(0 => -1);
136 1
		$data = array_values($data);
137
138 1
		for ($i = 0, $size = sizeof($data); $i < $size; $i++)
139
		{
140 1
			$row 		= $data[$i];
141 1
			$this_depth	= $parental_depth[$row['parent_id']] + 1;
142 1
			$repeat		= abs($prev_depth - $this_depth);
143
144
			$tpl_data	= array(
145 1
				'PREV_DEPTH'	=> $prev_depth,
146 1
				'THIS_DEPTH'	=> $this_depth,
147 1
				'NUM_KIDS'		=> $this->count_descendants($row),
148 1
			);
149
150 1
			$template->assign_block_vars($handle, array_merge($tpl_data, array_change_key_case($row, CASE_UPPER)));
151
152 1
			for ($j = 0; $j < $repeat; $j++)
153
			{
154 1
				$template->assign_block_vars($handle . '.close', array());
155 1
			}
156
157 1
			$prev_depth = $this_depth;
158 1
			$parental_depth[$row[$this->pk]] = $this_depth;
159 1
		}
160
161 1
		for ($i = 0; $i < $prev_depth; $i++)
162
		{
163
			$template->assign_block_vars('close_' . $handle, array());
164
		}
165 1
	}
166
167
	/**
168
	 * Get tree as form options or data
169
	 *
170
	 * @param	array	$db_data	Raw tree data from database
171
	 * @param	string	$title_column	Database column name to use as label/title for each item
172
	 * @param	array	$selected_ids	Array of selected items
173
	 * @param	string	$return_mode	options | data
174
	 * @param	string	$pad_with		Character used to denote nesting
175
	 *
176
	 * @return	mixed	Returns array of padded titles or html string of options depending on $return_mode
177
	 */
178
	public function display_options($db_data, $title_column, $selected_ids = array(), $return_mode = 'options', $pad_with = '&nbsp;&nbsp;&nbsp;&nbsp;')
179
	{
180
		$right = 0;
181
		$padding = '';
182
		$return_options = '';
183
		$return_data = array();
184
		$padding_store = array('0' => '');
185
186
		$db_data = array_values($db_data);
187
		for ($i = 0, $size = sizeof($db_data); $i < $size; $i++)
188
		{
189
			$row = $db_data[$i];
190
191
			if ($row['left_id'] < $right)
192
			{
193
				$padding .= $pad_with;
194
				$padding_store[$row['parent_id']] = $padding;
195
			}
196
			else if ($row['left_id'] > $right + 1)
197
			{
198
				$padding = (isset($padding_store[$row['parent_id']])) ? $padding_store[$row['parent_id']] : '';
199
			}
200
201
			$right = $row['right_id'];
202
			$title = $padding . '&#x251c;&#x2500; ' . $row[$title_column];
203
			$selected = (in_array($row[$this->pk], $selected_ids)) ? ' selected="selected' : '';
204
205
			$return_options .= '<option value="' . $row[$this->pk] . '"' . $selected . '>' . $title . '</option>';
206
			$return_data[$row[$this->pk]] = $title;
207
		}
208
209
		return ($return_mode == 'options') ? $return_options : $return_data;
210
	}
211
}
212