XoopsTree   B
last analyzed

Complexity

Total Complexity 52

Size/Duplication

Total Lines 380
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 182
dl 0
loc 380
rs 7.44
c 0
b 0
f 0
wmc 52

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A getFirstChild() 0 23 5
A getIdPathFromId() 0 22 4
A getPathFromId() 0 24 4
A getAllParentId() 0 22 4
A getAllChildId() 0 23 5
A getChildTreeArray() 0 24 5
B makeMySelBox() 0 43 10
A getAllChild() 0 23 5
A getNicePathFromId() 0 25 5
A getFirstChildId() 0 20 4

How to fix   Complexity   

Complex Class

Complex classes like XoopsTree often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use XoopsTree, and based on these observations, apply Extract Interface, too.

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 <[email protected]>
25
 * @author              John Neill <[email protected]>
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);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::getRowsNum() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

80
        $count  = $this->db->getRowsNum(/** @scrutinizer ignore-type */ $result);
Loading history...
81
        if ($count == 0) {
82
            return $arr;
83
        }
84
        while (false !== ($myrow = $this->db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

84
        while (false !== ($myrow = $this->db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
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);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::getRowsNum() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

108
        $count   = $this->db->getRowsNum(/** @scrutinizer ignore-type */ $result);
Loading history...
109
        if ($count == 0) {
110
            return $idarray;
111
        }
112
        while (false !== (list($id) = $this->db->fetchRow($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchRow() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

112
        while (false !== (list($id) = $this->db->fetchRow(/** @scrutinizer ignore-type */ $result))) {
Loading history...
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);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::getRowsNum() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

140
        $count  = $this->db->getRowsNum(/** @scrutinizer ignore-type */ $result);
Loading history...
141
        if ($count == 0) {
142
            return $idarray;
143
        }
144
        while (false !== (list($r_id) = $this->db->fetchRow($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchRow() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

144
        while (false !== (list($r_id) = $this->db->fetchRow(/** @scrutinizer ignore-type */ $result))) {
Loading history...
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);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchRow() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

174
        list($r_id) = $this->db->fetchRow(/** @scrutinizer ignore-type */ $result);
Loading history...
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) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::getRowsNum() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

204
        if ($this->db->getRowsNum(/** @scrutinizer ignore-type */ $result) == 0) {
Loading history...
205
            return $path;
206
        }
207
        list($parentid, $name) = $this->db->fetchRow($result);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchRow() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

207
        list($parentid, $name) = $this->db->fetchRow(/** @scrutinizer ignore-type */ $result);
Loading history...
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))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchRow() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

255
        while (false !== (list($catid, $name) = $this->db->fetchRow(/** @scrutinizer ignore-type */ $result))) {
Loading history...
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) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::getRowsNum() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

296
        if ($this->db->getRowsNum(/** @scrutinizer ignore-type */ $result) == 0) {
Loading history...
297
            return $path;
298
        }
299
        list($parentid, $name) = $this->db->fetchRow($result);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchRow() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

299
        list($parentid, $name) = $this->db->fetchRow(/** @scrutinizer ignore-type */ $result);
Loading history...
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) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::getRowsNum() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

330
        if ($this->db->getRowsNum(/** @scrutinizer ignore-type */ $result) == 0) {
Loading history...
331
            return $path;
332
        }
333
        list($parentid) = $this->db->fetchRow($result);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchRow() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

333
        list($parentid) = $this->db->fetchRow(/** @scrutinizer ignore-type */ $result);
Loading history...
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);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::getRowsNum() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

366
        $count  = $this->db->getRowsNum(/** @scrutinizer ignore-type */ $result);
Loading history...
367
        if ($count == 0) {
368
            return $parray;
369
        }
370
        while (false !== ($row = $this->db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

370
        while (false !== ($row = $this->db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
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);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::getRowsNum() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

400
        $count  = $this->db->getRowsNum(/** @scrutinizer ignore-type */ $result);
Loading history...
401
        if ($count == 0) {
402
            return $parray;
403
        }
404
        while (false !== ($row = $this->db->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

404
        while (false !== ($row = $this->db->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
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