MenuItem::hasActiveStateFromChilds()   A
last analyzed

Complexity

Conditions 6
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.2222
c 0
b 0
f 0
cc 6
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Rinvex\Menus\Models;
6
7
use Illuminate\Support\Str;
8
use Illuminate\Support\Collection;
9
use Illuminate\Support\Facades\Route;
10
use Collective\Html\HtmlFacade as HTML;
11
use Illuminate\Support\Facades\Request;
12
13
class MenuItem
14
{
15
    /**
16
     * The properties array.
17
     *
18
     * @var array
19
     */
20
    public $properties = [];
21
22
    /**
23
     * The childs collection.
24
     *
25
     * @var \Illuminate\Support\Collection
26
     */
27
    protected $childs;
28
29
    /**
30
     * The hide callbacks collection.
31
     *
32
     * @var \Illuminate\Support\Collection
33
     */
34
    protected $hideCallbacks;
35
36
    /**
37
     * The active callback.
38
     *
39
     * @var callable
40
     */
41
    protected $activeWhen;
42
43
    /**
44
     * Constructor.
45
     *
46
     * @param array $properties
47
     */
48
    public function __construct($properties = [])
49
    {
50
        $this->fill($properties);
51
52
        $this->hideCallbacks = collect();
53
        $this->childs = collect();
54
    }
55
56
    /**
57
     * Get property.
58
     *
59
     * @param string $key
60
     *
61
     * @return mixed
62
     */
63
    public function __get($key)
64
    {
65
        return data_get($this->properties, $key);
66
    }
67
68
    /**
69
     * Fill the properties.
70
     *
71
     * @param array $properties
72
     *
73
     * @return static
74
     */
75
    public function fill($properties)
76
    {
77
        $this->properties = array_merge($this->properties, $properties);
78
79
        return $this;
80
    }
81
82
    /**
83
     * Add new child item.
84
     *
85
     * @param array $properties
86
     *
87
     * @return static
88
     */
89
    protected function add(array $properties = [])
90
    {
91
        $properties['attributes']['id'] = $properties['attributes']['id'] ?? md5(json_encode($properties));
92
        $this->childs->push($item = new static($properties));
93
94
        return $item;
95
    }
96
97
    /**
98
     * Create new menu with dropdown.
99
     *
100
     * @param callable $callback
101
     * @param string   $title
102
     * @param int      $order
0 ignored issues
show
Documentation introduced by
Should the type for parameter $order not be null|integer?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
103
     * @param string   $icon
0 ignored issues
show
Documentation introduced by
Should the type for parameter $icon not be null|string?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
104
     * @param array    $attributes
105
     *
106
     * @return static
107
     */
108
    public function dropdown(callable $callback, string $title, int $order = null, string $icon = null, array $attributes = [])
109
    {
110
        $type = 'dropdown';
111
112
        call_user_func($callback, $item = $this->add(compact('type', 'title', 'order', 'icon', 'attributes')));
113
114
        return $item;
115
    }
116
117
    /**
118
     * Register new menu item using registered route.
119
     *
120
     * @param string $route
0 ignored issues
show
Documentation introduced by
Should the type for parameter $route not be array? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
121
     * @param string $title
122
     * @param int    $order
0 ignored issues
show
Documentation introduced by
Should the type for parameter $order not be null|integer?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
123
     * @param string $icon
0 ignored issues
show
Documentation introduced by
Should the type for parameter $icon not be null|string?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
124
     * @param array  $attributes
125
     *
126
     * @return static
127
     */
128
    public function route(array $route, string $title, int $order = null, string $icon = null, array $attributes = [])
129
    {
130
        $type = 'route';
131
132
        return $this->add(compact('type', 'route', 'title', 'order', 'icon', 'attributes'));
133
    }
134
135
    /**
136
     * Register new menu item using url.
137
     *
138
     * @param string $url
139
     * @param string $title
140
     * @param int    $order
0 ignored issues
show
Documentation introduced by
Should the type for parameter $order not be null|integer?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
141
     * @param string $icon
0 ignored issues
show
Documentation introduced by
Should the type for parameter $icon not be null|string?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
142
     * @param array  $attributes
143
     *
144
     * @return static
145
     */
146
    public function url(string $url, string $title, int $order = null, string $icon = null, array $attributes = [])
147
    {
148
        $type = 'url';
149
150
        return $this->add(compact('type', 'url', 'title', 'order', 'icon', 'attributes'));
151
    }
152
153
    /**
154
     * Add new header item.
155
     *
156
     * @param string $title
157
     * @param int    $order
0 ignored issues
show
Documentation introduced by
Should the type for parameter $order not be null|integer?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
158
     * @param string $icon
0 ignored issues
show
Documentation introduced by
Should the type for parameter $icon not be null|string?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
159
     * @param array  $attributes
160
     *
161
     * @return static
162
     */
163
    public function header(string $title, int $order = null, string $icon = null, array $attributes = [])
164
    {
165
        $type = 'header';
166
167
        return $this->add(compact('type', 'title', 'order', 'icon', 'attributes'));
168
    }
169
170
    /**
171
     * Add new divider item.
172
     *
173
     * @param int   $order
0 ignored issues
show
Documentation introduced by
Should the type for parameter $order not be null|integer?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
174
     * @param array $attributes
175
     *
176
     * @return static
177
     */
178
    public function divider(int $order = null, array $attributes = [])
179
    {
180
        $type = 'divider';
181
182
        return $this->add(compact('type', 'order', 'attributes'));
183
    }
184
185
    /**
186
     * Get childs.
187
     *
188
     * @return \Illuminate\Support\Collection
189
     */
190
    public function getChilds(): Collection
191
    {
192
        return $this->childs->sortBy('properties.order');
193
    }
194
195
    /**
196
     * Get url.
197
     *
198
     * @return string
199
     */
200
    public function getUrl(): string
201
    {
202
        return $this->route ? route($this->route[0], $this->route[1] ?? []) : ($this->url ? url($this->url) : '');
0 ignored issues
show
Documentation introduced by
The property route does not exist on object<Rinvex\Menus\Models\MenuItem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
The property url does not exist on object<Rinvex\Menus\Models\MenuItem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
203
    }
204
205
    /**
206
     * Get HTML attribute data.
207
     *
208
     * @return mixed
209
     */
210
    public function getAttributes()
211
    {
212
        return HTML::attributes($this->attributes);
0 ignored issues
show
Documentation introduced by
The property attributes does not exist on object<Rinvex\Menus\Models\MenuItem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
213
    }
214
215
    /**
216
     * Check if the current item is divider.
217
     *
218
     * @return bool
219
     */
220
    public function isDivider(): bool
221
    {
222
        return $this->type === 'divider';
0 ignored issues
show
Documentation introduced by
The property type does not exist on object<Rinvex\Menus\Models\MenuItem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
223
    }
224
225
    /**
226
     * Check if the current item is header.
227
     *
228
     * @return bool
229
     */
230
    public function isHeader(): bool
231
    {
232
        return $this->type === 'header';
0 ignored issues
show
Documentation introduced by
The property type does not exist on object<Rinvex\Menus\Models\MenuItem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
233
    }
234
235
    /**
236
     * Check is the current item has sub menu .
237
     *
238
     * @return bool
239
     */
240
    public function hasChilds(): bool
241
    {
242
        return $this->getChilds()->isNotEmpty();
243
    }
244
245
    /**
246
     * Check the active state for current menu.
247
     *
248
     * @return bool
249
     */
250
    public function hasActiveOnChild(): bool
251
    {
252
        return $this->hasChilds() ? $this->hasActiveStateFromChilds() : false;
253
    }
254
255
    /**
256
     * Set hide callback for current menu item.
257
     *
258
     * @param callable $callback
259
     *
260
     * @return $this
261
     */
262
    public function hideWhen(callable $callback)
263
    {
264
        $this->hideCallbacks->push($callback);
265
266
        return $this;
267
    }
268
269
    /**
270
     * Set authorization callback for current menu item.
271
     *
272
     * @param string $ability
273
     * @param mixed  $params
274
     * @param string $guard
0 ignored issues
show
Documentation introduced by
Should the type for parameter $guard not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
275
     *
276
     * @return $this
277
     */
278
    public function ifCan(string $ability, $params = null, $guard = null)
279
    {
280
        $this->hideCallbacks->push(function () use ($ability, $params, $guard) {
281
            return ! optional(auth()->guard($guard)->user())->can($ability, $params);
0 ignored issues
show
Bug introduced by
The method guard does only exist in Illuminate\Contracts\Auth\Factory, but not in Illuminate\Contracts\Auth\Guard.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
282
        });
283
284
        return $this;
285
    }
286
287
    /**
288
     * Set condition callback for current menu item.
289
     *
290
     * @param mixed $condition
291
     *
292
     * @return $this
293
     */
294
    public function if($condition)
295
    {
296
        $this->hideCallbacks->push(function () use ($condition) {
297
            return ! $condition;
298
        });
299
300
        return $this;
301
    }
302
303
    /**
304
     * Set authentication callback for current menu item.
305
     *
306
     * @param string $guard
0 ignored issues
show
Documentation introduced by
Should the type for parameter $guard not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
307
     *
308
     * @return $this
309
     */
310
    public function ifUser($guard = null)
311
    {
312
        $this->hideCallbacks->push(function () use ($guard) {
313
            return ! auth()->guard($guard)->user();
0 ignored issues
show
Bug introduced by
The method guard does only exist in Illuminate\Contracts\Auth\Factory, but not in Illuminate\Contracts\Auth\Guard.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
314
        });
315
316
        return $this;
317
    }
318
319
    /**
320
     * Set authentication callback for current menu item.
321
     *
322
     * @param string $guard
0 ignored issues
show
Documentation introduced by
Should the type for parameter $guard not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
323
     *
324
     * @return $this
325
     */
326
    public function ifGuest($guard = null)
327
    {
328
        $this->hideCallbacks->push(function () use ($guard) {
329
            return auth()->guard($guard)->user();
0 ignored issues
show
Bug introduced by
The method guard does only exist in Illuminate\Contracts\Auth\Factory, but not in Illuminate\Contracts\Auth\Guard.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
330
        });
331
332
        return $this;
333
    }
334
335
    /**
336
     * Check if the menu item is hidden.
337
     *
338
     * @return bool
339
     */
340
    public function isHidden(): bool
341
    {
342
        return (bool) $this->hideCallbacks->first(function ($callback) {
343
            return call_user_func($callback);
344
        });
345
    }
346
347
    /**
348
     * Get active state for current item.
349
     *
350
     * @return bool
351
     */
352
    public function isActive(): bool
353
    {
354
        if (is_callable($activeWhen = $this->activeWhen)) {
355
            return call_user_func($activeWhen);
356
        }
357
358
        if ($this->route) {
0 ignored issues
show
Documentation introduced by
The property route does not exist on object<Rinvex\Menus\Models\MenuItem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
359
            return $this->hasActiveStateFromRoute();
360
        }
361
362
        return $this->hasActiveStateFromUrl();
363
    }
364
365
    /**
366
     * Set active callback.
367
     *
368
     * @param callable $route
0 ignored issues
show
Bug introduced by
There is no parameter named $route. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
369
     *
370
     * @return $this
371
     */
372
    public function activateWhen(callable $callback)
373
    {
374
        $this->activeWhen = $callback;
375
376
        return $this;
377
    }
378
379
    /**
380
     * Set active callback on the given route.
381
     *
382
     * @param string $route
383
     *
384
     * @return $this
385
     */
386
    public function activateOnRoute(string $route)
387
    {
388
        $this->activeWhen = function () use ($route) {
389
            return Str::contains(Route::currentRouteName(), $route);
390
        };
391
392
        return $this;
393
    }
394
395
    /**
396
     * Get active status using route.
397
     *
398
     * @return bool
399
     */
400
    protected function hasActiveStateFromRoute(): bool
401
    {
402
        return Route::is($this->route[0]);
0 ignored issues
show
Documentation introduced by
The property route does not exist on object<Rinvex\Menus\Models\MenuItem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
403
    }
404
405
    /**
406
     * Get active status using request url.
407
     *
408
     * @return bool
409
     */
410
    protected function hasActiveStateFromUrl(): bool
411
    {
412
        return Request::is($this->url);
0 ignored issues
show
Documentation introduced by
The property url does not exist on object<Rinvex\Menus\Models\MenuItem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
413
    }
414
415
    /**
416
     * Check if the item has active state from childs.
417
     *
418
     * @return bool
419
     */
420
    protected function hasActiveStateFromChilds(): bool
421
    {
422
        return $this->getChilds()->contains(function (self $child) {
423
            return ($child->hasChilds() && $child->hasActiveStateFromChilds())
424
                       || ($child->route && $child->hasActiveStateFromRoute())
425
                       || $child->isActive() || $child->hasActiveStateFromUrl();
426
        }) ?? false;
427
    }
428
}
429