This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the Ariadne Component Library. |
||
5 | * |
||
6 | * (c) Muze <[email protected]> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | namespace arc; |
||
13 | |||
14 | /** |
||
15 | * Utility methods to handle common path related tasks, cleaning, changing relative to absolute, etc. |
||
16 | */ |
||
17 | class tree |
||
18 | { |
||
19 | /** |
||
20 | * Create a simple array from a tree. Each non-null nodeValue will be added with the path to its node as the key |
||
21 | * @param \arc\tree\Node $node |
||
22 | * @param string $root |
||
23 | * @param string $nodeName |
||
24 | * @return array [ $path => $data, ... ] |
||
25 | */ |
||
26 | 10 | public static function collapse($node, $root = '', $nodeName = 'nodeName') |
|
27 | { |
||
28 | 10 | return \arc\tree::map( |
|
29 | 10 | $node, |
|
30 | 10 | function ($child) { |
|
31 | 10 | return $child->nodeValue; |
|
32 | 10 | }, |
|
33 | $root, |
||
34 | $nodeName |
||
35 | ); |
||
36 | } |
||
37 | |||
38 | /** |
||
39 | * Creates a NamedNode tree from an array with path => nodeValue entries. |
||
40 | * @param array $tree The collapsed tree: [ $path => $data, ... ] |
||
41 | * @return \arc\tree\NamedNode an object tree with parent/children relations |
||
42 | */ |
||
43 | 16 | public static function expand($tree = null) |
|
44 | { |
||
45 | 16 | if (is_object( $tree ) && isset( $tree->childNodes )) { |
|
46 | return $tree; //FIXME: should we clone the tree to avoid shared state? |
||
47 | } |
||
48 | 16 | $root = new \arc\tree\NamedNode(); |
|
49 | 16 | if (!is_array($tree)) { |
|
50 | 12 | return $root; // empty tree |
|
51 | } |
||
52 | 4 | $previousParent = $root; |
|
53 | 4 | foreach ($tree as $path => $data) { |
|
54 | 4 | $previousPath = $previousParent->getPath(); |
|
55 | 4 | $subPath = \arc\path::diff( $previousPath, $path ); |
|
56 | 4 | if ($subPath) { |
|
57 | // create missing parent nodes, input tree may be sparsely filled |
||
58 | 4 | $node = \arc\path::reduce( |
|
59 | 4 | $subPath, |
|
60 | 4 | function ($previous, $name) { |
|
61 | 4 | if ($name == '..') { |
|
62 | 4 | return $previous->parentNode; |
|
63 | } |
||
64 | |||
65 | 4 | return $previous->appendChild( $name ); |
|
66 | 4 | }, |
|
67 | 4 | $previousParent |
|
68 | ); |
||
69 | } else { |
||
70 | // means the previousParent is equal to the current path, e.g. the root |
||
71 | $node = $previousParent; |
||
72 | } |
||
73 | 4 | $node->nodeValue = $data; |
|
74 | 4 | $previousParent = $node; |
|
75 | } |
||
76 | |||
77 | 4 | return $root; |
|
78 | } |
||
79 | |||
80 | /** |
||
81 | * Calls the first callback method on each successive parent until a non-null value is returned. Then |
||
82 | * calls all the parents from that point back to this node with the second callback in reverse order. |
||
83 | * The first callback (dive) must accept one parameter, the node. |
||
84 | * The second callback (rise) must accept two parameters, the nde and the result up to that point. |
||
85 | * @param \arc\tree\Node $node A tree node, must have traversable childNodes property and a parentNode property |
||
86 | * @param callable $diveCallback The callback for the dive phase. |
||
87 | * @param callable $riseCallback The callback for the rise phase. |
||
88 | * @return mixed |
||
89 | */ |
||
90 | 8 | public static function dive($node, $diveCallback = null, $riseCallback = null) |
|
91 | { |
||
92 | 8 | $result = null; |
|
93 | 8 | if (is_callable( $diveCallback )) { |
|
94 | 6 | $result = call_user_func( $diveCallback, $node ); |
|
95 | } |
||
96 | 8 | if (!isset( $result ) && $node->parentNode) { |
|
97 | 4 | $result = \arc\tree::dive( $node->parentNode, $diveCallback, $riseCallback ); |
|
0 ignored issues
–
show
|
|||
98 | } |
||
99 | 8 | if (is_callable( $riseCallback )) { |
|
100 | 4 | return call_user_func( $riseCallback, $node, $result ); |
|
101 | } else { |
||
102 | 6 | return $result; |
|
103 | } |
||
104 | } |
||
105 | |||
106 | /** |
||
107 | * Calls the callback method on each parent of the given node, starting at the root. |
||
108 | * @param \arc\tree\Node $node A tree node, must have traversable childNodes property and a parentNode property |
||
109 | * @param callable $callback The callback function applied to each parent. |
||
110 | * @return mixed |
||
111 | */ |
||
112 | 4 | public static function parents($node, $callback = null) |
|
113 | { |
||
114 | 4 | if (!isset( $callback )) { |
|
115 | $callback = function ($node, $result) { |
||
116 | return ( (array) $result ) + array( $node ); |
||
117 | }; |
||
118 | } |
||
119 | |||
120 | 4 | return self::dive( $node, null, $callback ); |
|
121 | } |
||
122 | |||
123 | /** |
||
124 | * Calls the callback method on each of the direct child nodes of the given node. |
||
125 | * @param \arc\tree\Node $node |
||
126 | * @param callable $callback The callback function applied to each child node |
||
127 | * @param mixed $nodeName The name of the 'name' property or a function that returns the name of a node. |
||
128 | * @return array |
||
129 | */ |
||
130 | View Code Duplication | public static function ls($node, $callback, $nodeName = 'nodeName') |
|
0 ignored issues
–
show
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. ![]() |
|||
131 | { |
||
132 | $result = []; |
||
133 | foreach ($node->childNodes as $child) { |
||
0 ignored issues
–
show
The property
childNodes does not seem to exist in arc\tree\Node .
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
134 | $name = self::getNodeName( $child, $nodeName ); |
||
135 | $result[ $name ] = call_user_func( $callback, $child ); |
||
136 | } |
||
137 | |||
138 | return $result; |
||
139 | } |
||
140 | |||
141 | /** |
||
142 | * Calls the callback method on each child of the current node, including the node itself, until a non-null |
||
143 | * result is returned. Returns that result. The tree is searched depth first. |
||
144 | * @param \arc\tree\Node $node |
||
145 | * @param callable $callback The callback function applied to each child node |
||
146 | * @return mixed |
||
147 | */ |
||
148 | public static function search($node, $callback) |
||
149 | { |
||
150 | $result = call_user_func( $callback, $node ); |
||
151 | if (isset( $result )) { |
||
152 | return $result; |
||
153 | } |
||
154 | foreach ($node->childNodes as $child) { |
||
0 ignored issues
–
show
The property
childNodes does not seem to exist in arc\tree\Node .
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
155 | $result = self::search( $child, $callback ); |
||
156 | if (isset( $result )) { |
||
157 | return $result; |
||
158 | } |
||
159 | } |
||
160 | |||
161 | return null; |
||
162 | } |
||
163 | |||
164 | /** |
||
165 | * Calls the callback method on each child of the current node, including the node itself. Any non-null result |
||
166 | * is added to the result array, with the path to the node as the key. |
||
167 | * @param \arc\tree\Node $node |
||
168 | * @param callable $callback The callback function applied to each child node |
||
169 | * @param string $root |
||
170 | * @param mixed $nodeName The name of the 'name' property or a function that returns the name of a node. |
||
171 | * @return array |
||
172 | */ |
||
173 | 10 | public static function map($node, $callback, $root = '', $nodeName = 'nodeName') |
|
174 | { |
||
175 | 10 | $result = []; |
|
176 | 10 | $name = self::getNodeName( $node, $nodeName ); |
|
177 | 10 | $path = $root . $name . '/'; |
|
178 | 10 | $callbackResult = call_user_func( $callback, $node ); |
|
179 | 10 | if (isset($callbackResult)) { |
|
180 | 10 | $result[ $path ] = $callbackResult; |
|
181 | } |
||
182 | 10 | foreach ($node->childNodes as $child) { |
|
0 ignored issues
–
show
The property
childNodes does not seem to exist in arc\tree\Node .
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
183 | 10 | $result += self::map( $child, $callback, $path, $nodeName ); |
|
184 | } |
||
185 | |||
186 | 10 | return $result; |
|
187 | } |
||
188 | |||
189 | /** |
||
190 | * Calls the callback method on all child nodes of the given node, including the node itself. The result of each |
||
191 | * call is passed on as the first argument to each succesive call. |
||
192 | * @param \arc\tree\Node $node |
||
193 | * @param callable $callback |
||
194 | * @param mixed $initial The value to pass to the first callback call. |
||
195 | * @return mixed |
||
196 | */ |
||
197 | View Code Duplication | public static function reduce($node, $callback, $initial = null) |
|
0 ignored issues
–
show
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. ![]() |
|||
198 | { |
||
199 | $result = call_user_func( $callback, $initial, $node ); |
||
200 | foreach ($node->childNodes as $child) { |
||
0 ignored issues
–
show
The property
childNodes does not seem to exist in arc\tree\Node .
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
201 | $result = self::reduce( $child, $callback, $result ); |
||
202 | } |
||
203 | |||
204 | return $result; |
||
205 | } |
||
206 | |||
207 | /** |
||
208 | * Filters the tree using a callback method. If the callback method returns true, the node's value is included |
||
209 | * in the result, otherwise it is skipped. Filter returns a collapsed tree: [ path => nodeValue ] |
||
210 | * The callback method must take one argument: the current node. |
||
211 | * @param \arc\tree\Node $node |
||
212 | * @param callable $callback |
||
213 | * @return array |
||
214 | */ |
||
215 | public static function filter($node, $callback, $root = '', $nodeName = 'nodeName') |
||
216 | { |
||
217 | return self::map( $node, function ($node) use ($callback) { |
||
218 | if (call_user_func( $callback, $node )) { |
||
219 | return $node->nodeValue; |
||
220 | } |
||
221 | }, $root, $nodeName ); |
||
222 | } |
||
223 | |||
224 | /** |
||
225 | * Sorts the childNodes list of the node, recursively. |
||
226 | * @param \arc\tree\Node $node |
||
227 | * @param callable $callback |
||
228 | * @param mixed $nodeName |
||
229 | * @throws UnknownError |
||
230 | */ |
||
231 | public static function sort($node, $callback, $nodeName = 'nodeName') |
||
232 | { |
||
233 | if (is_array($node->childNodes)) { |
||
234 | $sort = function ($node) use ($callback) { |
||
235 | uasort( $node->childNodes, $callback ); |
||
236 | }; |
||
237 | } elseif ($node->childNodes instanceof \ArrayObject) { |
||
0 ignored issues
–
show
The property
childNodes does not seem to exist in arc\tree\Node .
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
238 | $sort = function ($node) use ($callback) { |
||
239 | $node->childNodes->uasort( $callback ); |
||
240 | }; |
||
241 | } else { |
||
242 | throw new \arc\UnknownError( 'Cannot sort this tree - no suitable sort method found', |
||
243 | \arc\exceptions::OBJECT_NOT_FOUND); |
||
244 | } |
||
245 | self::map( $node, $sort, '', $nodeName ); |
||
246 | } |
||
247 | |||
248 | 10 | private static function getNodeName($node, $nodeName) |
|
249 | { |
||
250 | 10 | if (is_callable($nodeName)) { |
|
251 | $name = call_user_func( $nodeName, $node ); |
||
252 | } else { |
||
253 | 10 | $name = $node->{$nodeName}; |
|
254 | } |
||
255 | |||
256 | 10 | return $name; |
|
257 | } |
||
258 | } |
||
259 |
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.
If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.