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 (http://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
19defined('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 */
31class 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    public $db;
39
40    //constructor of class XoopsTree
41    //sets the names of table, unique id, and parend id
42    /**
43     * @param $table_name
44     * @param $id_name
45     * @param $pid_name
46     */
47    public function __construct($table_name, $id_name, $pid_name)
48    {
49        $GLOBALS['xoopsLogger']->addDeprecated("Class '" . __CLASS__ . "' is deprecated, check 'XoopsObjectTree' in tree.php");
50        $this->db = XoopsDatabaseFactory::getDatabaseConnection();
51        $this->table = $table_name;
52        $this->id    = $id_name;
53        $this->pid   = $pid_name;
54    }
55
56    // returns an array of first child objects for a given id($sel_id)
57    /**
58     * @param        $sel_id
59     * @param string $order
60     *
61     * @return array
62     */
63    public function getFirstChild($sel_id, $order = '')
64    {
65        $sel_id = (int)$sel_id;
66        $arr    = array();
67        $sql    = 'SELECT * FROM ' . $this->table . ' WHERE ' . $this->pid . '=' . $sel_id . '';
68        if ($order != '') {
69            $sql .= " ORDER BY $order";
70        }
71        $result = $this->db->query($sql);
72        $count  = $this->db->getRowsNum($result);
73        if ($count == 0) {
74            return $arr;
75        }
76        while (false !== ($myrow = $this->db->fetchArray($result))) {
77            $arr[] = $myrow;
78        }
79
80        return $arr;
81    }
82
83    // returns an array of all FIRST child ids of a given id($sel_id)
84    /**
85     * @param $sel_id
86     *
87     * @return array
88     */
89    public function getFirstChildId($sel_id)
90    {
91        $sel_id  = (int)$sel_id;
92        $idarray = array();
93        $result  = $this->db->query('SELECT ' . $this->id . ' FROM ' . $this->table . ' WHERE ' . $this->pid . '=' . $sel_id . '');
94        $count   = $this->db->getRowsNum($result);
95        if ($count == 0) {
96            return $idarray;
97        }
98        while (false !== (list($id) = $this->db->fetchRow($result))) {
99            $idarray[] = $id;
100        }
101
102        return $idarray;
103    }
104
105    //returns an array of ALL child ids for a given id($sel_id)
106    /**
107     * @param        $sel_id
108     * @param string $order
109     * @param array  $idarray
110     *
111     * @return array
112     */
113    public function getAllChildId($sel_id, $order = '', $idarray = array())
114    {
115        $sel_id = (int)$sel_id;
116        $sql    = 'SELECT ' . $this->id . ' FROM ' . $this->table . ' WHERE ' . $this->pid . '=' . $sel_id . '';
117        if ($order != '') {
118            $sql .= " ORDER BY $order";
119        }
120        $result = $this->db->query($sql);
121        $count  = $this->db->getRowsNum($result);
122        if ($count == 0) {
123            return $idarray;
124        }
125        while (false !== (list($r_id) = $this->db->fetchRow($result))) {
126            $idarray[] = $r_id;
127            $idarray   = $this->getAllChildId($r_id, $order, $idarray);
128        }
129
130        return $idarray;
131    }
132
133    //returns an array of ALL parent ids for a given id($sel_id)
134    /**
135     * @param        $sel_id
136     * @param string $order
137     * @param array  $idarray
138     *
139     * @return array
140     */
141    public function getAllParentId($sel_id, $order = '', $idarray = array())
142    {
143        $sel_id = (int)$sel_id;
144        $sql    = 'SELECT ' . $this->pid . ' FROM ' . $this->table . ' WHERE ' . $this->id . '=' . $sel_id . '';
145        if ($order != '') {
146            $sql .= " ORDER BY $order";
147        }
148        $result = $this->db->query($sql);
149        list($r_id) = $this->db->fetchRow($result);
150        if ($r_id == 0) {
151            return $idarray;
152        }
153        $idarray[] = $r_id;
154        $idarray   = $this->getAllParentId($r_id, $order, $idarray);
155
156        return $idarray;
157    }
158
159    //generates path from the root id to a given id($sel_id)
160    // the path is delimetered with "/"
161    /**
162     * @param        $sel_id
163     * @param        $title
164     * @param string $path
165     *
166     * @return string
167     */
168    public function getPathFromId($sel_id, $title, $path = '')
169    {
170        $sel_id = (int)$sel_id;
171        $result = $this->db->query('SELECT ' . $this->pid . ', ' . $title . ' FROM ' . $this->table . ' WHERE ' . $this->id . "=$sel_id");
172        if ($this->db->getRowsNum($result) == 0) {
173            return $path;
174        }
175        list($parentid, $name) = $this->db->fetchRow($result);
176        $myts = MyTextSanitizer::getInstance();
177        $name = $myts->htmlSpecialChars($name);
178        $path = '/' . $name . $path . '';
179        if ($parentid == 0) {
180            return $path;
181        }
182        $path = $this->getPathFromId($parentid, $title, $path);
183
184        return $path;
185    }
186
187    //makes a nicely ordered selection box
188    //$preset_id is used to specify a preselected item
189    //set $none to 1 to add a option with value 0
190    /**
191     * @param        $title
192     * @param string $order
193     * @param int    $preset_id
194     * @param int    $none
195     * @param string $sel_name
196     * @param string $onchange
197     */
198    public function makeMySelBox($title, $order = '', $preset_id = 0, $none = 0, $sel_name = '', $onchange = '')
199    {
200        if ($sel_name == '') {
201            $sel_name = $this->id;
202        }
203        $myts = MyTextSanitizer::getInstance();
204        echo "<select name='" . $sel_name . "'";
205        if ($onchange != '') {
206            echo " onchange='" . $onchange . "'";
207        }
208        echo ">\n";
209        $sql = 'SELECT ' . $this->id . ', ' . $title . ' FROM ' . $this->table . ' WHERE ' . $this->pid . '=0';
210        if ($order != '') {
211            $sql .= " ORDER BY $order";
212        }
213        $result = $this->db->query($sql);
214        if ($none) {
215            echo "<option value='0'>----</option>\n";
216        }
217        while (false !== (list($catid, $name) = $this->db->fetchRow($result))) {
218            $sel = '';
219            if ($catid == $preset_id) {
220                $sel = " selected";
221            }
222            echo "<option value='$catid'$sel>$name</option>\n";
223            $sel = '';
224            $arr = $this->getChildTreeArray($catid, $order);
225            foreach ($arr as $option) {
226                $option['prefix'] = str_replace('.', '--', $option['prefix']);
227                $catpath          = $option['prefix'] . '&nbsp;' . $myts->htmlSpecialChars($option[$title]);
228                if ($option[$this->id] == $preset_id) {
229                    $sel = " selected";
230                }
231                echo "<option value='" . $option[$this->id] . "'$sel>$catpath</option>\n";
232                $sel = '';
233            }
234        }
235        echo "</select>\n";
236    }
237
238    //generates nicely formatted linked path from the root id to a given id
239    /**
240     * @param        $sel_id
241     * @param        $title
242     * @param        $funcURL
243     * @param string $path
244     *
245     * @return string
246     */
247    public function getNicePathFromId($sel_id, $title, $funcURL, $path = '')
248    {
249        $path   = !empty($path) ? '&nbsp;:&nbsp;' . $path : $path;
250        $sel_id = (int)$sel_id;
251        $sql    = 'SELECT ' . $this->pid . ', ' . $title . ' FROM ' . $this->table . ' WHERE ' . $this->id . "=$sel_id";
252        $result = $this->db->query($sql);
253        if ($this->db->getRowsNum($result) == 0) {
254            return $path;
255        }
256        list($parentid, $name) = $this->db->fetchRow($result);
257        $myts = MyTextSanitizer::getInstance();
258        $name = $myts->htmlSpecialChars($name);
259        $path = "<a href='" . $funcURL . '&amp;' . $this->id . '=' . $sel_id . "'>" . $name . '</a>' . $path . '';
260        if ($parentid == 0) {
261            return $path;
262        }
263        $path = $this->getNicePathFromId($parentid, $title, $funcURL, $path);
264
265        return $path;
266    }
267
268    //generates id path from the root id to a given id
269    // the path is delimetered with "/"
270    /**
271     * @param        $sel_id
272     * @param string $path
273     *
274     * @return string
275     */
276    public function getIdPathFromId($sel_id, $path = '')
277    {
278        $sel_id = (int)$sel_id;
279        $result = $this->db->query('SELECT ' . $this->pid . ' FROM ' . $this->table . ' WHERE ' . $this->id . "=$sel_id");
280        if ($this->db->getRowsNum($result) == 0) {
281            return $path;
282        }
283        list($parentid) = $this->db->fetchRow($result);
284        $path = '/' . $sel_id . $path . '';
285        if ($parentid == 0) {
286            return $path;
287        }
288        $path = $this->getIdPathFromId($parentid, $path);
289
290        return $path;
291    }
292
293    /**
294     * Enter description here...
295     *
296     * @param int|mixed    $sel_id
297     * @param string|mixed $order
298     * @param array|mixed  $parray
299     *
300     * @return mixed
301     */
302    public function getAllChild($sel_id = 0, $order = '', $parray = array())
303    {
304        $sel_id = (int)$sel_id;
305        $sql    = 'SELECT * FROM ' . $this->table . ' WHERE ' . $this->pid . '=' . $sel_id . '';
306        if ($order != '') {
307            $sql .= " ORDER BY $order";
308        }
309        $result = $this->db->query($sql);
310        $count  = $this->db->getRowsNum($result);
311        if ($count == 0) {
312            return $parray;
313        }
314        while (false !== ($row = $this->db->fetchArray($result))) {
315            $parray[] = $row;
316            $parray   = $this->getAllChild($row[$this->id], $order, $parray);
317        }
318
319        return $parray;
320    }
321
322    /**
323     * Enter description here...
324     *
325     * @param  int|mixed    $sel_id
326     * @param  string|mixed $order
327     * @param  array|mixed  $parray
328     * @param  string|mixed $r_prefix
329     * @return mixed
330     */
331    public function getChildTreeArray($sel_id = 0, $order = '', $parray = array(), $r_prefix = '')
332    {
333        $sel_id = (int)$sel_id;
334        $sql    = 'SELECT * FROM ' . $this->table . ' WHERE ' . $this->pid . '=' . $sel_id . '';
335        if ($order != '') {
336            $sql .= " ORDER BY $order";
337        }
338        $result = $this->db->query($sql);
339        $count  = $this->db->getRowsNum($result);
340        if ($count == 0) {
341            return $parray;
342        }
343        while (false !== ($row = $this->db->fetchArray($result))) {
344            $row['prefix'] = $r_prefix . '.';
345            $parray[]      = $row;
346            $parray        = $this->getChildTreeArray($row[$this->id], $order, $parray, $row['prefix']);
347        }
348
349        return $parray;
350    }
351}
352