Passed
Branch decouple-schema-constructors (79d259)
by Caen
02:51
created

AbstractPage::constructPageSchemas()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Hyde\Framework\Concerns;
4
5
use Hyde\Framework\Actions\SourceFileParser;
6
use Hyde\Framework\Concerns\FrontMatter\Schemas\Constructors\ConstructsPageSchemas;
7
use Hyde\Framework\Concerns\FrontMatter\Schemas\PageSchema;
8
use Hyde\Framework\Contracts\CompilableContract;
9
use Hyde\Framework\Contracts\PageContract;
10
use Hyde\Framework\Foundation\PageCollection;
11
use Hyde\Framework\Hyde;
12
use Hyde\Framework\Models\FrontMatter;
13
use Hyde\Framework\Models\Metadata\Metadata;
14
use Hyde\Framework\Models\Route;
15
use Hyde\Framework\Services\DiscoveryService;
16
17
/**
18
 * To ensure compatibility with the Hyde Framework, all Page Models should extend this class.
19
 * Markdown-based Pages can extend the AbstractMarkdownPage class to get relevant helpers.
20
 * To learn about what the methods do, see the PHPDocs in the PageContract.
21
 *
22
 * Unlike other frameworks, in general you don't instantiate pages yourself in Hyde,
23
 * instead, the page models acts as blueprints defining information for Hyde to
24
 * know how to parse a file, and what data around it should be generated.
25
 *
26
 * To create a parsed file instance, you'd typically just create a source file,
27
 * and you can then access the parsed file from the HydeKernel's page index.
28
 *
29
 * @see \Hyde\Framework\Contracts\PageContract
30
 * @see \Hyde\Framework\Concerns\AbstractMarkdownPage
31
 * @see \Hyde\Framework\Testing\Feature\AbstractPageTest
32
 */
33
abstract class AbstractPage implements PageContract, CompilableContract
34
{
35
    use PageSchema;
36
    use ConstructsPageSchemas;
0 ignored issues
show
Bug introduced by
The trait Hyde\Framework\Concerns\...s\ConstructsPageSchemas requires the property $markdown which is not provided by Hyde\Framework\Concerns\AbstractPage.
Loading history...
37
38
    public static string $sourceDirectory;
39
    public static string $outputDirectory;
40
    public static string $fileExtension;
41
    public static string $template;
42
43
    public string $identifier;
44
    public string $routeKey;
45
46
    public FrontMatter $matter;
47
    public Metadata $metadata;
48
49
    public function __construct(string $identifier = '', FrontMatter|array $matter = [])
50
    {
51
        $this->identifier = $identifier;
52
        $this->routeKey = $this->getCurrentPagePath();
53
54
        $this->matter = $matter instanceof FrontMatter ? $matter : new FrontMatter($matter);
0 ignored issues
show
introduced by
$matter is never a sub-type of Hyde\Framework\Models\FrontMatter.
Loading history...
55
        $this->constructPageSchemas();
56
        $this->metadata = new Metadata($this);
57
    }
58
59
    /** @inheritDoc */
60
    final public static function getSourceDirectory(): string
61
    {
62
        return unslash(static::$sourceDirectory);
63
    }
64
65
    /** @inheritDoc */
66
    final public static function getOutputDirectory(): string
67
    {
68
        return unslash(static::$outputDirectory);
69
    }
70
71
    /** @inheritDoc */
72
    final public static function getFileExtension(): string
73
    {
74
        return '.'.ltrim(static::$fileExtension, '.');
75
    }
76
77
    /** @inheritDoc */
78
    public static function parse(string $slug): PageContract
79
    {
80
        return (new SourceFileParser(static::class, $slug))->get();
81
    }
82
83
    /** @inheritDoc */
84
    public static function files(): array|false
85
    {
86
        return DiscoveryService::getSourceFileListForModel(static::class);
87
    }
88
89
    /** @inheritDoc */
90
    public static function all(): PageCollection
91
    {
92
        return Hyde::pages()->getPages(static::class);
93
    }
94
95
    /** @inheritDoc */
96
    public static function qualifyBasename(string $basename): string
97
    {
98
        return static::getSourceDirectory().'/'.unslash($basename).static::getFileExtension();
99
    }
100
101
    /** @inheritDoc */
102
    public static function getOutputLocation(string $basename): string
103
    {
104
        // Using the trim function we ensure we don't have a leading slash when the output directory is the root directory.
105
        return trim(
106
            static::getOutputDirectory().'/'.unslash($basename),
107
            '/'
108
        ).'.html';
109
    }
110
111
    /** @inheritDoc */
112
    public function get(string $key = null, mixed $default = null): mixed
113
    {
114
        if ($key !== null && property_exists($this, $key) && isset($this->$key)) {
115
            return $this->$key;
116
        }
117
118
        return $this->matter($key, $default);
119
    }
120
121
    /** @inheritDoc */
122
    public function matter(string $key = null, mixed $default = null): mixed
123
    {
124
        return $this->matter->get($key, $default);
125
    }
126
127
    /** @inheritDoc */
128
    public function has(string $key, bool $strict = false): bool
129
    {
130
        if ($strict) {
131
            return property_exists($this, $key) || $this->matter->has($key);
132
        }
133
134
        return ! blank($this->get($key));
135
    }
136
137
    /** @inheritDoc */
138
    public function getIdentifier(): string
139
    {
140
        return $this->identifier;
141
    }
142
143
    /** @inheritDoc */
144
    public function getSourcePath(): string
145
    {
146
        return static::qualifyBasename($this->identifier);
147
    }
148
149
    /** @inheritDoc */
150
    public function getOutputPath(): string
151
    {
152
        return $this->getCurrentPagePath().'.html';
153
    }
154
155
    /** @inheritDoc */
156
    public function getCurrentPagePath(): string
157
    {
158
        return trim(static::getOutputDirectory().'/'.$this->identifier, '/');
159
    }
160
161
    /** @inheritDoc */
162
    public function getRouteKey(): string
163
    {
164
        return $this->routeKey;
165
    }
166
167
    /** @inheritDoc */
168
    public function getRoute(): Route
169
    {
170
        return new Route($this);
171
    }
172
173
    /** @inheritDoc */
174
    public function htmlTitle(): string
175
    {
176
        return config('site.name', 'HydePHP').' - '.$this->title;
177
    }
178
179
    /** @inheritDoc */
180
    public function getBladeView(): string
181
    {
182
        return static::$template;
183
    }
184
185
    /** @inheritDoc */
186
    abstract public function compile(): string;
187
188
    public function renderPageMetadata(): string
189
    {
190
        return $this->metadata->render();
191
    }
192
193
    public function showInNavigation(): bool
194
    {
195
        return ! $this->navigation['hidden'];
196
    }
197
198
    public function navigationMenuPriority(): int
199
    {
200
        return $this->navigation['priority'];
201
    }
202
203
    public function navigationMenuTitle(): string
204
    {
205
        return $this->navigation['title'];
206
    }
207
}
208