1: <?php
2: /**
3: * XOOPS tree handler
4: *
5: * You may not change or alter any portion of this comment or credits
6: * of supporting developers from this source code or any supporting source code
7: * which is considered copyrighted (c) material of the original comment or credit authors.
8: * This program is distributed in the hope that it will be useful,
9: * but WITHOUT ANY WARRANTY; without even the implied warranty of
10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11: *
12: * @copyright (c) 2000-2016 XOOPS Project (www.xoops.org)
13: * @license GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
14: * @package kernel
15: * @since 2.0.0
16: * @author Kazumi Ono (AKA onokazu) http://www.myweb.ne.jp/, http://jp.xoops.org/
17: */
18:
19: defined('XOOPS_ROOT_PATH') || exit('Restricted access');
20:
21: /**
22: * Abstract base class for forms
23: *
24: * @author Kazumi Ono <onokazu@xoops.org>
25: * @author John Neill <catzwolf@xoops.org>
26: * @copyright (c) 2000-2016 XOOPS Project (www.xoops.org)
27: * @package kernel
28: * @subpackage XoopsTree
29: * @access public
30: */
31: class XoopsTree
32: {
33: public $table; //table with parent-child structure
34: public $id; //name of unique id for records in table $table
35: public $pid; // name of parent id used in table $table
36: public $order; //specifies the order of query results
37: public $title; // name of a field in table $table which will be used when selection box and paths are generated
38: /**
39: * @var \XoopsMySQLDatabase
40: */
41: public $db;
42:
43: //constructor of class XoopsTree
44: //sets the names of table, unique id, and parend id
45: /**
46: * @param $table_name
47: * @param $id_name
48: * @param $pid_name
49: */
50: public function __construct($table_name, $id_name, $pid_name)
51: {
52: $GLOBALS['xoopsLogger']->addDeprecated("Class '" . __CLASS__ . "' is deprecated, check 'XoopsObjectTree' in tree.php");
53: $this->db = XoopsDatabaseFactory::getDatabaseConnection();
54: $this->table = $table_name;
55: $this->id = $id_name;
56: $this->pid = $pid_name;
57: }
58:
59: // returns an array of first child objects for a given id($sel_id)
60: /**
61: * @param $sel_id
62: * @param string $order
63: *
64: * @return array
65: */
66: public function getFirstChild($sel_id, $order = '')
67: {
68: $sel_id = (int)$sel_id;
69: $arr = array();
70: $sql = 'SELECT * FROM ' . $this->table . ' WHERE ' . $this->pid . '=' . $sel_id . '';
71: if ($order != '') {
72: $sql .= " ORDER BY $order";
73: }
74: $result = $this->db->query($sql);
75: if (!$this->db->isResultSet($result)) {
76: throw new \RuntimeException(
77: \sprintf(_DB_QUERY_ERROR, $sql) . $this->db->error(), E_USER_ERROR
78: );
79: }
80: $count = $this->db->getRowsNum($result);
81: if ($count == 0) {
82: return $arr;
83: }
84: while (false !== ($myrow = $this->db->fetchArray($result))) {
85: $arr[] = $myrow;
86: }
87:
88: return $arr;
89: }
90:
91: // returns an array of all FIRST child ids of a given id($sel_id)
92: /**
93: * @param $sel_id
94: *
95: * @return array
96: */
97: public function getFirstChildId($sel_id)
98: {
99: $sel_id = (int)$sel_id;
100: $idarray = array();
101: $sql = 'SELECT ' . $this->id . ' FROM ' . $this->table . ' WHERE ' . $this->pid . '=' . $sel_id . '';
102: $result = $this->db->query($sql);
103: if (!$this->db->isResultSet($result)) {
104: throw new \RuntimeException(
105: \sprintf(_DB_QUERY_ERROR, $sql) . $this->db->error(), E_USER_ERROR
106: );
107: }
108: $count = $this->db->getRowsNum($result);
109: if ($count == 0) {
110: return $idarray;
111: }
112: while (false !== (list($id) = $this->db->fetchRow($result))) {
113: $idarray[] = $id;
114: }
115:
116: return $idarray;
117: }
118:
119: //returns an array of ALL child ids for a given id($sel_id)
120: /**
121: * @param $sel_id
122: * @param string $order
123: * @param array $idarray
124: *
125: * @return array
126: */
127: public function getAllChildId($sel_id, $order = '', $idarray = array())
128: {
129: $sel_id = (int)$sel_id;
130: $sql = 'SELECT ' . $this->id . ' FROM ' . $this->table . ' WHERE ' . $this->pid . '=' . $sel_id . '';
131: if ($order != '') {
132: $sql .= " ORDER BY $order";
133: }
134: $result = $this->db->query($sql);
135: if (!$this->db->isResultSet($result)) {
136: throw new \RuntimeException(
137: \sprintf(_DB_QUERY_ERROR, $sql) . $this->db->error(), E_USER_ERROR
138: );
139: }
140: $count = $this->db->getRowsNum($result);
141: if ($count == 0) {
142: return $idarray;
143: }
144: while (false !== (list($r_id) = $this->db->fetchRow($result))) {
145: $idarray[] = $r_id;
146: $idarray = $this->getAllChildId($r_id, $order, $idarray);
147: }
148:
149: return $idarray;
150: }
151:
152: //returns an array of ALL parent ids for a given id($sel_id)
153:
154: /**
155: * @param string|int $sel_id
156: * @param string $order
157: * @param array $idarray
158: *
159: * @return array
160: */
161: public function getAllParentId($sel_id, $order = '', $idarray = array())
162: {
163: $sel_id = (int)$sel_id;
164: $sql = 'SELECT ' . $this->pid . ' FROM ' . $this->table . ' WHERE ' . $this->id . '=' . $sel_id . '';
165: if ($order != '') {
166: $sql .= " ORDER BY $order";
167: }
168: $result = $this->db->query($sql);
169: if (!$this->db->isResultSet($result)) {
170: throw new \RuntimeException(
171: \sprintf(_DB_QUERY_ERROR, $sql) . $this->db->error(), E_USER_ERROR
172: );
173: }
174: list($r_id) = $this->db->fetchRow($result);
175: $r_id = (int)$r_id;
176: if ($r_id === 0) {
177: return $idarray;
178: }
179: $idarray[] = $r_id;
180: $idarray = $this->getAllParentId($r_id, $order, $idarray);
181:
182: return $idarray;
183: }
184:
185: //generates path from the root id to a given id($sel_id)
186: // the path is delimetered with "/"
187: /**
188: * @param string|int $sel_id
189: * @param string $title
190: * @param string $path
191: *
192: * @return string
193: */
194: public function getPathFromId($sel_id, $title, $path = '')
195: {
196: $sel_id = (int)$sel_id;
197: $sql = 'SELECT ' . $this->pid . ', ' . $title . ' FROM ' . $this->table . ' WHERE ' . $this->id . "=$sel_id";
198: $result = $this->db->query($sql);
199: if (!$this->db->isResultSet($result)) {
200: throw new \RuntimeException(
201: \sprintf(_DB_QUERY_ERROR, $sql) . $this->db->error(), E_USER_ERROR
202: );
203: }
204: if ($this->db->getRowsNum($result) == 0) {
205: return $path;
206: }
207: list($parentid, $name) = $this->db->fetchRow($result);
208: $myts = \MyTextSanitizer::getInstance();
209: $parentid = (int)$parentid;
210: $name = $myts->htmlSpecialChars($name);
211: $path = '/' . $name . $path . '';
212: if ($parentid === 0) {
213: return $path;
214: }
215: $path = $this->getPathFromId($parentid, $title, $path);
216:
217: return $path;
218: }
219:
220: //makes a nicely ordered selection box
221: //$preset_id is used to specify a preselected item
222: //set $none to 1 to add an option with value 0
223: /**
224: * @param $title
225: * @param string $order
226: * @param int $preset_id
227: * @param int $none
228: * @param string $sel_name
229: * @param string $onchange
230: */
231: public function makeMySelBox($title, $order = '', $preset_id = 0, $none = 0, $sel_name = '', $onchange = '')
232: {
233: if ($sel_name == '') {
234: $sel_name = $this->id;
235: }
236: $myts = \MyTextSanitizer::getInstance();
237: echo "<select name='" . $sel_name . "'";
238: if ($onchange != '') {
239: echo " onchange='" . $onchange . "'";
240: }
241: echo ">\n";
242: $sql = 'SELECT ' . $this->id . ', ' . $title . ' FROM ' . $this->table . ' WHERE ' . $this->pid . '=0';
243: if ($order != '') {
244: $sql .= " ORDER BY $order";
245: }
246: $result = $this->db->query($sql);
247: if (!$this->db->isResultSet($result)) {
248: throw new \RuntimeException(
249: \sprintf(_DB_QUERY_ERROR, $sql) . $this->db->error(), E_USER_ERROR
250: );
251: }
252: if ($none) {
253: echo "<option value='0'>----</option>\n";
254: }
255: while (false !== (list($catid, $name) = $this->db->fetchRow($result))) {
256: $sel = '';
257: if ($catid == $preset_id) {
258: $sel = " selected";
259: }
260: echo "<option value='$catid'$sel>$name</option>\n";
261: $sel = '';
262: $arr = $this->getChildTreeArray($catid, $order);
263: foreach ($arr as $option) {
264: $option['prefix'] = str_replace('.', '--', $option['prefix']);
265: $catpath = $option['prefix'] . '&nbsp;' . $myts->htmlSpecialChars($option[$title]);
266: if ($option[$this->id] == $preset_id) {
267: $sel = " selected";
268: }
269: echo "<option value='" . $option[$this->id] . "'$sel>$catpath</option>\n";
270: $sel = '';
271: }
272: }
273: echo "</select>\n";
274: }
275:
276: //generates nicely formatted linked path from the root id to a given id
277: /**
278: * @param string|int $sel_id
279: * @param string $title
280: * @param string $funcURL
281: * @param string $path
282: *
283: * @return string
284: */
285: public function getNicePathFromId($sel_id, $title, $funcURL, $path = '')
286: {
287: $path = !empty($path) ? '&nbsp;:&nbsp;' . $path : $path;
288: $sel_id = (int)$sel_id;
289: $sql = 'SELECT ' . $this->pid . ', ' . $title . ' FROM ' . $this->table . ' WHERE ' . $this->id . "=$sel_id";
290: $result = $this->db->query($sql);
291: if (!$this->db->isResultSet($result)) {
292: throw new \RuntimeException(
293: \sprintf(_DB_QUERY_ERROR, $sql) . $this->db->error(), E_USER_ERROR
294: );
295: }
296: if ($this->db->getRowsNum($result) == 0) {
297: return $path;
298: }
299: list($parentid, $name) = $this->db->fetchRow($result);
300: $myts = \MyTextSanitizer::getInstance();
301: $name = $myts->htmlSpecialChars($name);
302: $parentid = (int)$parentid;
303: $path = "<a href='" . $funcURL . '&amp;' . $this->id . '=' . $sel_id . "'>" . $name . '</a>' . $path . '';
304: if ($parentid === 0) {
305: return $path;
306: }
307: $path = $this->getNicePathFromId($parentid, $title, $funcURL, $path);
308:
309: return $path;
310: }
311:
312: //generates id path from the root id to a given id
313: // the path is delimetered with "/"
314: /**
315: * @param string|int $sel_id
316: * @param string $path
317: *
318: * @return string
319: */
320: public function getIdPathFromId($sel_id, $path = '')
321: {
322: $sel_id = (int)$sel_id;
323: $sql = 'SELECT ' . $this->pid . ' FROM ' . $this->table . ' WHERE ' . $this->id . "=$sel_id";
324: $result = $this->db->query($sql);
325: if (!$this->db->isResultSet($result)) {
326: throw new \RuntimeException(
327: \sprintf(_DB_QUERY_ERROR, $sql) . $this->db->error(), E_USER_ERROR
328: );
329: }
330: if ($this->db->getRowsNum($result) == 0) {
331: return $path;
332: }
333: list($parentid) = $this->db->fetchRow($result);
334: $path = '/' . $sel_id . $path . '';
335: $parentid = (int)$parentid;
336: if ($parentid === 0) {
337: return $path;
338: }
339: $path = $this->getIdPathFromId($parentid, $path);
340:
341: return $path;
342: }
343:
344: /**
345: * Enter description here...
346: *
347: * @param int|mixed $sel_id
348: * @param string|mixed $order
349: * @param array|mixed $parray
350: *
351: * @return mixed
352: */
353: public function getAllChild($sel_id = 0, $order = '', $parray = array())
354: {
355: $sel_id = (int)$sel_id;
356: $sql = 'SELECT * FROM ' . $this->table . ' WHERE ' . $this->pid . '=' . $sel_id . '';
357: if ($order != '') {
358: $sql .= " ORDER BY $order";
359: }
360: $result = $this->db->query($sql);
361: if (!$this->db->isResultSet($result)) {
362: throw new \RuntimeException(
363: \sprintf(_DB_QUERY_ERROR, $sql) . $this->db->error(), E_USER_ERROR
364: );
365: }
366: $count = $this->db->getRowsNum($result);
367: if ($count == 0) {
368: return $parray;
369: }
370: while (false !== ($row = $this->db->fetchArray($result))) {
371: $parray[] = $row;
372: $parray = $this->getAllChild($row[$this->id], $order, $parray);
373: }
374:
375: return $parray;
376: }
377:
378: /**
379: * Enter description here...
380: *
381: * @param int|mixed $sel_id
382: * @param string|mixed $order
383: * @param array|mixed $parray
384: * @param string|mixed $r_prefix
385: * @return mixed
386: */
387: public function getChildTreeArray($sel_id = 0, $order = '', $parray = array(), $r_prefix = '')
388: {
389: $sel_id = (int)$sel_id;
390: $sql = 'SELECT * FROM ' . $this->table . ' WHERE ' . $this->pid . '=' . $sel_id . '';
391: if ($order != '') {
392: $sql .= " ORDER BY $order";
393: }
394: $result = $this->db->query($sql);
395: if (!$this->db->isResultSet($result)) {
396: throw new \RuntimeException(
397: \sprintf(_DB_QUERY_ERROR, $sql) . $this->db->error(), E_USER_ERROR
398: );
399: }
400: $count = $this->db->getRowsNum($result);
401: if ($count == 0) {
402: return $parray;
403: }
404: while (false !== ($row = $this->db->fetchArray($result))) {
405: $row['prefix'] = $r_prefix . '.';
406: $parray[] = $row;
407: $parray = $this->getChildTreeArray($row[$this->id], $order, $parray, $row['prefix']);
408: }
409:
410: return $parray;
411: }
412: }
413: