Completed
Push — master ( 62af87...249590 )
by Michael
03:02
created

ObjectTree   B

Complexity

Total Complexity 39

Size/Duplication

Total Lines 250
Duplicated Lines 5.6 %

Coupling/Cohesion

Components 0
Dependencies 0

Importance

Changes 0
Metric Value
dl 14
loc 250
rs 8.2857
c 0
b 0
f 0
wmc 39
lcom 0
cbo 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B makeTreeItems() 7 19 7
A makeTree() 0 7 1
A makeSelBox() 0 21 3
B getAllChildObject() 0 15 5
A makeObjectTree() 0 10 2
C getAllChildArray() 7 22 7
A makeArrayTree() 0 10 2
B myGetParentForums() 0 15 5
B getParentForums() 0 22 6

How to fix   Duplicated Code   

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:

1
<?php namespace XoopsModules\Newbb;
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 36 and the first side effect is on line 30.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
//
4
// ------------------------------------------------------------------------ //
5
// This program is free software; you can redistribute it and/or modify     //
6
// it under the terms of the GNU General Public License as published by     //
7
// the Free Software Foundation; either version 2 of the License, or        //
8
// (at your option) any later version.                                      //
9
//                                                                          //
10
// You may not change or alter any portion of this comment or credits       //
11
// of supporting developers from this source code or any supporting         //
12
// source code which is considered copyrighted (c) material of the          //
13
// original comment or credit authors.                                      //
14
//                                                                          //
15
// This program is distributed in the hope that it will be useful,          //
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of           //
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            //
18
// GNU General Public License for more details.                             //
19
//                                                                          //
20
// You should have received a copy of the GNU General Public License        //
21
// along with this program; if not, write to the Free Software              //
22
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA //
23
// ------------------------------------------------------------------------ //
24
// Author: phppp (D.J., [email protected])                                  //
25
//  URL: https://xoops.org                                                    //
26
// Project: Article Project                                                 //
27
// ------------------------------------------------------------------------ //
28
29
// defined('XOOPS_ROOT_PATH') || exit('Restricted access.');
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...
30
require_once $GLOBALS['xoops']->path('class/tree.php');
31
32
if (!class_exists('ObjectTree')) {
33
    /**
34
     * Class ObjectTree
35
     */
36
    class ObjectTree extends \XoopsObjectTree
37
    {
38
        /**
39
         * @param      $objectArr
40
         * @param null $rootId
41
         */
42
        public function __construct(&$objectArr, $rootId = null)
43
        {
44
            parent::__construct($objectArr, 'forum_id', 'parent_forum', $rootId);
45
        }
46
47
        /**
48
         * Make options for a select box from
49
         *
50
         * @param int        $key         ID of the object to display as the root of select options
51
         * @param string     $ret         (reference to a string when called from outside) Result from previous recursions
52
         * @param string     $prefix_orig String to indent items at deeper levels
53
         * @param string     $prefix_curr String to indent the current item
54
         * @param null|array $tags
55
         * @internal  param string $fieldName Name of the member variable from the
56
         *                                node objects that should be used as the title for the options.
57
         * @internal  param string $selected Value to display as selected
58
         * @access    private
59
         */
60
        protected function makeTreeItems($key, &$ret, $prefix_orig, $prefix_curr = '', $tags = null)
0 ignored issues
show
Coding Style introduced by
$prefix_orig does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
61
        {
62
            if ($key > 0) {
63 View Code Duplication
                if (count($tags) > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
64
                    foreach ($tags as $tag) {
0 ignored issues
show
Bug introduced by
The expression $tags of type null|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
65
                        $ret[$key][$tag] = $this->tree[$key]['obj']->getVar($tag);
66
                    }
67
                } else {
68
                    $ret[$key]['forum_name'] = $this->tree[$key]['obj']->getVar('forum_name');
69
                }
70
                $ret[$key]['prefix'] = $prefix_curr;
0 ignored issues
show
Coding Style introduced by
$prefix_curr does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
71
                $prefix_curr         .= $prefix_orig;
0 ignored issues
show
Coding Style introduced by
$prefix_curr does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
72
            }
73
            if (isset($this->tree[$key]['child']) && !empty($this->tree[$key]['child'])) {
74
                foreach ($this->tree[$key]['child'] as $childkey) {
75
                    $this->makeTreeItems($childkey, $ret, $prefix_orig, $prefix_curr, $tags);
0 ignored issues
show
Coding Style introduced by
$prefix_orig does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
76
                }
77
            }
78
        }
79
80
        /**
81
         * Make a select box with options from the tree
82
         *
83
         * @param  string  $prefix         String to indent deeper levels
84
         * @param  integer $key            ID of the object to display as the root of select options
85
         * @param  null    $tags
86
         * @return array|string  HTML select box
87
         * @internal param string $name Name of the select box
88
         * @internal param string $fieldName Name of the member variable from the
89
         *                                 node objects that should be used as the title for the options.
90
         * @internal param string $selected Value to display as selected
91
         * @internal param bool $addEmptyOption Set TRUE to add an empty option with value "0" at the top of the hierarchy
92
         */
93
        public function &makeTree($prefix = '-', $key = 0, $tags = null)
94
        {
95
            $ret = [];
96
            $this->makeTreeItems($key, $ret, $prefix, '', $tags);
97
98
            return $ret;
99
        }
100
101
        /**
102
         * Make a select box with options from the tree
103
         *
104
         * @param  string  $name           Name of the select box
105
         * @param  string  $fieldName      Name of the member variable from the
106
         *                                 node objects that should be used as the title for the options.
107
         * @param  string  $prefix         String to indent deeper levels
108
         * @param  string  $selected       Value to display as selected
109
         * @param  bool    $addEmptyOption Set TRUE to add an empty option with value "0" at the top of the hierarchy
110
         * @param  integer $key            ID of the object to display as the root of select options
111
         * @param  string  $extra
112
         * @return string  HTML select box
113
         *
114
         * @deprecated since 2.5.9, please use makeSelectElement()
115
         */
116
        public function makeSelBox(
117
            $name,
118
            $fieldName,
119
            $prefix = '-',
120
            $selected = '',
121
            $addEmptyOption = false,
122
            $key = 0,
123
            $extra = '') //makeSelBox($name, $prefix = '-', $selected = '', $EmptyOption = false, $key = 0)
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% 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...
124
        {
125
            $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
126
            trigger_error("makeSelBox() is deprecated since 2.5.9, please use makeSelectElement(), accessed from {$trace[0]['file']} line {$trace[0]['line']},");
127
128
            $ret = '<select name=' . $name . '>';
129
            if (!empty($addEmptyOption)) {
130
                $ret .= '<option value="0">' . (is_string($EmptyOption) ? $EmptyOption : '') . '</option>';
0 ignored issues
show
Coding Style introduced by
$EmptyOption does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
Bug introduced by
The variable $EmptyOption does not exist. Did you mean $addEmptyOption?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
131
            }
132
            $this->_makeSelBoxOptions('forum_name', $selected, $key, $ret, $prefix);
133
            $ret .= '</select>';
134
135
            return $ret;
136
        }
137
138
        /**
139
         * Make a tree for the array of a given category
140
         *
141
         * @param  string  $key   top key of the tree
142
         * @param  array   $ret   the tree
143
         * @param  integer $depth level of subcategories
144
         * @return void
145
         * @internal param array $tags fields to be used
146
         */
147
        public function getAllChildObject($key, &$ret, $depth = 0)
148
        {
149
            if (0 == --$depth) {
150
                return;
151
            }
152
153
            if (isset($this->tree[$key]['child'])) {
154
                foreach ($this->tree[$key]['child'] as $childkey) {
155
                    if (isset($this->tree[$childkey]['obj'])) {
156
                        $ret['child'][$childkey] = $this->tree[$childkey]['obj'];
157
                    }
158
                    $this->getAllChild_object($childkey, $ret['child'][$childkey], $depth);
159
                }
160
            }
161
        }
162
163
        /**
164
         * Make a tree for the array
165
         *
166
         * @param  int|string $key   top key of the tree
0 ignored issues
show
Documentation introduced by
Consider making the type for parameter $key a bit more specific; maybe use integer.
Loading history...
167
         * @param  integer    $depth level of subcategories
168
         * @return array
169
         * @internal param array $tags fields to be used
170
         */
171
        public function &makeObjectTree($key = 0, $depth = 0)
172
        {
173
            $ret = [];
174
            if ($depth > 0) {
175
                ++$depth;
176
            }
177
            $this->getAllChild_object($key, $ret, $depth);
178
179
            return $ret;
180
        }
181
182
        /**
183
         * Make a tree for the array of a given category
184
         *
185
         * @param  string  $key   top key of the tree
186
         * @param  array   $ret   the tree
187
         * @param  array   $tags  fields to be used
188
         * @param  integer $depth level of subcategories
189
         * @return void
190
         */
191
        public function getAllChildArray($key, &$ret, array $tags = [], $depth = 0)
192
        {
193
            if (0 == --$depth) {
194
                return;
195
            }
196
197
            if (isset($this->tree[$key]['child'])) {
198
                foreach ($this->tree[$key]['child'] as $childkey) {
199
                    if (isset($this->tree[$childkey]['obj'])) {
200 View Code Duplication
                        if (count($tags) > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
201
                            foreach ($tags as $tag) {
202
                                $ret['child'][$childkey][$tag] = $this->tree[$childkey]['obj']->getVar($tag);
203
                            }
204
                        } else {
205
                            $ret['child'][$childkey]['forum_name'] = $this->tree[$childkey]['obj']->getVar('forum_name');
206
                        }
207
                    }
208
209
                    $this->getAllChildArray($childkey, $ret['child'][$childkey], $tags, $depth);
210
                }
211
            }
212
        }
213
214
        /**
215
         * Make a tree for the array
216
         *
217
         * @param  int|string $key   top key of the tree
0 ignored issues
show
Documentation introduced by
Consider making the type for parameter $key a bit more specific; maybe use integer.
Loading history...
218
         * @param  array      $tags  fields to be used
0 ignored issues
show
Documentation introduced by
Should the type for parameter $tags not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
219
         * @param  integer    $depth level of subcategories
220
         * @return array
221
         */
222
        public function &makeArrayTree($key = 0, $tags = null, $depth = 0)
223
        {
224
            $ret = [];
225
            if ($depth > 0) {
226
                ++$depth;
227
            }
228
            $this->getAllChildArray($key, $ret, $tags, $depth);
229
230
            return $ret;
231
        }
232
233
        /**#@+
234
         * get all parent forums
235
         *
236
         * @param  string $key     ID of the child object
237
         * @param  array  $ret     (empty when called from outside) Result from previous recursions
238
         * @param  int    $uplevel (empty when called from outside) level of recursion
239
         * @return array  Array of parent nodes.
240
         */
241
        public function &myGetParentForums($key, array $ret = [], $uplevel = 0)
242
        {
243
            if (isset($this->tree[$key]['parent']) && isset($this->tree[$this->tree[$key]['parent']]['obj'])) {
244
                $ret[$uplevel] = $this->tree[$this->tree[$key]['parent']]['obj'];
245
                if ($this->tree[$key]['parent'] !== $key) {
246
                    //$parents = $this->getParentForums($this->tree[$key]['parent'], $ret, $uplevel+1);
0 ignored issues
show
Unused Code Comprehensibility introduced by
71% 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...
247
                    $parents = $this->getParentForums($this->tree[$key]['parent']);
248
                    foreach (array_keys($parents) as $newkey) {
249
                        $ret[$newkey] = $parents[$newkey];
250
                    }
251
                }
252
            }
253
254
            return $ret;
255
        }
256
257
        /**
258
         * @param        $key
259
         * @param  bool  $reverse
260
         * @return array
261
         */
262
        public function &getParentForums($key, $reverse = true)
263
        {
264
            $ret  = [];
265
            $pids = [];
266
            if (isset($this->tree[$key]['parent']) && isset($this->tree[$this->tree[$key]['parent']]['obj'])) {
267
                $pids[]  = $this->tree[$this->tree[$key]['parent']]['obj']->getVar($this->myId);
268
                $parents = $this->myGetParentForums($this->tree[$key]['parent'], $ret);
269
                foreach (array_keys($parents) as $newkey) {
270
                    if (!is_object($newkey)) {
271
                        continue;
272
                    }
273
                    $ret[] = $parents[$newkey]->getVar($this->myId);
274
                }
275
            }
276
            if ($reverse) {
277
                $pids = array_reverse($ret) + $pids;
278
            } else {
279
                $pids += $ret;
280
            }
281
282
            return $pids;
283
        }
284
        /**#@-*/
285
    }
286
}
287