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