Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
21 / 21 |
|
100.00% |
12 / 12 |
CRAP | |
100.00% |
1 / 1 |
NavItem | |
100.00% |
21 / 21 |
|
100.00% |
12 / 12 |
14 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
fromRoute | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
forLink | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
forRoute | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
__toString | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getDestination | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getLabel | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getPriority | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getGroup | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
isCurrent | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getRouteGroup | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
normalizeGroupKey | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | namespace Hyde\Framework\Features\Navigation; |
6 | |
7 | use Hyde\Foundation\Facades\Routes; |
8 | use Hyde\Hyde; |
9 | use Hyde\Support\Models\Route; |
10 | use Illuminate\Support\Str; |
11 | use Stringable; |
12 | |
13 | /** |
14 | * Abstraction for a navigation menu item. Used by the NavigationMenu and DocumentationSidebar classes. |
15 | * |
16 | * You have a few options to construct a navigation menu item: |
17 | * 1. You can supply a Route directly and explicit properties to the constructor |
18 | * 2. You can use NavItem::fromRoute() to use data from the route |
19 | * 3. You can use NavItem::forLink() for an external or un-routed link |
20 | */ |
21 | class NavItem implements Stringable |
22 | { |
23 | public readonly string $destination; |
24 | public readonly string $label; |
25 | public readonly int $priority; |
26 | public readonly ?string $group; |
27 | |
28 | /** |
29 | * Create a new navigation menu item. |
30 | */ |
31 | public function __construct(Route|string $destination, string $label, int $priority = 500, ?string $group = null) |
32 | { |
33 | $this->destination = (string) $destination; |
34 | $this->label = $label; |
35 | $this->priority = $priority; |
36 | $this->group = $group; |
37 | } |
38 | |
39 | /** |
40 | * Create a new navigation menu item from a route. |
41 | */ |
42 | public static function fromRoute(Route $route, ?string $label = null, ?int $priority = null, ?string $group = null): static |
43 | { |
44 | return new static( |
45 | $route->getLink(), |
46 | $label ?? $route->getPage()->navigationMenuLabel(), |
47 | $priority ?? $route->getPage()->navigationMenuPriority(), |
48 | $group ?? static::getRouteGroup($route), |
49 | ); |
50 | } |
51 | |
52 | /** |
53 | * Create a new navigation menu item leading to an external URI. |
54 | */ |
55 | public static function forLink(string $href, string $label, int $priority = 500): static |
56 | { |
57 | return new static($href, $label, $priority); |
58 | } |
59 | |
60 | /** |
61 | * Create a new navigation menu item leading to a Route model. |
62 | * |
63 | * @param \Hyde\Support\Models\Route|string<\Hyde\Support\Models\RouteKey> $route Route model or route key |
64 | * @param int|null $priority Leave blank to use the priority of the route's corresponding page. |
65 | * @param string|null $label Leave blank to use the label of the route's corresponding page. |
66 | * @param string|null $group Leave blank to use the group of the route's corresponding page. |
67 | */ |
68 | public static function forRoute(Route|string $route, ?string $label = null, ?int $priority = null, ?string $group = null): static |
69 | { |
70 | return static::fromRoute($route instanceof Route ? $route : Routes::getOrFail($route), $label, $priority, $group); |
71 | } |
72 | |
73 | /** |
74 | * Resolve a link to the navigation item. |
75 | */ |
76 | public function __toString(): string |
77 | { |
78 | return $this->destination; |
79 | } |
80 | |
81 | /** |
82 | * Get the destination link of the navigation item. |
83 | * |
84 | * If the navigation item is an external link, this will return the link as is, |
85 | * if it's for a route, a resolved relative link will be returned. |
86 | */ |
87 | public function getDestination(): string |
88 | { |
89 | return $this->destination; |
90 | } |
91 | |
92 | /** |
93 | * Get the label of the navigation item. |
94 | */ |
95 | public function getLabel(): string |
96 | { |
97 | return $this->label; |
98 | } |
99 | |
100 | /** |
101 | * Get the priority to determine the order of the navigation item. |
102 | */ |
103 | public function getPriority(): int |
104 | { |
105 | return $this->priority; |
106 | } |
107 | |
108 | /** |
109 | * Get the group identifier of the navigation item, if any. |
110 | * |
111 | * For sidebars this is the category key, for navigation menus this is the dropdown key. |
112 | */ |
113 | public function getGroup(): ?string |
114 | { |
115 | return $this->group; |
116 | } |
117 | |
118 | /** |
119 | * Check if the NavItem instance is the current page. |
120 | */ |
121 | public function isCurrent(): bool |
122 | { |
123 | return Hyde::currentRoute()->getLink() === $this->destination; |
124 | } |
125 | |
126 | protected static function getRouteGroup(Route $route): ?string |
127 | { |
128 | /** @var string|null $group */ |
129 | $group = $route->getPage()->data('navigation.group'); |
130 | |
131 | return static::normalizeGroupKey($group); |
132 | } |
133 | |
134 | protected static function normalizeGroupKey(?string $group): ?string |
135 | { |
136 | return $group ? Str::slug($group) : null; |
137 | } |
138 | } |