Completed
Pull Request — master (#12)
by
unknown
01:54
created

LexikonTree   B

Complexity

Total Complexity 42

Size/Duplication

Total Lines 327
Duplicated Lines 16.82 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
dl 55
loc 327
rs 8.295
c 0
b 0
f 0
wmc 42
lcom 1
cbo 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A getFirstChild() 0 19 4
A getFirstChildId() 0 15 3
A getAllChildId() 19 19 4
A getAllParentId() 17 17 3
A getPathFromId() 0 18 3
D makeMySelBox() 0 39 9
A getNicePathFromId() 0 20 4
A getIdPathFromId() 0 16 3
A getAllChild() 19 19 4
A getChildTreeArray() 0 20 4

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like LexikonTree 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 LexikonTree, 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       XOOPS Project (http://xoops.org)
13
 * @license         GNU GPL 2 (http://www.gnu.org/licenses/old-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('XOOPS root path not defined');
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
20
21
/**
22
 * Abstract base class for forms
23
 *
24
 * @author     Kazumi Ono <[email protected]>
25
 * @author     John Neill <[email protected]>
26
 * @copyright  copyright (c) XOOPS.org
27
 * @package    kernel
28
 * @subpackage LexikonTree
29
 * @access     public
30
 */
31
class LexikonTree
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
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 LexikonTree
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
     * @return lexikontree
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
47
     */
48
    public function __construct($table_name, $id_name, $pid_name)
49
    {
50
        //        $GLOBALS['xoopsLogger']->addDeprecated("Class '" . __CLASS__ . "' is deprecated, check 'XoopsObjectTree' in tree.php");
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
51
        $this->db    = XoopsDatabaseFactory::getDatabaseConnection();
52
        $this->table = $table_name;
53
        $this->id    = $id_name;
54
        $this->pid   = $pid_name;
55
    }
56
57
    // returns an array of first child objects for a given id($sel_id)
58
59
    /**
60
     * @param        $sel_id
61
     * @param string $order
62
     *
63
     * @return array
64
     */
65
    public function getFirstChild($sel_id, $order = '')
66
    {
67
        $sel_id = (int)$sel_id;
68
        $arr    = [];
69
        $sql    = 'SELECT * FROM ' . $this->table . ' WHERE ' . $this->pid . '=' . $sel_id . '';
70
        if ($order != '') {
71
            $sql .= " ORDER BY $order";
72
        }
73
        $result = $this->db->query($sql);
74
        $count  = $this->db->getRowsNum($result);
75
        if ($count == 0) {
76
            return $arr;
77
        }
78
        while ($myrow = $this->db->fetchArray($result)) {
79
            array_push($arr, $myrow);
80
        }
81
82
        return $arr;
83
    }
84
85
    // returns an array of all FIRST child ids of a given id($sel_id)
86
87
    /**
88
     * @param $sel_id
89
     *
90
     * @return array
91
     */
92
    public function getFirstChildId($sel_id)
93
    {
94
        $sel_id  = (int)$sel_id;
95
        $idarray = [];
96
        $result  = $this->db->query('SELECT ' . $this->id . ' FROM ' . $this->table . ' WHERE ' . $this->pid . '=' . $sel_id . '');
97
        $count   = $this->db->getRowsNum($result);
98
        if ($count == 0) {
99
            return $idarray;
100
        }
101
        while (list($id) = $this->db->fetchRow($result)) {
102
            array_push($idarray, $id);
103
        }
104
105
        return $idarray;
106
    }
107
108
    //returns an array of ALL child ids for a given id($sel_id)
109
110
    /**
111
     * @param        $sel_id
112
     * @param string $order
113
     * @param array  $idarray
114
     *
115
     * @return array
116
     */
117 View Code Duplication
    public function getAllChildId($sel_id, $order = '', $idarray = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
118
    {
119
        $sel_id = (int)$sel_id;
120
        $sql    = 'SELECT ' . $this->id . ' FROM ' . $this->table . ' WHERE ' . $this->pid . '=' . $sel_id . '';
121
        if ($order != '') {
122
            $sql .= " ORDER BY $order";
123
        }
124
        $result = $this->db->query($sql);
125
        $count  = $this->db->getRowsNum($result);
126
        if ($count == 0) {
127
            return $idarray;
128
        }
129
        while (list($r_id) = $this->db->fetchRow($result)) {
130
            array_push($idarray, $r_id);
131
            $idarray = $this->getAllChildId($r_id, $order, $idarray);
132
        }
133
134
        return $idarray;
135
    }
136
137
    //returns an array of ALL parent ids for a given id($sel_id)
138
139
    /**
140
     * @param        $sel_id
141
     * @param string $order
142
     * @param array  $idarray
143
     *
144
     * @return array
145
     */
146 View Code Duplication
    public function getAllParentId($sel_id, $order = '', $idarray = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
147
    {
148
        $sel_id = (int)$sel_id;
149
        $sql    = 'SELECT ' . $this->pid . ' FROM ' . $this->table . ' WHERE ' . $this->id . '=' . $sel_id . '';
150
        if ($order != '') {
151
            $sql .= " ORDER BY $order";
152
        }
153
        $result = $this->db->query($sql);
154
        list($r_id) = $this->db->fetchRow($result);
155
        if ($r_id == 0) {
156
            return $idarray;
157
        }
158
        array_push($idarray, $r_id);
159
        $idarray = $this->getAllParentId($r_id, $order, $idarray);
160
161
        return $idarray;
162
    }
163
164
    //generates path from the root id to a given id($sel_id)
165
    // the path is delimetered with "/"
166
    /**
167
     * @param        $sel_id
168
     * @param        $title
169
     * @param string $path
170
     *
171
     * @return string
172
     */
173
    public function getPathFromId($sel_id, $title, $path = '')
174
    {
175
        $sel_id = (int)$sel_id;
176
        $result = $this->db->query('SELECT ' . $this->pid . ', ' . $title . ' FROM ' . $this->table . ' WHERE ' . $this->id . "=$sel_id");
177
        if ($this->db->getRowsNum($result) == 0) {
178
            return $path;
179
        }
180
        list($parentid, $name) = $this->db->fetchRow($result);
181
        $myts = MyTextSanitizer::getInstance();
182
        $name = $myts->htmlspecialchars($name);
183
        $path = '/' . $name . $path . '';
184
        if ($parentid == 0) {
185
            return $path;
186
        }
187
        $path = $this->getPathFromId($parentid, $title, $path);
188
189
        return $path;
190
    }
191
192
    //makes a nicely ordered selection box
193
    //$preset_id is used to specify a preselected item
194
    //set $none to 1 to add a option with value 0
195
    /**
196
     * @param        $title
197
     * @param string $order
198
     * @param int    $preset_id
199
     * @param int    $none
200
     * @param string $sel_name
201
     * @param string $onchange
202
     */
203
    public function makeMySelBox($title, $order = '', $preset_id = 0, $none = 0, $sel_name = '', $onchange = '')
204
    {
205
        if ($sel_name == '') {
206
            $sel_name = $this->id;
207
        }
208
        $myts = MyTextSanitizer::getInstance();
209
        echo "<select name='" . $sel_name . "'";
210
        if ($onchange != '') {
211
            echo " onchange='" . $onchange . "'";
212
        }
213
        echo ">\n";
214
        $sql = 'SELECT ' . $this->id . ', ' . $title . ' FROM ' . $this->table . ' WHERE ' . $this->pid . '=0';
215
        if ($order != '') {
216
            $sql .= " ORDER BY $order";
217
        }
218
        $result = $this->db->query($sql);
219
        if ($none) {
220
            echo "<option value='0'>----</option>\n";
221
        }
222
        while (list($catid, $name) = $this->db->fetchRow($result)) {
223
            $sel = '';
224
            if ($catid == $preset_id) {
225
                $sel = ' selected';
226
            }
227
            echo "<option value='$catid'$sel>$name</option>\n";
228
            $sel = '';
229
            $arr = $this->getChildTreeArray($catid, $order);
230
            foreach ($arr as $option) {
231
                $option['prefix'] = str_replace('.', '--', $option['prefix']);
232
                $catpath          = $option['prefix'] . '&nbsp;' . $myts->htmlspecialchars($option[$title]);
233
                if ($option[$this->id] == $preset_id) {
234
                    $sel = ' selected';
235
                }
236
                echo "<option value='" . $option[$this->id] . "'$sel>$catpath</option>\n";
237
                $sel = '';
238
            }
239
        }
240
        echo "</select>\n";
241
    }
242
243
    //generates nicely formatted linked path from the root id to a given id
244
245
    /**
246
     * @param        $sel_id
247
     * @param        $title
248
     * @param        $funcURL
249
     * @param string $path
250
     *
251
     * @return string
252
     */
253
    public function getNicePathFromId($sel_id, $title, $funcURL, $path = '')
254
    {
255
        $path   = !empty($path) ? '&nbsp;:&nbsp;' . $path : $path;
256
        $sel_id = (int)$sel_id;
257
        $sql    = 'SELECT ' . $this->pid . ', ' . $title . ' FROM ' . $this->table . ' WHERE ' . $this->id . "=$sel_id";
258
        $result = $this->db->query($sql);
259
        if ($this->db->getRowsNum($result) == 0) {
260
            return $path;
261
        }
262
        list($parentid, $name) = $this->db->fetchRow($result);
263
        $myts = MyTextSanitizer::getInstance();
264
        $name = $myts->htmlspecialchars($name);
265
        $path = "<a href='" . $funcURL . '&amp;' . $this->id . '=' . $sel_id . "'>" . $name . '</a>' . $path . '';
266
        if ($parentid == 0) {
267
            return $path;
268
        }
269
        $path = $this->getNicePathFromId($parentid, $title, $funcURL, $path);
270
271
        return $path;
272
    }
273
274
    //generates id path from the root id to a given id
275
    // the path is delimetered with "/"
276
    /**
277
     * @param        $sel_id
278
     * @param string $path
279
     *
280
     * @return string
281
     */
282
    public function getIdPathFromId($sel_id, $path = '')
283
    {
284
        $sel_id = (int)$sel_id;
285
        $result = $this->db->query('SELECT ' . $this->pid . ' FROM ' . $this->table . ' WHERE ' . $this->id . "=$sel_id");
286
        if ($this->db->getRowsNum($result) == 0) {
287
            return $path;
288
        }
289
        list($parentid) = $this->db->fetchRow($result);
290
        $path = '/' . $sel_id . $path . '';
291
        if ($parentid == 0) {
292
            return $path;
293
        }
294
        $path = $this->getIdPathFromId($parentid, $path);
295
296
        return $path;
297
    }
298
299
    /**
300
     * Enter description here...
301
     *
302
     * @param int|mixed    $sel_id
303
     * @param string|mixed $order
304
     * @param array|mixed  $parray
305
     *
306
     * @return array|unknown|unknown_type
307
     */
308 View Code Duplication
    public function getAllChild($sel_id = 0, $order = '', $parray = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
309
    {
310
        $sel_id = (int)$sel_id;
311
        $sql    = 'SELECT * FROM ' . $this->table . ' WHERE ' . $this->pid . '=' . $sel_id . '';
312
        if ($order != '') {
313
            $sql .= " ORDER BY $order";
314
        }
315
        $result = $this->db->query($sql);
316
        $count  = $this->db->getRowsNum($result);
317
        if ($count == 0) {
318
            return $parray;
319
        }
320
        while ($row = $this->db->fetchArray($result)) {
321
            array_push($parray, $row);
322
            $parray = $this->getAllChild($row[$this->id], $order, $parray);
323
        }
324
325
        return $parray;
326
    }
327
328
    /**
329
     * Enter description here...
330
     *
331
     * @param  int|mixed    $sel_id
332
     * @param  string|mixed $order
333
     * @param  array|mixed  $parray
334
     * @param  string|mixed $r_prefix
335
     * @return array|unknown|unknown_type
336
     */
337
    public function getChildTreeArray($sel_id = 0, $order = '', $parray = [], $r_prefix = '')
338
    {
339
        $sel_id = (int)$sel_id;
340
        $sql    = 'SELECT * FROM ' . $this->table . ' WHERE ' . $this->pid . '=' . $sel_id . '';
341
        if ($order != '') {
342
            $sql .= " ORDER BY $order";
343
        }
344
        $result = $this->db->query($sql);
345
        $count  = $this->db->getRowsNum($result);
346
        if ($count == 0) {
347
            return $parray;
348
        }
349
        while ($row = $this->db->fetchArray($result)) {
350
            $row['prefix'] = $r_prefix . '.';
351
            array_push($parray, $row);
352
            $parray = $this->getChildTreeArray($row[$this->id], $order, $parray, $row['prefix']);
353
        }
354
355
        return $parray;
356
    }
357
}
358