Passed
Push — master ( ad6b2a...b41ca0 )
by Caen
07:45 queued 14s
created

DocumentationSidebar::getActiveGroup()   B

Complexity

Conditions 8
Paths 3

Size

Total Lines 20
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 8
nc 3
nop 0
dl 0
loc 20
rs 8.4444
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Framework\Features\Navigation;
6
7
use Hyde\Facades\Config;
8
use Hyde\Pages\DocumentationPage;
9
use Hyde\Support\Facades\Render;
10
use Illuminate\Contracts\Support\Arrayable;
11
12
use function app;
13
use function is_string;
14
15
class DocumentationSidebar extends NavigationMenu
16
{
17
    /**
18
     * Get the navigation menu instance from the service container.
19
     */
20
    public static function get(): static
21
    {
22
        return app('navigation.sidebar');
23
    }
24
25
    public function __construct(Arrayable|array $items = [])
26
    {
27
        parent::__construct($items);
28
    }
29
30
    public function getHeader(): string
31
    {
32
        return Config::getString('docs.sidebar.header', 'Documentation');
33
    }
34
35
    public function getFooter(): ?string
36
    {
37
        /** @var null|string|false $option */
38
        $option = Config::get('docs.sidebar.footer', '[Back to home page](../)');
39
40
        if (is_string($option)) {
41
            return $option;
42
        }
43
44
        return null;
45
    }
46
47
    public function hasFooter(): bool
48
    {
49
        return $this->getFooter() !== null;
50
    }
51
52
    public function isCollapsible(): bool
53
    {
54
        return Config::getBool('docs.sidebar.collapsible', true);
55
    }
56
57
    public function hasGroups(): bool
58
    {
59
        return $this->getItems()->contains(fn (NavigationItem|NavigationGroup $item): bool => $item instanceof NavigationGroup);
60
    }
61
62
    /**
63
     * Get the group that should be open when the sidebar is loaded.
64
     *
65
     * @internal This method offloads logic for the sidebar view, and is not intended to be used in other contexts.
66
     */
67
    public function getActiveGroup(): ?NavigationGroup
68
    {
69
        if ($this->items->isEmpty() || (! $this->hasGroups()) || (! $this->isCollapsible()) || Render::getPage() === null) {
70
            return null;
71
        }
72
73
        $currentPage = Render::getPage();
74
75
        if ($currentPage->getRoute()->is(DocumentationPage::homeRouteName()) && blank($currentPage->navigationMenuGroup())) {
76
            // Unless the index page has a specific group set, the first group in the sidebar should be open when visiting the index page.
77
            return $this->items->sortBy(fn (NavigationGroup $item): int => $item->getPriority())->first();
78
        }
79
80
        /** @var ?NavigationGroup $first */
81
        $first = $this->items->first(function (NavigationGroup $group) use ($currentPage): bool {
82
            // A group is active when it contains the current page being rendered.
83
            return $currentPage->navigationMenuGroup() && $group->getGroupKey() === NavigationGroup::normalizeGroupKey($currentPage->navigationMenuGroup());
84
        });
85
86
        return $first;
87
    }
88
}
89