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 ( cf3086...93d6fd )
by Sebastian
01:54
created

Menu::fill()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 13
rs 9.4285
cc 3
eloc 7
nc 3
nop 1
1
<?php
2
3
namespace Spatie\Menu;
4
5
use Spatie\HtmlElement\HtmlElement;
6
use Spatie\Menu\Traits\HtmlAttributes;
7
use Spatie\Menu\Traits\ParentAttributes;
8
9
class Menu implements Item
10
{
11
    use HtmlAttributes, ParentAttributes;
12
13
    /** @var array */
14
    protected $items = [];
15
16
    /** @var string */
17
    protected $prepend = '';
18
19
    /** @var string */
20
    protected $append = '';
21
22
    /** @var array */
23
    protected $filters = [];
24
25
    /**
26
     * @param \Spatie\Menu\Item[] ...$items
27
     */
28
    protected function __construct(Item ...$items)
29
    {
30
        $this->items = $items;
31
32
        $this->bootHtmlAttributes();
33
        $this->bootParentAttributes();
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(...array_values($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
        foreach ($this->filters as $filter) {
59
            $this->applyFilter($filter, $item);
60
        }
61
62
        $this->items[] = $item;
63
64
        return $this;
65
    }
66
67
    /**
68
     * Shortcut function to add a plain link to the menu.
69
     *
70
     * @param string $url
71
     * @param string $text
72
     *
73
     * @return \Spatie\Menu\Menu
74
     */
75
    public function link(string $url, string $text)
76
    {
77
        return $this->add(Link::to($url, $text));
78
    }
79
80
    /**
81
     * Apply a filter to an item. Returns the result of the filter.
82
     *
83
     * @param callable $filter
84
     * @param \Spatie\Menu\Item $item
85
     */
86
    protected function applyFilter(callable $filter, Item $item)
87
    {
88
        $type = first_parameter_type($filter);
89
90
        if (!item_matches_type($item, $type)) {
91
            return;
92
        }
93
94
        $filter($item);
95
    }
96
97
    /**
98
     * Iterate over all the items and apply a callback. If you typehint the
99
     * item parameter in the callable, it wil only be applied to items of that type.
100
     *
101
     * @param callable $callable
102
     *
103
     * @return $this
104
     */
105
    public function each(callable $callable)
106
    {
107
        $type = first_parameter_type($callable);
108
109
        foreach ($this->items as $item) {
110
            if (!item_matches_type($item, $type)) {
111
                continue;
112
            }
113
114
            $callable($item);
115
        }
116
117
        return $this;
118
    }
119
120
    /**
121
     * Register a filter to the menu. When an item is added, all filters will be applied to the
122
     * item. If you typehint the item
123
     * parameter in the callable, it wil only be applied to items of that type.
124
     *
125
     * @param callable $callable
126
     *
127
     * @return $this
128
     */
129
    public function registerFilter(callable $callable)
130
    {
131
        $this->filters[] = $callable;
132
133
        return $this;
134
    }
135
136
    /**
137
     * Apply a callable to all existing items, and register it as a filter so it will get applied
138
     * to all new items too. If you typehint the item parameter in the callable, it wil only be
139
     * applied to items of that type.
140
     *
141
     * @param callable $callable
142
     *
143
     * @return $this
144
     */
145
    public function applyToAll(callable $callable)
146
    {
147
        $this->each($callable);
148
        $this->registerFilter($callable);
149
150
        return $this;
151
    }
152
153
    /**
154
     * Prepend a string of html to the menu on render.
155
     *
156
     * @param string $prefix
157
     *
158
     * @return $this
159
     */
160
    public function prefixLinks(string $prefix)
161
    {
162
        return $this->applyToAll(function (Link $link) use ($prefix) {
163
            $link->prefix($prefix);
164
        });
165
    }
166
167
    /**
168
     * Prepend the menu with a string of html on render.
169
     *
170
     * @param string $prepend
171
     *
172
     * @return $this
173
     */
174
    public function prepend(string $prepend)
175
    {
176
        $this->prepend = $prepend;
177
178
        return $this;
179
    }
180
181
    /**
182
     * Prepend the menu with a string of html on render if a certain condition is met.
183
     *
184
     * @param bool $condition
185
     * @param string $prepend
186
     *
187
     * @return $this
188
     */
189
    public function prependIf(bool $condition, string $prepend)
190
    {
191
        if ($condition) {
192
            return $this->prepend($prepend);
193
        }
194
195
        return $this;
196
    }
197
198
    /**
199
     * Append a string of html to the menu on render.
200
     *
201
     * @param string $append
202
     *
203
     * @return $this
204
     */
205
    public function append(string $append)
206
    {
207
        $this->append = $append;
208
209
        return $this;
210
    }
211
212
    /**
213
     * Append the menu with a string of html on render if a certain condition is met.
214
     *
215
     * @param bool $condition
216
     * @param string $append
217
     *
218
     * @return static
219
     */
220
    public function appendIf(bool $condition, string $append)
221
    {
222
        if ($condition) {
223
            return $this->append($append);
224
        }
225
226
        return $this;
227
    }
228
229
    /**
230
     * Determine whether the menu is active.
231
     *
232
     * @return bool
233
     */
234
    public function isActive() : bool
235
    {
236
        foreach ($this->items as $item) {
237
            if ($item->isActive()) {
238
                return true;
239
            }
240
        }
241
242
        return false;
243
    }
244
245
    /**
246
     * Set multiple items in the menu as active based on a callable that filters through items.
247
     * If you typehint the item parameter in the callable, it wil only be applied to items of
248
     * that type.
249
     *
250
     * @param callable|string $patternOrCallable
251
     * @param string $root
252
     *
253
     * @return $this
254
     */
255
    public function setActive($patternOrCallable, string $root = '/')
256
    {
257
        if (is_string($patternOrCallable)) {
258
            return $this->setActiveFromUrl($patternOrCallable, $root);
259
        }
260
261
        if (is_callable($patternOrCallable)) {
262
            return $this->setActiveFromCallable($patternOrCallable);
263
        }
264
265
        throw new \InvalidArgumentException('`setActive` requires a pattern or a callable');
266
    }
267
268
    /**
269
     * @param string $url
270
     * @param string $root
271
     *
272
     * @return $this
273
     */
274
    public function setActiveFromUrl(string $url, string $root = '/')
275
    {
276
        $requestUrl = url_parts($url);
277
        $requestRoot = strip_trailing_slashes($root, '/');
278
279
        $this->applyToAll(function (Link $link) use ($requestUrl, $requestRoot) {
280
281
            $url = url_parts($link->getUrl());
282
283
            // If the menu item is on a different host it can't be active.
284
            if ($url['host'] !== '' && $url['host'] !== $requestUrl['host']) {
285
                return;
286
            }
287
288
            // If the request url or the link url is on the root, only set exact matches active.
289
            if (
290
                $requestUrl['path'] === $requestRoot ||
291
                $url['path'] === $requestRoot
292
            ) {
293
                if ($url['path'] === $requestUrl['path']) {
294
                    $link->setActive();
295
                }
296
297
                return;
298
            }
299
300
            // The menu item is active if it's path starts with the request path.
301
            if (strpos($url['path'], $requestUrl['path']) === 0) {
302
                $link->setActive();
303
            };
304
        });
305
306
        return $this;
307
    }
308
309
    /**
310
     * @param callable $callable
311
     *
312
     * @return $this
313
     */
314
    public function setActiveFromCallable(callable $callable)
315
    {
316
        $type = first_parameter_type($callable);
317
318
        return $this->applyToAll(function (Item $item) use ($callable, $type) {
319
            if (!item_matches_type($item, $type)) {
320
                return;
321
            }
322
323
            if ($callable($item)) {
324
                $item->setActive();
325
            }
326
        });
327
    }
328
329
    /**
330
     * @return string
331
     */
332
    public function render() : string
333
    {
334
        $contents = HtmlElement::render(
335
            'ul',
336
            $this->htmlAttributes->toArray(),
337
            array_map(function (Item $item) {
338
                return HtmlElement::render(
339
                    $item->isActive() ? 'li.active' : 'li',
340
                    $item->getParentAttributes(),
341
                    $item->render()
342
                );
343
            }, $this->items)
344
        );
345
346
        return "{$this->prepend}{$contents}{$this->append}";
347
    }
348
349
    /**
350
     * @return string
351
     */
352
    public function __toString() : string
353
    {
354
        return $this->render();
355
    }
356
}
357