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 | namespace Vine; |
||
4 | |||
5 | use Vine\Commands\Move; |
||
6 | use Vine\Commands\Prune; |
||
7 | use Vine\Commands\Shake; |
||
8 | use Vine\Queries\Ancestors; |
||
9 | use Vine\Queries\Count; |
||
10 | use Vine\Commands\Copy; |
||
11 | use Vine\Queries\Pluck; |
||
12 | |||
13 | class Node |
||
14 | { |
||
15 | /** |
||
16 | * @var self |
||
17 | */ |
||
18 | private $parent; |
||
19 | |||
20 | /** |
||
21 | * @var NodeCollection |
||
22 | */ |
||
23 | private $children; |
||
24 | |||
25 | /** |
||
26 | * @var mixed |
||
27 | */ |
||
28 | private $entry; |
||
29 | |||
30 | 171 | public function __construct($entry) |
|
31 | { |
||
32 | 171 | $this->entry = $entry; |
|
33 | 171 | $this->children = new NodeCollection; |
|
34 | 171 | } |
|
35 | |||
36 | 42 | public function equals(self $other) |
|
37 | { |
||
38 | 42 | return $this === $other; |
|
39 | } |
||
40 | |||
41 | /** |
||
42 | * @param array|NodeCollection $children |
||
43 | * @return Node |
||
44 | */ |
||
45 | 129 | public function addChildren($children): self |
|
46 | { |
||
47 | 129 | $children = $this->transformToNodeCollection($children); |
|
48 | |||
49 | 126 | $this->children->merge($children); |
|
0 ignored issues
–
show
|
|||
50 | |||
51 | 126 | array_map(function(Node $child){ |
|
52 | 126 | $child->parent($this); |
|
0 ignored issues
–
show
$this is of type this<Vine\Node> , but the function expects a null|object<self> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
53 | 126 | },$children->all()); |
|
54 | |||
55 | 126 | return $this; |
|
56 | } |
||
57 | |||
58 | /** |
||
59 | * @return NodeCollection |
||
60 | */ |
||
61 | 93 | public function children(): NodeCollection |
|
62 | { |
||
63 | 93 | return $this->children; |
|
64 | } |
||
65 | |||
66 | 75 | public function entry($key = null) |
|
67 | { |
||
68 | 75 | if(!is_null($key)) |
|
69 | { |
||
70 | 45 | return (is_array($this->entry) && isset($this->entry[$key])) |
|
71 | 42 | ? $this->entry[$key] |
|
72 | 45 | : (is_object($this->entry) ? $this->entry->{$key} : null); |
|
73 | } |
||
74 | |||
75 | 39 | return $this->entry; |
|
76 | } |
||
77 | |||
78 | /** |
||
79 | * Replace entire entry value |
||
80 | * |
||
81 | * @param $entry |
||
82 | */ |
||
83 | 3 | public function replaceEntry($entry) |
|
84 | { |
||
85 | 3 | $this->entry = $entry; |
|
86 | 3 | } |
|
87 | |||
88 | /** |
||
89 | * @param Node $parent |
||
90 | * @return $this |
||
91 | */ |
||
92 | 126 | public function parent(self $parent = null) |
|
93 | { |
||
94 | // Without arguments this method returns the parent node |
||
95 | 126 | if(!$parent) return $this->parent; |
|
96 | |||
97 | 126 | $this->parent = $parent; |
|
0 ignored issues
–
show
It seems like
$parent of type object<self> is incompatible with the declared type object<Vine\Node> of property $parent .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
98 | |||
99 | 126 | return $this; |
|
100 | } |
||
101 | |||
102 | /** |
||
103 | * Remove this node or (detaches) a child node. |
||
104 | * This detaches self from parent or when node is passed, it deletes that child node from any depth in the graph |
||
105 | * Also removes the entire children tree from that node! |
||
106 | * |
||
107 | * @param Node $node |
||
108 | * @return $this |
||
109 | */ |
||
110 | 33 | public function remove(self $node = null) |
|
111 | { |
||
112 | // Remove self from the parent node |
||
113 | 33 | if(is_null($node) && !$this->isRoot()) |
|
114 | { |
||
115 | 24 | $this->parent()->remove($this); |
|
0 ignored issues
–
show
$this is of type this<Vine\Node> , but the function expects a null|object<self> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
116 | 24 | $this->parent = null; |
|
117 | |||
118 | 24 | return $this; |
|
119 | } |
||
120 | |||
121 | // remove node from node tree |
||
122 | 33 | return $this->children()->remove($node); |
|
0 ignored issues
–
show
It seems like
$node defined by parameter $node on line 110 can also be of type null ; however, Vine\NodeCollection::remove() does only seem to accept object<Vine\Node> , maybe add an additional type check?
This check looks at variables that have been passed in as parameters and are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() The return type of
return $this->children()->remove($node); (Vine\NodeCollection ) is incompatible with the return type documented by Vine\Node::remove of type Vine\Node .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function ![]() |
|||
123 | } |
||
124 | |||
125 | /** |
||
126 | * Move a child node to a different parent |
||
127 | * |
||
128 | * @param Node $parent |
||
129 | * @return mixed |
||
130 | */ |
||
131 | 21 | public function move(self $parent) |
|
132 | { |
||
133 | 21 | return (new Move())($this,$parent); |
|
134 | } |
||
135 | |||
136 | 3 | public function moveToRoot() |
|
137 | { |
||
138 | 3 | return $this->remove(); |
|
139 | } |
||
140 | |||
141 | /** |
||
142 | * At which depth does this node resides inside the entire tree |
||
143 | * |
||
144 | * @return int |
||
145 | */ |
||
146 | 3 | public function depth(): int |
|
147 | { |
||
148 | 3 | if($this->isRoot()) return 0; |
|
149 | |||
150 | 3 | return $this->parent()->depth() + 1; |
|
151 | } |
||
152 | |||
153 | /** |
||
154 | * count of all direct child nodes |
||
155 | * |
||
156 | * @return int |
||
157 | */ |
||
158 | 6 | public function count(): int |
|
159 | { |
||
160 | 6 | if($this->isLeaf()) return 0; |
|
161 | |||
162 | 6 | return $this->children()->count(); |
|
163 | } |
||
164 | |||
165 | /** |
||
166 | * Total of all child nodes |
||
167 | * |
||
168 | * @return int |
||
169 | */ |
||
170 | 12 | public function total(): int |
|
171 | { |
||
172 | 12 | if($this->isLeaf()) return 0; |
|
173 | |||
174 | 12 | return (new Count)($this); |
|
175 | } |
||
176 | |||
177 | /** |
||
178 | * @return bool |
||
179 | */ |
||
180 | 27 | public function isLeaf(): bool |
|
181 | { |
||
182 | 27 | return $this->children->isEmpty(); |
|
183 | } |
||
184 | |||
185 | /** |
||
186 | * @return bool |
||
187 | */ |
||
188 | 48 | public function isRoot(): bool |
|
189 | { |
||
190 | 48 | return !$this->parent; |
|
191 | } |
||
192 | |||
193 | /** |
||
194 | * @param $key |
||
195 | * @param array $values |
||
196 | * @return NodeCollection |
||
197 | */ |
||
198 | 3 | public function findMany($key, array $values): NodeCollection |
|
199 | { |
||
200 | 3 | return $this->children()->findMany($key, $values); |
|
201 | } |
||
202 | |||
203 | /** |
||
204 | * @param $key |
||
205 | * @param $value |
||
206 | * @return Node |
||
207 | */ |
||
208 | 3 | public function find($key, $value): Node |
|
209 | { |
||
210 | 3 | return $this->children()->find($key, $value); |
|
211 | } |
||
212 | |||
213 | /** |
||
214 | * @param null $depth |
||
215 | * @return NodeCollection |
||
216 | */ |
||
217 | 9 | public function ancestors($depth = null): NodeCollection |
|
218 | { |
||
219 | 9 | return (new Ancestors)($this, $depth); |
|
220 | } |
||
221 | |||
222 | /** |
||
223 | * Get flat array of plucked values from child nodes |
||
224 | * |
||
225 | * @param $key |
||
226 | * @param null $value |
||
227 | * @param bool $down |
||
228 | * @return array |
||
229 | */ |
||
230 | 12 | public function pluck($key, $value = null, $down = true): array |
|
231 | { |
||
232 | 12 | return (new Pluck)($this, $key, $value, $down); |
|
233 | } |
||
234 | |||
235 | /** |
||
236 | * Get flat array of plucked values from child nodes |
||
237 | * |
||
238 | * @param $key |
||
239 | * @param null $value |
||
240 | * @return array |
||
241 | */ |
||
242 | 3 | public function pluckAncestors($key, $value = null): array |
|
243 | { |
||
244 | 3 | return $this->pluck($key, $value, false); |
|
245 | } |
||
246 | |||
247 | /** |
||
248 | * Get a copy of this node |
||
249 | * |
||
250 | * @param null|int $depth |
||
251 | * @return Node |
||
252 | */ |
||
253 | 33 | public function copy($depth = null): self |
|
254 | { |
||
255 | 33 | return $depth === 0 |
|
256 | 33 | ? new self($this->entry()) |
|
257 | 33 | : (new Copy())($this,$depth); |
|
258 | } |
||
259 | |||
260 | /** |
||
261 | * Copy of this node without its parent / children relationships |
||
262 | * |
||
263 | * @return Node |
||
264 | */ |
||
265 | 33 | public function isolatedCopy(): self |
|
266 | { |
||
267 | 33 | return $this->copy(0); |
|
268 | } |
||
269 | |||
270 | /** |
||
271 | * Reduce collection to the nodes that pass the callback |
||
272 | * Shaking a collection will keep the ancestor structure |
||
273 | * |
||
274 | * @param callable $callback |
||
275 | * @return self |
||
276 | */ |
||
277 | 9 | public function shake(Callable $callback): self |
|
278 | { |
||
279 | 9 | return (new Shake())($this, $callback); |
|
280 | } |
||
281 | |||
282 | /** |
||
283 | * Same as shaking except that it will not keep the ancestor structure |
||
284 | * |
||
285 | * @param callable $callback |
||
286 | * @return self |
||
287 | */ |
||
288 | 12 | public function prune(Callable $callback): self |
|
289 | { |
||
290 | 12 | return (new Prune())($this, $callback); |
|
291 | } |
||
292 | |||
293 | /** |
||
294 | * @param $children |
||
295 | * @return NodeCollection |
||
296 | */ |
||
297 | 129 | private function transformToNodeCollection($children): NodeCollection |
|
298 | { |
||
299 | 129 | if (is_array($children)) { |
|
300 | 123 | $children = new NodeCollection(...$children); |
|
301 | 45 | } elseif ($children instanceof Node) { |
|
302 | 27 | $children = new NodeCollection($children); |
|
303 | 33 | } elseif (!$children instanceof NodeCollection) { |
|
304 | 3 | throw new \InvalidArgumentException('Invalid children parameter. Accepted types are array or NodeCollection.'); |
|
305 | } |
||
306 | |||
307 | 126 | return $children; |
|
308 | } |
||
309 | |||
310 | /** |
||
311 | * Fetch entry data via a direct call to Node. |
||
312 | * E.g. $node->name resolves to $node->entry('name') |
||
313 | * |
||
314 | * @param $name |
||
315 | * @return mixed|null|NodeCollection |
||
316 | */ |
||
317 | 15 | public function __get($name) |
|
318 | { |
||
319 | 15 | if($name == 'children') return $this->children(); |
|
320 | |||
321 | 12 | return $this->entry($name); |
|
322 | } |
||
323 | } |
||
324 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: