Passed
Push — master ( a77e6b...67a175 )
by Caen
13:07 queued 12s
created

NavItem   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 113
Duplicated Lines 0 %

Importance

Changes 59
Bugs 1 Features 0
Metric Value
eloc 24
c 59
b 1
f 0
dl 0
loc 113
rs 10
wmc 14

12 Methods

Rating   Name   Duplication   Size   Complexity  
A getDestination() 0 3 1
A isCurrent() 0 3 1
A fromRoute() 0 7 1
A getGroup() 0 3 1
A getPriority() 0 3 1
A __construct() 0 6 1
A forLink() 0 3 1
A getRouteGroup() 0 3 1
A normalizeGroupKey() 0 3 2
A __toString() 0 3 1
A getLabel() 0 3 1
A forRoute() 0 3 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Framework\Features\Navigation;
6
7
use Hyde\Hyde;
8
use Hyde\Support\Models\Route;
9
use Illuminate\Support\Str;
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;
0 ignored issues
show
Bug introduced by
The property destination is declared read-only in Hyde\Framework\Features\Navigation\NavItem.
Loading history...
33
        $this->label = $label;
0 ignored issues
show
Bug introduced by
The property label is declared read-only in Hyde\Framework\Features\Navigation\NavItem.
Loading history...
34
        $this->priority = $priority;
0 ignored issues
show
Bug introduced by
The property priority is declared read-only in Hyde\Framework\Features\Navigation\NavItem.
Loading history...
35
        $this->group = $group;
0 ignored issues
show
Bug introduced by
The property group is declared read-only in Hyde\Framework\Features\Navigation\NavItem.
Loading history...
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 : \Hyde\Facades\Route::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
        return static::normalizeGroupKey(($route)->getPage()->data('navigation.group'));
128
    }
129
130
    protected static function normalizeGroupKey(?string $group): ?string
131
    {
132
        return $group ? Str::slug($group) : null;
133
    }
134
}
135