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 | } |