Passed
Push — master ( 6d0bec...700d12 )
by Michael
05:09 queued 02:42
created

ObjectTree   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 284
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 35
eloc 80
c 0
b 0
f 0
dl 0
loc 284
rs 9.6

12 Methods

Rating   Name   Duplication   Size   Complexity  
A makeSelBox() 0 18 2
A __construct() 0 9 2
A getTree() 0 3 1
A makeSelectElement() 0 20 2
A makeSelBoxOptions() 0 14 6
A initialize() 0 10 3
A __get() 0 11 2
A getByKey() 0 3 1
A getAllChild() 0 13 4
A addSelectOptions() 0 11 5
A getFirstChild() 0 10 3
A getAllParent() 0 11 4
1
<?php
2
3
namespace XoopsModules\News;
4
5
/**
6
 * XOOPS tree class
7
 *
8
 * You may not change or alter any portion of this comment or credits
9
 * of supporting developers from this source code or any supporting source code
10
 * which is considered copyrighted (c) material of the original comment or credit authors.
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
 *
15
 * @copyright       (c) 2000-2020 XOOPS Project (www.xoops.org)
16
 * @license             GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
17
 * @package             kernel
18
 * @since               2.0.0
19
 * @author              Kazumi Ono (http://www.myweb.ne.jp/, http://jp.xoops.org/)
20
 */
21
22
/**
23
 * A tree structures with {@link XoopsObject}s as nodes
24
 *
25
 * @package    kernel
26
 * @subpackage core
27
 * @author     Kazumi Ono <[email protected]>
28
 */
29
class ObjectTree
30
{
31
    /**
32
     * @access private
33
     */
34
    protected $parentId;
35
    protected $myId;
36
    protected $rootId;
37
    protected $tree = [];
38
    protected $objects;
39
40
    /**
41
     * Constructor
42
     *
43
     * @param array  $objectArr Array of {@link XoopsObject}s
44
     * @param string $myId      field name of object ID
45
     * @param string $parentId  field name of parent object ID
46
     * @param string $rootId    field name of root object ID
47
     */
48
    public function __construct($objectArr, $myId, $parentId, $rootId = null)
49
    {
50
        $this->objects  = $objectArr;
51
        $this->myId     = $myId;
52
        $this->parentId = $parentId;
53
        if (isset($rootId)) {
54
            $this->rootId = $rootId;
55
        }
56
        $this->initialize();
57
    }
58
59
    /**
60
     * Initialize the object
61
     *
62
     * @access private
63
     */
64
    protected function initialize()
65
    {
66
        foreach (\array_keys($this->objects) as $i) {
67
            $key1                         = $this->objects[$i]->getVar($this->myId);
68
            $this->tree[$key1]['obj']     = $this->objects[$i];
69
            $key2                         = $this->objects[$i]->getVar($this->parentId);
70
            $this->tree[$key1]['parent']  = $key2;
71
            $this->tree[$key2]['child'][] = $key1;
72
            if (isset($this->rootId)) {
73
                $this->tree[$key1]['root'] = $this->objects[$i]->getVar($this->rootId);
74
            }
75
        }
76
    }
77
78
    /**
79
     * Get the tree
80
     *
81
     * @return array Associative array comprising the tree
82
     */
83
    public function &getTree()
84
    {
85
        return $this->tree;
86
    }
87
88
    /**
89
     * returns an object from the tree specified by its id
90
     *
91
     * @param string $key ID of the object to retrieve
92
     * @return object Object within the tree
93
     */
94
    public function &getByKey($key)
95
    {
96
        return $this->tree[$key]['obj'];
97
    }
98
99
    /**
100
     * returns an array of all the first child object of an object specified by its id
101
     *
102
     * @param string $key ID of the parent object
103
     * @return array  Array of children of the parent
104
     */
105
    public function getFirstChild($key)
106
    {
107
        $ret = [];
108
        if (isset($this->tree[$key]['child'])) {
109
            foreach ($this->tree[$key]['child'] as $childKey) {
110
                $ret[$childKey] = $this->tree[$childKey]['obj'];
111
            }
112
        }
113
114
        return $ret;
115
    }
116
117
    /**
118
     * returns an array of all child objects of an object specified by its id
119
     *
120
     * @param string $key ID of the parent
121
     * @param array  $ret (Empty when called from client) Array of children from previous recursions.
122
     * @return array  Array of child nodes.
123
     */
124
    public function getAllChild($key, $ret = [])
125
    {
126
        if (isset($this->tree[$key]['child'])) {
127
            foreach ($this->tree[$key]['child'] as $childKey) {
128
                $ret[$childKey] = $this->tree[$childKey]['obj'];
129
                $children       = $this->getAllChild($childKey, $ret);
130
                foreach (\array_keys($children) as $newKey) {
131
                    $ret[$newKey] = $children[$newKey];
132
                }
133
            }
134
        }
135
136
        return $ret;
137
    }
138
139
    /**
140
     * returns an array of all parent objects.
141
     * the key of returned array represents how many levels up from the specified object
142
     *
143
     * @param string $key     ID of the child object
144
     * @param array  $ret     (empty when called from outside) Result from previous recursions
145
     * @param int    $upLevel (empty when called from outside) level of recursion
146
     * @return array  Array of parent nodes.
147
     */
148
    public function getAllParent($key, $ret = [], $upLevel = 1)
149
    {
150
        if (isset($this->tree[$key]['parent']) && isset($this->tree[$this->tree[$key]['parent']]['obj'])) {
151
            $ret[$upLevel] = $this->tree[$this->tree[$key]['parent']]['obj'];
152
            $parents       = $this->getAllParent($this->tree[$key]['parent'], $ret, $upLevel + 1);
153
            foreach (\array_keys($parents) as $newKey) {
154
                $ret[$newKey] = $parents[$newKey];
155
            }
156
        }
157
158
        return $ret;
159
    }
160
161
    /**
162
     * Make options for a select box from
163
     *
164
     * @param string $fieldName   Name of the member variable from the
165
     *                            node objects that should be used as the title for the options.
166
     * @param string $selected    Value to display as selected
167
     * @param int    $key         ID of the object to display as the root of select options
168
     * @param string $ret         (reference to a string when called from outside) Result from previous recursions
169
     * @param string $prefix_orig String to indent items at deeper levels
170
     * @param string $prefix_curr String to indent the current item
171
     *
172
     * @deprecated since 2.5.9, please use makeSelectElement() functionality
173
     */
174
    protected function makeSelBoxOptions($fieldName, $selected, $key, &$ret, $prefix_orig, $prefix_curr = '')
175
    {
176
        if ($key > 0) {
177
            $value = $this->tree[$key]['obj']->getVar($this->myId);
178
            $ret   .= '<option value="' . $value . '"';
179
            if ($value == $selected) {
180
                $ret .= ' selected';
181
            }
182
            $ret         .= '>' . $prefix_curr . $this->tree[$key]['obj']->getVar($fieldName) . '</option>';
183
            $prefix_curr .= $prefix_orig;
184
        }
185
        if (isset($this->tree[$key]['child']) && !empty($this->tree[$key]['child'])) {
186
            foreach ($this->tree[$key]['child'] as $childKey) {
187
                $this->makeSelBoxOptions($fieldName, $selected, $childKey, $ret, $prefix_orig, $prefix_curr);
0 ignored issues
show
Deprecated Code introduced by
The function XoopsModules\News\ObjectTree::makeSelBoxOptions() has been deprecated: since 2.5.9, please use makeSelectElement() functionality ( Ignorable by Annotation )

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

187
                /** @scrutinizer ignore-deprecated */ $this->makeSelBoxOptions($fieldName, $selected, $childKey, $ret, $prefix_orig, $prefix_curr);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
188
            }
189
        }
190
    }
191
192
    /**
193
     * Make a select box with options from the tree
194
     *
195
     * @param string $name             Name of the select box
196
     * @param string $fieldName        Name of the member variable from the
197
     *                                 node objects that should be used as the title for the options.
198
     * @param string $prefix           String to indent deeper levels
199
     * @param string $selected         Value to display as selected
200
     * @param bool   $addEmptyOption   Set TRUE to add an empty option with value "0" at the top of the hierarchy
201
     * @param int    $key              ID of the object to display as the root of select options
202
     * @param string $extra
203
     * @return string  HTML select box
204
     *
205
     * @deprecated since 2.5.9, please use makeSelectElement()
206
     */
207
    public function makeSelBox(
208
        $name,
209
        $fieldName,
210
        $prefix = '-',
211
        $selected = '',
212
        $addEmptyOption = false,
213
        $key = 0,
214
        $extra = ''
215
    ) {
216
        $trace = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 1);
217
        \trigger_error("makeSelBox() is deprecated since 2.5.9, please use makeSelectElement(), accessed from {$trace[0]['file']} line {$trace[0]['line']},");
218
        $ret = '<select name="' . $name . '" id="' . $name . '" ' . $extra . '>';
219
        if (false !== (bool)$addEmptyOption) {
220
            $ret .= '<option value="0"></option>';
221
        }
222
        $this->makeSelBoxOptions($fieldName, $selected, $key, $ret, $prefix);
0 ignored issues
show
Deprecated Code introduced by
The function XoopsModules\News\ObjectTree::makeSelBoxOptions() has been deprecated: since 2.5.9, please use makeSelectElement() functionality ( Ignorable by Annotation )

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

222
        /** @scrutinizer ignore-deprecated */ $this->makeSelBoxOptions($fieldName, $selected, $key, $ret, $prefix);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
223
224
        return $ret . '</select>';
225
    }
226
227
    /**
228
     * Make a select box with options from the tree
229
     *
230
     * @param string $name             Name of the select box
231
     * @param string $fieldName        Name of the member variable from the
232
     *                                 node objects that should be used as the title for the options.
233
     * @param string $prefix           String to indent deeper levels
234
     * @param string $selected         Value to display as selected
235
     * @param bool   $addEmptyOption   Set TRUE to add an empty option with value "0" at the top of the hierarchy
236
     * @param int    $key              ID of the object to display as the root of select options
237
     * @param string $extra            extra content to add to the element
238
     * @param string $caption          optional caption for form element
239
     *
240
     * @return \XoopsFormSelect form element
241
     */
242
    public function makeSelectElement(
243
        $name,
244
        $fieldName,
245
        $prefix = '-',
246
        $selected = '',
247
        $addEmptyOption = false,
248
        $key = 0,
249
        $extra = '',
250
        $caption = ''
251
    ) {
252
        \xoops_load('xoopsformselect');
253
        $element = new \XoopsFormSelect($caption, $name, $selected);
254
        $element->setExtra($extra);
255
256
        if (false !== (bool)$addEmptyOption) {
257
            $element->addOption('0', ' ');
258
        }
259
        $this->addSelectOptions($element, $fieldName, $key, $prefix);
260
261
        return $element;
262
    }
263
264
    /**
265
     * Make options for a select box from
266
     *
267
     * @param \XoopsFormSelect $element     form element to receive tree values as options
268
     * @param string           $fieldName   Name of the member variable from the node objects that
269
     *                                      should be used as the title for the options.
270
     * @param int              $key         ID of the object to display as the root of select options
271
     * @param string           $prefix_orig String to indent items at deeper levels
272
     * @param string           $prefix_curr String to indent the current item
273
     *
274
     * @access private
275
     */
276
    protected function addSelectOptions($element, $fieldName, $key, $prefix_orig, $prefix_curr = '')
277
    {
278
        if ($key > 0) {
279
            $value = $this->tree[$key]['obj']->getVar($this->myId);
280
            $name  = $prefix_curr . $this->tree[$key]['obj']->getVar($fieldName);
281
            $element->addOption($value, $name);
282
            $prefix_curr .= $prefix_orig;
283
        }
284
        if (isset($this->tree[$key]['child']) && !empty($this->tree[$key]['child'])) {
285
            foreach ($this->tree[$key]['child'] as $childKey) {
286
                $this->addSelectOptions($element, $fieldName, $childKey, $prefix_orig, $prefix_curr);
287
            }
288
        }
289
    }
290
291
    /**
292
     * Magic __get method
293
     *
294
     * Some modules did not respect the leading underscore is private convention and broke
295
     * when code was modernized. This will keep them running for now.
296
     *
297
     * @param string $name  unknown variable name requested
298
     *                      currently only '_tree' is supported
299
     *
300
     * @return mixed value
301
     */
302
    public function __get($name)
303
    {
304
        $trace = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 1);
305
        if ('_tree' === $name) {
306
            \trigger_error("XoopsObjectTree::\$_tree is deprecated, accessed from {$trace[0]['file']} line {$trace[0]['line']},");
307
308
            return $this->tree;
309
        }
310
        \trigger_error('Undefined property: XoopsObjectTree::$' . $name . " in {$trace[0]['file']} line {$trace[0]['line']}, ", \E_USER_NOTICE);
311
312
        return null;
313
    }
314
}
315