Passed
Push — master ( 4b1ce1...274e82 )
by Caen
03:37 queued 14s
created

HydePageDataFactory::getMatter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Framework\Factories;
6
7
use Hyde\Hyde;
8
use Hyde\Markdown\Models\Markdown;
9
use Hyde\Markdown\Models\FrontMatter;
10
use Hyde\Markdown\Contracts\FrontMatter\PageSchema;
11
use Hyde\Framework\Factories\Concerns\CoreDataObject;
12
use Hyde\Framework\Features\Navigation\NavigationData;
13
14
use function basename;
15
use function dirname;
16
use function str_contains;
17
use function str_ends_with;
18
use function str_starts_with;
19
use function substr;
20
use function trim;
21
22
class HydePageDataFactory extends Concerns\PageDataFactory implements PageSchema
23
{
24
    /**
25
     * The front matter properties supported by this factory.
26
     */
27
    final public const SCHEMA = PageSchema::PAGE_SCHEMA;
28
29
    protected readonly string $title;
30
    protected readonly ?NavigationData $navigation;
31
    private readonly string $routeKey;
32
    private readonly string $outputPath;
33
    private readonly string $identifier;
34
    private readonly string $pageClass;
35
    private readonly Markdown|false $markdown;
36
    private readonly FrontMatter $matter;
37
38
    public function __construct(private readonly CoreDataObject $pageData)
39
    {
40
        $this->matter = $this->pageData->matter;
0 ignored issues
show
Bug introduced by
The property matter is declared read-only in Hyde\Framework\Factories\HydePageDataFactory.
Loading history...
41
        $this->markdown = $this->pageData->markdown;
0 ignored issues
show
Bug introduced by
The property markdown is declared read-only in Hyde\Framework\Factories\HydePageDataFactory.
Loading history...
42
        $this->pageClass = $this->pageData->pageClass;
0 ignored issues
show
Bug introduced by
The property pageClass is declared read-only in Hyde\Framework\Factories\HydePageDataFactory.
Loading history...
43
        $this->identifier = $this->pageData->identifier;
0 ignored issues
show
Bug introduced by
The property identifier is declared read-only in Hyde\Framework\Factories\HydePageDataFactory.
Loading history...
44
        $this->outputPath = $this->pageData->outputPath;
0 ignored issues
show
Bug introduced by
The property outputPath is declared read-only in Hyde\Framework\Factories\HydePageDataFactory.
Loading history...
45
        $this->routeKey = $this->pageData->routeKey;
0 ignored issues
show
Bug introduced by
The property routeKey is declared read-only in Hyde\Framework\Factories\HydePageDataFactory.
Loading history...
46
47
        $this->title = $this->makeTitle();
0 ignored issues
show
Bug introduced by
The property title is declared read-only in Hyde\Framework\Factories\HydePageDataFactory.
Loading history...
48
        $this->navigation = $this->makeNavigation();
0 ignored issues
show
Bug introduced by
The property navigation is declared read-only in Hyde\Framework\Factories\HydePageDataFactory.
Loading history...
49
    }
50
51
    /**
52
     * @return array{title: string, navigation: \Hyde\Framework\Features\Navigation\NavigationData|null}
53
     */
54
    public function toArray(): array
55
    {
56
        return [
0 ignored issues
show
introduced by
The expression return array('title' => ...' => $this->navigation) returns an array which contains values of type Hyde\Framework\Features\...n\NavigationData|string which are incompatible with the return type Illuminate\Contracts\Support\TValue mandated by Illuminate\Contracts\Support\Arrayable::toArray().
Loading history...
57
            'title' => $this->title,
58
            'navigation' => $this->navigation,
59
        ];
60
    }
61
62
    protected function makeTitle(): string
63
    {
64
        return trim($this->findTitleForPage());
65
    }
66
67
    protected function makeNavigation(): NavigationData
68
    {
69
        return NavigationData::make((new NavigationDataFactory($this->pageData, $this->title))->toArray());
70
    }
71
72
    private function findTitleForPage(): string
73
    {
74
        return $this->getMatter('title')
75
            ?? $this->findTitleFromMarkdownHeadings()
76
            ?? $this->findTitleFromParentIdentifier()
77
            ?? Hyde::makeTitle(basename($this->identifier));
78
    }
79
80
    private function findTitleFromMarkdownHeadings(): ?string
81
    {
82
        if ($this->markdown !== false) {
83
            foreach ($this->markdown->toArray() as $line) {
84
                if (str_starts_with($line, '# ')) {
85
                    return trim(substr($line, 2), ' ');
86
                }
87
            }
88
        }
89
90
        return null;
91
    }
92
93
    private function findTitleFromParentIdentifier(): ?string
94
    {
95
        if (str_contains($this->identifier, '/') && str_ends_with($this->identifier, '/index')) {
96
            return Hyde::makeTitle(basename(dirname($this->identifier)));
97
        }
98
99
        return null;
100
    }
101
102
    protected function getMatter(string $key): string|null
103
    {
104
        return $this->matter->get($key);
105
    }
106
}
107