Completed
Push — master ( 890b95...e7da07 )
by ARCANEDEV
12s
created

Item::parseUrl()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
nc 8
nop 1
dl 0
loc 11
ccs 8
cts 8
cp 1
crap 4
rs 9.9
c 0
b 0
f 0
1
<?php namespace Arcanesoft\Sidebar;
2
3
use Illuminate\Contracts\Support\Arrayable;
4
use Illuminate\Contracts\Support\Jsonable;
5
use Illuminate\Support\Arr;
6
use JsonSerializable;
7
8
/**
9
 * Class     Item
10
 *
11
 * @package  Arcanesoft\Sidebar
12
 * @author   ARCANEDEV <[email protected]>
13
 */
14
class Item implements Arrayable, Jsonable, JsonSerializable
15
{
16
    /* -----------------------------------------------------------------
17
     |  Properties
18
     | -----------------------------------------------------------------
19
     */
20
21
    /** @var  string */
22
    protected $name;
23
24
    /** @var  string */
25
    public $title;
26
27
    /** @var  string */
28
    public $url;
29
30
    /** @var  string */
31
    public $icon;
32
33
    /** @var  \Arcanesoft\Sidebar\Collection */
34
    public $children;
35
36
    /** @var  array */
37
    protected $roles;
38
39
    /** @var  array */
40
    protected $permissions;
41
42
    /** @var boolean */
43
    private $selected;
44
45
    /* -----------------------------------------------------------------
46
     |  Constructor
47
     | -----------------------------------------------------------------
48
     */
49
50
    /**
51
     * SidebarItem constructor.
52
     *
53
     * @param  array  $attributes
54
     */
55 56
    public function __construct(array $attributes)
56
    {
57 56
        $this->name        = Arr::pull($attributes, 'name');
58 56
        $this->setTitle(Arr::pull($attributes, 'title'));
59 56
        $this->icon        = Arr::pull($attributes, 'icon');
60 56
        $this->roles       = Arr::pull($attributes, 'roles', []);
0 ignored issues
show
Documentation Bug introduced by
It seems like \Illuminate\Support\Arr:...utes, 'roles', array()) of type * is incompatible with the declared type array of property $roles.

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..

Loading history...
61 56
        $this->permissions = Arr::pull($attributes, 'permissions', []);
0 ignored issues
show
Documentation Bug introduced by
It seems like \Illuminate\Support\Arr:...'permissions', array()) of type * is incompatible with the declared type array of property $permissions.

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..

Loading history...
62 56
        $this->children    = (new Collection)->addItems(
63 56
            Arr::pull($attributes, 'children', [])
64
        );
65 56
        $this->selected    = false;
66
67 56
        $this->parseUrl($attributes);
68 56
    }
69
70
    /* -----------------------------------------------------------------
71
     |  Setters & Getters
72
     | -----------------------------------------------------------------
73
     */
74
75
    /**
76
     * Get the sidebar item's name.
77
     *
78
     * @return string
79
     */
80 8
    public function name()
81
    {
82 8
        return $this->name;
83
    }
84
85
    /**
86
     * Set the title.
87
     *
88
     * @param  string  $title
89
     *
90
     * @return $this
91
     */
92 56
    public function setTitle(string $title)
93
    {
94
        /** @var  \Illuminate\Translation\Translator  $translator */
95 56
        $translator  = trans();
96 56
        $this->title = $translator->has($title)
0 ignored issues
show
Documentation Bug introduced by
It seems like $translator->has($title)...r->get($title) : $title can also be of type array. However, the property $title is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
97 4
            ? $translator->get($title)
98 52
            : $title;
99
100 56
        return $this;
101
    }
102
103
    /**
104
     * Set the url.
105
     *
106
     * @param  string  $url
107
     *
108
     * @return $this
109
     */
110 56
    public function setUrl(string $url)
111
    {
112 56
        $this->url = url($url);
0 ignored issues
show
Documentation Bug introduced by
It seems like url($url) can also be of type object<Illuminate\Contracts\Routing\UrlGenerator>. However, the property $url is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
113
114 56
        return $this;
115
    }
116
117
    /**
118
     * Set the selected item.
119
     *
120
     * @param  string  $name
121
     *
122
     * @return $this
123
     */
124 12
    public function setSelected(string $name)
125
    {
126 12
        $this->selected = ($this->name === $name);
127 12
        $this->children->setSelected($name);
128
129 12
        return $this;
130
    }
131
132
    /**
133
     * Get the roles.
134
     *
135
     * @return array|mixed
136
     */
137 8
    public function roles()
138
    {
139 8
        return $this->roles;
140
    }
141
142
    /**
143
     * Get the permissions.
144
     *
145
     * @return array|mixed
146
     */
147 8
    public function permissions()
148
    {
149 8
        return $this->permissions;
150
    }
151
152
    /* -----------------------------------------------------------------
153
     |  Main Methods
154
     | -----------------------------------------------------------------
155
     */
156
157
    /**
158
     * Make a sidebar item.
159
     *
160
     * @param  array  $attributes
161
     *
162
     * @return \Arcanesoft\Sidebar\Item
163
     */
164 8
    public static function make(array $attributes = [])
165
    {
166 8
        return new static($attributes);
167
    }
168
169
    /**
170
     * Set the url from the route.
171
     *
172
     * @param  string  $name
173
     * @param  array   $params
174
     *
175
     * @return $this
176
     */
177 8
    public function route($name, array $params = [])
178
    {
179 8
        return $this->setUrl(
180 6
            route($name, $params)
181
        );
182
    }
183
184
    /**
185
     * Set the url from the action.
186
     *
187
     * @param  string|array  $name
188
     * @param  array         $params
189
     *
190
     * @return $this
191
     */
192 4
    public function action($name, array $params = [])
193
    {
194 4
        return $this->setUrl(
195 3
            action($name, $params)
196
        );
197
    }
198
199
    /**
200
     * Get the active/inactive class.
201
     *
202
     * @param  string  $active
203
     * @param  string  $inactive
204
     *
205
     * @return string
206
     */
207 4
    public function active($active = 'active', $inactive = '') : string
208
    {
209 4
        return $this->isActive() ? $active : $inactive;
210
    }
211
212
    /**
213
     * Push multiple child items.
214
     *
215
     * @param  array  $items
216
     *
217
     * @return $this
218
     */
219 4
    public function addChildren(array $items)
220
    {
221 4
        $this->children->addItems($items);
222
223 4
        return $this;
224
    }
225
226
    /* -----------------------------------------------------------------
227
     |  Check Methods
228
     | -----------------------------------------------------------------
229
     */
230
231
    /**
232
     * Check if has children.
233
     *
234
     * @return bool
235
     */
236 44
    public function hasChildren() : bool
237
    {
238 44
        return $this->children->isNotEmpty();
239
    }
240
241
    /**
242
     * Check if has any selected children.
243
     *
244
     * @return bool
245
     */
246 40
    public function hasAnySelectedChildren() : bool
247
    {
248 40
        return $this->hasChildren()
249 40
            && $this->children->hasAnySelected();
250
    }
251
252
    /**
253
     * Check if the item is active.
254
     *
255
     * @return bool
256
     */
257 40
    public function isActive() : bool
258
    {
259 40
        return $this->isSelected() || $this->hasAnySelectedChildren();
260
    }
261
262
    /**
263
     * Check if the item is selected.
264
     *
265
     * @return bool
266
     */
267 40
    public function isSelected() : bool
268
    {
269 40
        return $this->selected;
270
    }
271
272
    /* -----------------------------------------------------------------
273
     |  Other Methods
274
     | -----------------------------------------------------------------
275
     */
276
277
    /**
278
     * Parse the url attribute.
279
     *
280
     * @param  array  $attributes
281
     *
282
     * @return void
283
     */
284 56
    protected function parseUrl(array $attributes) : void
285
    {
286 56
        if (isset($attributes['url']))
287 56
            $this->setUrl($attributes['url']);
288
289 56
        if (isset($attributes['route']))
290 8
            $this->route(...Arr::wrap($attributes['route']));
0 ignored issues
show
Documentation introduced by
\Illuminate\Support\Arr:...p($attributes['route']) is of type array, but the function expects a string.

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);
Loading history...
291
292 56
        if (isset($attributes['action']))
293 4
            $this->action(...Arr::wrap($attributes['action']));
294 56
    }
295
296
    /**
297
     * Get the instance as an array.
298
     *
299
     * @return array
300
     */
301 24
    public function toArray()
302
    {
303
        return [
304 24
            'name'        => $this->name,
305 24
            'title'       => $this->title,
306 24
            'url'         => $this->url,
307 24
            'icon'        => $this->icon,
308 24
            'active'      => $this->isActive(),
309 24
            'children'    => $this->children->toArray(),
310 24
            'roles'       => $this->roles,
311 24
            'permissions' => $this->permissions,
312
        ];
313
    }
314
315
    /**
316
     * Convert the object into something JSON serializable.
317
     *
318
     * @return array
319
     */
320 8
    public function jsonSerialize()
321
    {
322 8
        return $this->toArray();
323
    }
324
325
    /**
326
     * Get the collection of items as JSON.
327
     *
328
     * @param  int  $options
329
     *
330
     * @return string
331
     */
332 4
    public function toJson($options = 0)
333
    {
334 4
        return json_encode($this->jsonSerialize(), $options);
335
    }
336
337
    /**
338
     * Check if has roles.
339
     *
340
     * @return bool
341
     */
342 8
    public function hasRoles()
343
    {
344 8
        return ! empty($this->roles);
345
    }
346
347
    /**
348
     * Check if has permissions.
349
     *
350
     * @return bool
351
     */
352 8
    public function hasPermissions()
353
    {
354 8
        return ! empty($this->permissions);
355
    }
356
}
357