Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
44 / 44
100.00% covered (success)
100.00%
7 / 7
CRAP
100.00% covered (success)
100.00%
1 / 1
GeneratesNavigationMenu
100.00% covered (success)
100.00%
44 / 44
100.00% covered (success)
100.00%
7 / 7
21
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getLinks
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
1 / 1
11
 getLinksFromConfig
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
4
 getTitleFromSlug
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getListOfCustomPages
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 getRelativeRoutePathForSlug
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getNavigationLinks
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace Hyde\Framework\Actions;
4
5use Hyde\Framework\Helpers\Features;
6use Hyde\Framework\Hyde;
7use Hyde\Framework\Services\CollectionService;
8use Illuminate\Support\Str;
9
10/**
11 * Generate the dynamic navigation menu.
12 */
13class 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}