GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 5637b4...7162f6 )
by Sebastian
02:22
created

Menu::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace Spatie\Menu;
4
5
use ReflectionFunction;
6
use ReflectionParameter;
7
use Spatie\HtmlElement\Html;
8
use Spatie\Menu\Items\Link;
9
use Spatie\Menu\Traits\HtmlAttributes;
10
use Spatie\Menu\Traits\ParentAttributes;
11
12
class Menu implements Item
13
{
14
    use HtmlAttributes, ParentAttributes;
15
16
    /** @var array */
17
    protected $items = [];
18
19
    /** @var string */
20
    protected $prepend = '';
21
22
    /** @var string */
23
    protected $append = '';
24
25
    /** @var array */
26
    protected $filters = [];
27
28
    /**
29
     * @param \Spatie\Menu\Item[] ...$items
30
     */
31
    protected function __construct(Item ...$items)
32
    {
33
        $this->items = $items;
34
    }
35
36
    /**
37
     * Create a new menu, optionally prefilled with items.
38
     *
39
     * @param array $items
40
     *
41
     * @return static
42
     */
43
    public static function new(array $items = [])
44
    {
45
        return new static(...$items);
46
    }
47
48
    /**
49
     * Add an item to the menu. This also applies all registered filters on the item. If a filter
50
     * returns false, the item won't be added.
51
     *
52
     * @param \Spatie\Menu\Item $item
53
     *
54
     * @return $this
55
     */
56
    public function add(Item $item)
57
    {
58
        if ($this->applyFilters($item) === false) {
59
            return $this;
60
        }
61
62
        $this->items[] = $item;
63
64
        return $this;
65
    }
66
67
    /**
68
     * Applies all the currently registered filters to an item.
69
     *
70
     * @param \Spatie\Menu\Item $item
71
     *
72
     * @return bool
73
     */
74
    protected function applyFilters(Item $item) : bool
75
    {
76
        foreach ($this->filters as $filter) {
77
            if ($this->applyFilter($filter, $item) === false) {
78
                return false;
79
            }
80
        }
81
82
        return true;
83
    }
84
85
    /**
86
     * Apply a filter to an item. Returns the result of the filter.
87
     *
88
     * @param callable $filter
89
     * @param \Spatie\Menu\Item $item
90
     *
91
     * @return mixed
92
     */
93
    protected function applyFilter(callable $filter, Item $item)
94
    {
95
        $type = $this->determineFirstParameterType($filter);
96
97
        if ($type !== null && !$item instanceof $type) {
98
            return;
99
        }
100
101
        return $filter($item);
102
    }
103
104
    /**
105
     * Map through all the items and return an array containing the result. If you typehint the
106
     * item parameter in the callable, it wil only be applied to items of that type.
107
     *
108
     * @param callable $callable
109
     *
110
     * @return array
111
     */
112
    public function map(callable $callable) : array
113
    {
114
        $type = $this->determineFirstParameterType($callable);
115
116
        $items = $this->items;
117
118
        if ($type !== null) {
119
            $items = array_filter($items, function (Item $item) use ($type) {
120
                return $item instanceof $type;
121
            });
122
        }
123
124
        return array_map($callable, $items);
125
    }
126
127
    /**
128
     * Iterate over all the items and apply a callback. If you typehint the
129
     * item parameter in the callable, it wil only be applied to items of that type.
130
     *
131
     * @param callable $callable
132
     *
133
     * @return $this
134
     */
135 View Code Duplication
    public function each(callable $callable)
0 ignored issues
show
Duplication introduced by
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.

Loading history...
136
    {
137
        $type = $this->determineFirstParameterType($callable);
138
139
        foreach ($this->items as $item) {
140
            if ($type !== null && !$item instanceof $type) {
141
                continue;
142
            }
143
144
            $callable($item);
145
        }
146
147
        return $this;
148
    }
149
150
    /**
151
     * Register a filter to the menu. When an item is added, all filters will be applied to the
152
     * item. If a filter returns false, the item won't be added. If you typehint the item
153
     * parameter in the callable, it wil only be applied to items of that type.
154
     *
155
     * @param callable $callable
156
     *
157
     * @return $this
158
     */
159
    public function registerFilter(callable $callable)
160
    {
161
        $this->filters[] = $callable;
162
163
        return $this;
164
    }
165
166
    /**
167
     * Apply a callable to all existing items, and register it as a filter so it will get applied
168
     * to all new items too. If you typehint the item parameter in the callable, it wil only be
169
     * applied to items of that type.
170
     *
171
     * @param callable $callable
172
     *
173
     * @return $this
174
     */
175
    public function applyToAll(callable $callable)
176
    {
177
        $this->each($callable);
178
        $this->registerFilter($callable);
179
180
        return $this;
181
    }
182
183
    /**
184
     * Determine the type of the first parameter of a callable.
185
     *
186
     * @param callable $callable
187
     *
188
     * @return string|null
189
     */
190
    protected function determineFirstParameterType(callable $callable)
191
    {
192
        $reflection = new ReflectionFunction($callable);
193
194
        $parameterTypes = array_map(function (ReflectionParameter $parameter) {
195
            return $parameter->getClass() ? $parameter->getClass()->name : null;
196
        }, $reflection->getParameters());
197
198
        return $parameterTypes[0] ?? null;
199
    }
200
201
    /**
202
     * Prepend a string of html to the menu on render.
203
     *
204
     * @param string $prefix
205
     *
206
     * @return $this
207
     */
208
    public function prefixLinks(string $prefix)
209
    {
210
        return $this->applyToAll(function (Link $link) use ($prefix) {
211
            $link->prefix($prefix);
212
        });
213
    }
214
215
    /**
216
     * Prepend the menu with a string of html on render.
217
     *
218
     * @param string $prepend
219
     *
220
     * @return $this
221
     */
222
    public function prepend(string $prepend)
223
    {
224
        $this->prepend = $prepend;
225
226
        return $this;
227
    }
228
229
    /**
230
     * Append a string of html to the menu on render.
231
     *
232
     * @param string $append
233
     *
234
     * @return $this
235
     */
236
    public function append(string $append)
237
    {
238
        $this->append = $append;
239
240
        return $this;
241
    }
242
243
    /**
244
     * Determine whether the menu is active.
245
     *
246
     * @return bool
247
     */
248
    public function isActive() : bool
249
    {
250
        foreach ($this->items as $item) {
251
            if ($item->isActive()) {
252
                return true;
253
            }
254
        }
255
256
        return false;
257
    }
258
259
    /**
260
     * Set multiple items in the menu as active based on a callable that filters through items.
261
     * If you typehint the item parameter in the callable, it wil only be applied to items of
262
     * that type.
263
     *
264
     * @param callable $callable
265
     *
266
     * @return $this
267
     */
268 View Code Duplication
    public function setActive(callable $callable)
0 ignored issues
show
Duplication introduced by
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.

Loading history...
269
    {
270
        $type = $this->determineFirstParameterType($callable);
271
272
        foreach ($this->items as $item) {
273
            if ($type !== null && !$item instanceof $type) {
274
                continue;
275
            }
276
277
            if ($callable($item)) {
278
                $item->setActive();
279
            }
280
        }
281
282
        return $this;
283
    }
284
285
    /**
286
     * Render the menu in html.
287
     *
288
     * @return string
289
     */
290
    public function render() : string
291
    {
292
        $menu = Html::el(
293
            'ul',
294
            $this->attributes()->toArray(),
295
            $this->map(function (Item $item) {
296
                return Html::el(
297
                    $item->isActive() ? 'li.active' : 'li',
298
                    $item->getParentAttributes(),
299
                    $item->render()
300
                );
301
            })
302
        );
303
304
        return "{$this->prepend}{$menu}{$this->append}";
305
    }
306
307
    public function __toString() : string
308
    {
309
        return $this->render();
310
    }
311
}
312