Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
44 / 44 |
|
100.00% |
7 / 7 |
CRAP | |
100.00% |
1 / 1 |
GeneratesNavigationMenu | |
100.00% |
44 / 44 |
|
100.00% |
7 / 7 |
21 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getLinks | |
100.00% |
22 / 22 |
|
100.00% |
1 / 1 |
11 | |||
getLinksFromConfig | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
4 | |||
getTitleFromSlug | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
getListOfCustomPages | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
getRelativeRoutePathForSlug | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getNavigationLinks | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | namespace Hyde\Framework\Actions; |
4 | |
5 | use Hyde\Framework\Helpers\Features; |
6 | use Hyde\Framework\Hyde; |
7 | use Hyde\Framework\Services\CollectionService; |
8 | use Illuminate\Support\Str; |
9 | |
10 | /** |
11 | * Generate the dynamic navigation menu. |
12 | */ |
13 | class GeneratesNavigationMenu |
14 | { |
15 | /** |
16 | * The current page route string. |
17 | * |
18 | * Used to check if a given link is active, |
19 | * and more importantly it is needed to |
20 | * assemble the relative link paths. |
21 | * |
22 | * @example 'posts/my-new-post.html' |
23 | * @example 'index.html' |
24 | * |
25 | * @var string |
26 | */ |
27 | public string $currentPage; |
28 | |
29 | /** |
30 | * The created array of navigation links. |
31 | * |
32 | * @var array |
33 | */ |
34 | public array $links; |
35 | |
36 | /** |
37 | * Construct the class. |
38 | * |
39 | * @param string $currentPage |
40 | */ |
41 | public function __construct(string $currentPage) |
42 | { |
43 | $this->currentPage = $currentPage; |
44 | |
45 | $this->links = $this->getLinks(); |
46 | } |
47 | |
48 | /** |
49 | * Create the link array. |
50 | * |
51 | * @return array |
52 | */ |
53 | private function getLinks(): array |
54 | { |
55 | $links = $this->getLinksFromConfig(); |
56 | |
57 | // Automatically add top level pages |
58 | foreach ($this->getListOfCustomPages() as $slug) { |
59 | $title = $this->getTitleFromSlug($slug); |
60 | // Only add the automatic link if it is not present in the config array |
61 | if (! in_array($title, array_column($links, 'title'))) { |
62 | $links[] = [ |
63 | 'title' => $title, |
64 | 'route' => $this->getRelativeRoutePathForSlug($slug), |
65 | 'current' => $this->currentPage == $slug, |
66 | 'priority' => $slug == 'index' ? 100 : 999, |
67 | ]; |
68 | } |
69 | } |
70 | |
71 | // Add extra links |
72 | |
73 | // If the documentation feature is enabled... |
74 | if (Features::hasDocumentationPages()) { |
75 | // And there is no link to the docs... |
76 | if (! in_array('Docs', array_column($links, 'title'))) { |
77 | // But a suitable file exists... |
78 | if (file_exists(Hyde::getDocumentationPagePath('/index.md')) || file_exists(Hyde::getDocumentationPagePath('/readme.md'))) { |
79 | // Then we can add a link. |
80 | $links[] = [ |
81 | 'title' => 'Docs', |
82 | 'route' => $this->getRelativeRoutePathForSlug( |
83 | file_exists(Hyde::getDocumentationPagePath('/index.md')) |
84 | ? Hyde::docsDirectory().'/index' |
85 | : Hyde::docsDirectory().'/readme' |
86 | ), |
87 | 'current' => false, |
88 | 'priority' => 500, |
89 | ]; |
90 | } |
91 | } |
92 | } |
93 | |
94 | // Remove config defined blacklisted links |
95 | foreach ($links as $key => $link) { |
96 | if (in_array(Str::slug($link['title']), config('hyde.navigation_menu_blacklist', []))) { |
97 | unset($links[$key]); |
98 | } |
99 | } |
100 | |
101 | // Sort |
102 | |
103 | $columns = array_column($links, 'priority'); |
104 | array_multisort($columns, SORT_ASC, $links); |
105 | |
106 | return $links; |
107 | } |
108 | |
109 | /** |
110 | * Get the custom navigation links from the config, if there are any. |
111 | * |
112 | * @return array |
113 | */ |
114 | public function getLinksFromConfig(): array |
115 | { |
116 | $configLinks = config('hyde.navigation_menu_links', []); |
117 | |
118 | $links = []; |
119 | |
120 | if (sizeof($configLinks) > 0) { |
121 | foreach ($configLinks as $link) { |
122 | $links[] = [ |
123 | 'title' => $link['title'], |
124 | 'route' => $link['destination'] ?? $this->getRelativeRoutePathForSlug($link['slug']), |
125 | 'current' => isset($link['slug']) && $this->currentPage == $link['slug'], |
126 | 'priority' => $link['priority'] ?? 999, |
127 | ]; |
128 | } |
129 | } |
130 | |
131 | return $links; |
132 | } |
133 | |
134 | /** |
135 | * Get the page title. |
136 | * |
137 | * @param string $slug |
138 | * @return string |
139 | */ |
140 | public function getTitleFromSlug(string $slug): string |
141 | { |
142 | if ($slug == 'index') { |
143 | return 'Home'; |
144 | } |
145 | |
146 | return Hyde::titleFromSlug($slug); |
147 | } |
148 | |
149 | /** |
150 | * Get a list of all the top level pages. |
151 | * |
152 | * @return array |
153 | */ |
154 | private function getListOfCustomPages(): array |
155 | { |
156 | return array_unique( |
157 | array_merge( |
158 | CollectionService::getBladePageList(), |
159 | CollectionService::getMarkdownPageList() |
160 | ) |
161 | ); |
162 | } |
163 | |
164 | /** |
165 | * Inject the proper number of `../` before the links. |
166 | * |
167 | * @param string $slug |
168 | * @return string |
169 | */ |
170 | private function getRelativeRoutePathForSlug(string $slug): string |
171 | { |
172 | return Hyde::relativeLink($slug.'.html', $this->currentPage); |
173 | } |
174 | |
175 | /** |
176 | * Static helper to get the array of navigation links. |
177 | * |
178 | * @param string $currentPage |
179 | * @return array |
180 | */ |
181 | public static function getNavigationLinks(string $currentPage = 'index'): array |
182 | { |
183 | $generator = new self($currentPage); |
184 | |
185 | return $generator->links; |
186 | } |
187 | } |