Completed
Pull Request — master (#550)
by Richard
08:09
created

XoopsObjectTree::getByKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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

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

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

Loading history...
202
            }
203
        }
204
    }
205
206
    /**
207
     * Make a select box with options from the tree
208
     *
209
     * @param  string  $name           Name of the select box
210
     * @param  string  $fieldName      Name of the member variable from the
211
     *                                 node objects that should be used as the title for the options.
212
     * @param  string  $prefix         String to indent deeper levels
213
     * @param  string  $selected       Value to display as selected
214
     * @param  bool    $addEmptyOption Set TRUE to add an empty option with value "0" at the top of the hierarchy
215
     * @param  integer $key            ID of the object to display as the root of select options
216
     * @param  string  $extra          extra content to add to the element
217
     * @return string  HTML select box
218
     *
219
     * @deprecated since 2.5.9, please use makeSelectElement()
220
     */
221
    public function makeSelBox(
222
        $name,
223
        $fieldName,
224
        $prefix = '-',
225
        $selected = '',
226
        $addEmptyOption = false,
227
        $key = 0,
228
        $extra = ''
229
    ) {
230
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
231
        trigger_error("makeSelBox() is deprecated since 2.5.9, please use makeSelectElement(), accessed from {$trace[0]['file']} line {$trace[0]['line']},");
232
        $ret = '<select name="' . $name . '" id="' . $name . '" ' . $extra . '>';
233
        if (false !== (bool)$addEmptyOption) {
234
            $ret .= '<option value="0"></option>';
235
        }
236
        $this->makeSelBoxOptions($fieldName, $selected, $key, $ret, $prefix);
0 ignored issues
show
Deprecated Code introduced by
The method XoopsObjectTree::makeSelBoxOptions() has been deprecated with message: since 2.5.9, please use makeSelectElement() functionality

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

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

Loading history...
237
238
        return $ret . '</select>';
239
    }
240
241
    /**
242
     * Make a select box with options from the tree
243
     *
244
     * @param  string  $name           Name of the select box
245
     * @param  string  $fieldName      Name of the member variable from the
246
     *                                 node objects that should be used as the title for the options.
247
     * @param  string  $prefix         String to indent deeper levels
248
     * @param  string  $selected       Value to display as selected
249
     * @param  bool    $addEmptyOption Set TRUE to add an empty option with value "0" at the top of the hierarchy
250
     * @param  integer $key            ID of the object to display as the root of select options
251
     * @param  string  $extra          extra content to add to the element
252
     * @param  string  $caption        optional caption for form element
253
     *
254
     * @return XoopsFormSelect form element
255
     */
256
    public function makeSelectElement(
257
        $name,
258
        $fieldName,
259
        $prefix = '-',
260
        $selected = '',
261
        $addEmptyOption = false,
262
        $key = 0,
263
        $extra = '',
264
        $caption = ''
265
    ) {
266
        $element = new XoopsFormSelect($caption, $name, $selected);
267
        $element->setExtra($extra);
0 ignored issues
show
Deprecated Code introduced by
The method Xoops\Form\Element::setExtra() has been deprecated with message: please use attributes for event scripting

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

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

Loading history...
268
269
        if (false !== (bool)$addEmptyOption) {
270
            $element->addOption('0', ' ');
271
        }
272
        $this->addSelectOptions($element, $fieldName, $key, $prefix);
273
274
        return $element;
275
    }
276
277
    /**
278
     * Make options for a select box from
279
     *
280
     * @param XoopsFormSelect $element     form element to receive tree values as options
281
     * @param string          $fieldName   Name of the member variable from the node objects that
282
     *                                     should be used as the title for the options.
283
     * @param int             $key         ID of the object to display as the root of select options
284
     * @param string          $prefix_orig String to indent items at deeper levels
285
     * @param string          $prefix_curr String to indent the current item
286
     *
287
     * @return void
288
     */
289
    protected function addSelectOptions($element, $fieldName, $key, $prefix_orig, $prefix_curr = '')
290
    {
291
        if ($key > 0) {
292
            $value = $this->tree[$key]['obj']->getVar($this->myId);
293
            $name = $prefix_curr . $this->tree[$key]['obj']->getVar($fieldName);
294
            $element->addOption($value, $name);
295
            $prefix_curr .= $prefix_orig;
296
        }
297 View Code Duplication
        if (isset($this->tree[$key]['child']) && !empty($this->tree[$key]['child'])) {
298
            foreach ($this->tree[$key]['child'] as $childKey) {
299
                $this->addSelectOptions($element, $fieldName, $childKey, $prefix_orig, $prefix_curr);
300
            }
301
        }
302
    }
303
304
    /**
305
     * Magic __get method
306
     *
307
     * Some modules did not respect the leading underscore is private convention and broke
308
     * when code was modernized. This will keep them running for now.
309
     *
310
     * @param string $name unknown variable name requested
311
     *                      currently only '_tree' is supported
312
     *
313
     * @return mixed value
314
     */
315
    public function __get($name)
316
    {
317
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
318
        if ($name === '_tree') {
319
            trigger_error("XoopsObjectTree::\$_tree is deprecated, accessed from {$trace[0]['file']} line {$trace[0]['line']},");
320
            return $this->tree;
321
        }
322
        trigger_error(
323
            'Undefined property: XoopsObjectTree::$' . $name .
324
            " in {$trace[0]['file']} line {$trace[0]['line']}, ",
325
            E_USER_NOTICE);
326
        return null;
327
    }
328
}
329