display::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

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