Completed
Pull Request — master (#243)
by Richard
17:23
created

XoopsObjectTree::__get()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 10
nc 2
nop 1
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
1
<?php
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 28 and the first side effect is on line 19.

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
 * XOOPS tree class
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 (http://www.gnu.org/licenses/gpl-2.0.html)
14
 * @package             kernel
15
 * @since               2.0.0
16
 * @author              Kazumi Ono (http://www.myweb.ne.jp/, http://jp.xoops.org/)
17
 */
18
19
defined('XOOPS_ROOT_PATH') || exit('Restricted access');
20
21
/**
22
 * A tree structures with {@link XoopsObject}s as nodes
23
 *
24
 * @package    kernel
25
 * @subpackage core
26
 * @author     Kazumi Ono <[email protected]>
27
 */
28
class XoopsObjectTree
29
{
30
    /**
31
     * @access private
32
     */
33
    protected $parentId;
34
    protected $myId;
35
    protected $rootId;
36
    protected $tree = array();
37
    protected $objects;
38
39
    /**
40
     * Constructor
41
     *
42
     * @param array  $objectArr Array of {@link XoopsObject}s
43
     * @param string $myId      field name of object ID
44
     * @param string $parentId  field name of parent object ID
45
     * @param string $rootId    field name of root object ID
46
     */
47
    public function __construct(&$objectArr, $myId, $parentId, $rootId = null)
48
    {
49
        $this->objects = $objectArr;
50
        $this->myId     = $myId;
51
        $this->parentId = $parentId;
52
        if (isset($rootId)) {
53
            $this->rootId = $rootId;
54
        }
55
        $this->initialize();
56
    }
57
58
    /**
59
     * Initialize the object
60
     *
61
     * @access private
62
     */
63
    protected function initialize()
64
    {
65
        foreach (array_keys($this->objects) as $i) {
66
            $key1                          = $this->objects[$i]->getVar($this->myId);
67
            $this->tree[$key1]['obj']     = $this->objects[$i];
68
            $key2                          = $this->objects[$i]->getVar($this->parentId);
69
            $this->tree[$key1]['parent']  = $key2;
70
            $this->tree[$key2]['child'][] = $key1;
71
            if (isset($this->rootId)) {
72
                $this->tree[$key1]['root'] = $this->objects[$i]->getVar($this->rootId);
73
            }
74
        }
75
    }
76
77
    /**
78
     * Get the tree
79
     *
80
     * @return array Associative array comprising the tree
81
     */
82
    public function &getTree()
83
    {
84
        return $this->tree;
85
    }
86
87
    /**
88
     * returns an object from the tree specified by its id
89
     *
90
     * @param  string $key ID of the object to retrieve
91
     * @return object Object within the tree
92
     */
93
    public function &getByKey($key)
94
    {
95
        return $this->tree[$key]['obj'];
96
    }
97
98
    /**
99
     * returns an array of all the first child object of an object specified by its id
100
     *
101
     * @param  string $key ID of the parent object
102
     * @return array  Array of children of the parent
103
     */
104
    public function getFirstChild($key)
105
    {
106
        $ret = array();
107
        if (isset($this->tree[$key]['child'])) {
108
            foreach ($this->tree[$key]['child'] as $childKey) {
109
                $ret[$childKey] = $this->tree[$childKey]['obj'];
110
            }
111
        }
112
113
        return $ret;
114
    }
115
116
    /**
117
     * returns an array of all child objects of an object specified by its id
118
     *
119
     * @param  string $key ID of the parent
120
     * @param  array  $ret (Empty when called from client) Array of children from previous recursions.
121
     * @return array  Array of child nodes.
122
     */
123
    public function getAllChild($key, $ret = array())
124
    {
125
        if (isset($this->tree[$key]['child'])) {
126
            foreach ($this->tree[$key]['child'] as $childKey) {
127
                $ret[$childKey] = $this->tree[$childKey]['obj'];
128
                $children       = $this->getAllChild($childKey, $ret);
129
                foreach (array_keys($children) as $newKey) {
130
                    $ret[$newKey] = $children[$newKey];
131
                }
132
            }
133
        }
134
135
        return $ret;
136
    }
137
138
    /**
139
     * returns an array of all parent objects.
140
     * the key of returned array represents how many levels up from the specified object
141
     *
142
     * @param  string $key     ID of the child object
143
     * @param  array  $ret     (empty when called from outside) Result from previous recursions
144
     * @param  int    $upLevel (empty when called from outside) level of recursion
145
     * @return array  Array of parent nodes.
146
     */
147
    public function getAllParent($key, $ret = array(), $upLevel = 1)
148
    {
149
        if (isset($this->tree[$key]['parent']) && isset($this->tree[$this->tree[$key]['parent']]['obj'])) {
150
            $ret[$upLevel] = $this->tree[$this->tree[$key]['parent']]['obj'];
151
            $parents       = $this->getAllParent($this->tree[$key]['parent'], $ret, $upLevel + 1);
152
            foreach (array_keys($parents) as $newKey) {
153
                $ret[$newKey] = $parents[$newKey];
154
            }
155
        }
156
157
        return $ret;
158
    }
159
160
    /**
161
     * Make options for a select box from
162
     *
163
     * @param string $fieldName   Name of the member variable from the
164
     *                            node objects that should be used as the title for the options.
165
     * @param string $selected    Value to display as selected
166
     * @param int    $key         ID of the object to display as the root of select options
167
     * @param string $ret         (reference to a string when called from outside) Result from previous recursions
168
     * @param string $prefix_orig String to indent items at deeper levels
169
     * @param string $prefix_curr String to indent the current item
170
     *
171
     * @return void
172
     * @access private
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);
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  integer $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
    public function makeSelBox(
206
        $name,
207
        $fieldName,
208
        $prefix = '-',
209
        $selected = '',
210
        $addEmptyOption = false,
211
        $key = 0,
212
        $extra = ''
213
    ) {
214
        $ret = '<select name="' . $name . '" id="' . $name . '" ' . $extra . '>';
215
        if (false !== (bool)$addEmptyOption) {
216
            $ret .= '<option value="0"></option>';
217
        }
218
        $this->makeSelBoxOptions($fieldName, $selected, $key, $ret, $prefix);
219
220
        return $ret . '</select>';
221
    }
222
223
    /**
224
     * Magic __get method
225
     *
226
     * Some modules did not respect the leading underscore is private convention and broke
227
     * when code was modernized. This will keep them running for now.
228
     *
229
     * @param string $name unknown variable name requested
230
     *                      currently only '_tree' is supported
231
     *
232
     * @return mixed value
233
     */
234
    public function __get($name)
235
    {
236
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
237
        if ($name === '_tree') {
238
            trigger_error("XoopsObjectTree::\$_tree is deprecated, accessed from {$trace[0]['file']} line {$trace[0]['line']},");
239
            return $this->tree;
240
        }
241
        trigger_error(
242
            'Undefined property: XoopsObjectTree::$' . $name .
243
            " in {$trace[0]['file']} line {$trace[0]['line']}, ",
244
            E_USER_NOTICE);
245
        return null;
246
    }
247
}
248