Passed
Push — master ( ad6b2a...b41ca0 )
by Caen
07:45 queued 14s
created

NavigationItem   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 109
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 19
dl 0
loc 109
rs 10
c 0
b 0
f 0
wmc 14

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getPage() 0 3 2
A getExtraAttributes() 0 3 1
A getLink() 0 3 1
A __construct() 0 3 1
A getPriority() 0 3 1
A create() 0 3 1
A make() 0 14 4
A isActive() 0 3 1
A getLabel() 0 3 1
A __toString() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Framework\Features\Navigation;
6
7
use Hyde\Pages\Concerns\HydePage;
8
use Hyde\Foundation\Facades\Routes;
9
use Hyde\Hyde;
10
use Hyde\Support\Models\Route;
11
use Stringable;
12
13
use function is_string;
14
15
/**
16
 * Abstraction for a navigation menu item containing useful information like the destination, label, and priority.
17
 *
18
 * It is used by the MainNavigationMenu and DocumentationSidebar classes.
19
 */
20
class NavigationItem implements Stringable
21
{
22
    protected string|Route $destination;
23
    protected string $label;
24
    protected int $priority;
25
26
    /** @var array<string, scalar> */
27
    protected array $attributes = [];
28
29
    /**
30
     * Create a new navigation menu item, automatically filling in the properties from a Route instance if provided.
31
     *
32
     * @param  \Hyde\Support\Models\Route|string<\Hyde\Support\Models\RouteKey>|string  $destination  Route instance or route key, or an external URI.
33
     * @param  string|null  $label  If not provided, Hyde will try to get it from the route's connected page, or from the URL.
34
     * @param  int|null  $priority  If not provided, Hyde will try to get it from the route or the default priority of 500.
35
     * @param  array<string, scalar>  $attributes  Additional attributes for the navigation item.
36
     */
37
    public function __construct(Route|string $destination, ?string $label = null, ?int $priority = null, array $attributes = [])
38
    {
39
        [$this->destination, $this->label, $this->priority, $this->attributes] = self::make($destination, $label, $priority, $attributes);
40
    }
41
42
    /**
43
     * Create a new navigation menu item, automatically filling in the properties from a Route instance if provided.
44
     *
45
     * @param  \Hyde\Support\Models\Route|string<\Hyde\Support\Models\RouteKey>|string  $destination  Route instance or route key, or an external URI.
46
     * @param  string|null  $label  If not provided, Hyde will try to get it from the route's connected page, or from the URL.
47
     * @param  int|null  $priority  If not provided, Hyde will try to get it from the route or the default priority of 500.
48
     * @param  array<string, scalar>  $attributes  Additional attributes for the navigation item.
49
     */
50
    public static function create(Route|string $destination, ?string $label = null, ?int $priority = null, array $attributes = []): static
51
    {
52
        return new static(...self::make($destination, $label, $priority, $attributes));
53
    }
54
55
    /**
56
     * Resolve a link to the navigation item. See `getLink()` for more information.
57
     */
58
    public function __toString(): string
59
    {
60
        return $this->getLink();
61
    }
62
63
    /**
64
     * Resolve the destination link of the navigation item.
65
     *
66
     * This can then be used in the `href` attribute of an anchor tag.
67
     *
68
     * If the destination is a Route, it will be resolved using the Route's link.
69
     * Otherwise, it will be returned as is for external links using URLs.
70
     */
71
    public function getLink(): string
72
    {
73
        return (string) $this->destination;
74
    }
75
76
    /**
77
     * Get the label of the navigation item.
78
     */
79
    public function getLabel(): string
80
    {
81
        return $this->label;
82
    }
83
84
    /**
85
     * Get the priority to determine the order of the navigation item.
86
     */
87
    public function getPriority(): int
88
    {
89
        return $this->priority;
90
    }
91
92
    /**
93
     * If the navigation item is a link to a routed page, get the corresponding page instance.
94
     */
95
    public function getPage(): ?HydePage
96
    {
97
        return $this->destination instanceof Route ? $this->destination->getPage() : null;
98
    }
99
100
    /**
101
     * Check if the NavigationItem instance is the current page being rendered.
102
     */
103
    public function isActive(): bool
104
    {
105
        return Hyde::currentRoute()?->getLink() === $this->getLink();
0 ignored issues
show
Bug introduced by
The method currentRoute() does not exist on Hyde\Hyde. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

105
        return Hyde::/** @scrutinizer ignore-call */ currentRoute()?->getLink() === $this->getLink();
Loading history...
106
    }
107
108
    /** @return array{\Hyde\Support\Models\Route|string, string, int, array<string, scalar>} */
0 ignored issues
show
Documentation Bug introduced by
The doc comment array{\Hyde\Support\Mode... array<string, scalar>} at position 2 could not be parsed: Expected ':' at position 2, but found '\Hyde\Support\Models\Route'.
Loading history...
109
    protected static function make(Route|string $destination, ?string $label = null, ?int $priority = null, array $attributes = []): array
110
    {
111
        // Automatically resolve the destination if it's a route key.
112
        if (is_string($destination) && Routes::has($destination)) {
0 ignored issues
show
Bug introduced by
The method has() does not exist on Hyde\Foundation\Facades\Routes. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

112
        if (is_string($destination) && Routes::/** @scrutinizer ignore-call */ has($destination)) {
Loading history...
113
            $destination = Routes::get($destination);
114
        }
115
116
        if ($destination instanceof Route) {
117
            // Try to fill in missing properties from the route's connected page.
118
            $label ??= $destination->getPage()->navigationMenuLabel();
119
            $priority ??= $destination->getPage()->navigationMenuPriority();
120
        }
121
122
        return [$destination, $label ?? $destination, $priority ?? NavigationMenu::DEFAULT, $attributes];
123
    }
124
125
    /** @return array<string, scalar> */
126
    public function getExtraAttributes(): array
127
    {
128
        return $this->attributes;
129
    }
130
}
131