Passed
Push — master ( 6d6565...6a1810 )
by Caen
03:18 queued 12s
created

HydePage::showInNavigation()   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\Internal\ConstructsPageSchemas;
7
use Hyde\Framework\Contracts\CompilableContract;
8
use Hyde\Framework\Contracts\FrontMatter\PageSchema;
9
use Hyde\Framework\Contracts\RouteContract;
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\NavigationData;
15
use Hyde\Framework\Models\Route;
16
use Hyde\Framework\Services\DiscoveryService;
17
use Illuminate\Support\Arr;
18
19
/**
20
 * To ensure compatibility with the Hyde Framework, all page models should extend this class.
21
 * Markdown-based pages can extend the BaseMarkdownPage class to get relevant helpers.
22
 *
23
 * Unlike other frameworks, in general you don't instantiate pages yourself in Hyde,
24
 * instead, the page models acts as blueprints defining information for Hyde to
25
 * know how to parse a file, and what data around it should be generated.
26
 *
27
 * To create a parsed file instance, you'd typically just create a source file,
28
 * and you can then access the parsed file from the HydeKernel's page index.
29
 * The source files are usually parsed by the SourceFileParser action.
30
 *
31
 * @see \Hyde\Framework\Concerns\BaseMarkdownPage
32
 * @see \Hyde\Framework\Testing\Feature\HydePageTest
33
 */
34
abstract class HydePage implements CompilableContract, PageSchema
35
{
36
    use ConstructsPageSchemas;
0 ignored issues
show
Bug introduced by
The trait Hyde\Framework\Concerns\...l\ConstructsPageSchemas requires the property $markdown which is not provided by Hyde\Framework\Concerns\HydePage.
Loading history...
37
    use Internal\GeneratesNavigationData;
38
39
    public static string $sourceDirectory;
40
    public static string $outputDirectory;
41
    public static string $fileExtension;
42
    public static string $template;
43
44
    public string $identifier;
45
    public string $routeKey;
46
47
    public FrontMatter $matter;
48
    public Metadata $metadata;
49
50
    public string $title;
51
    public ?string $canonicalUrl = null;
52
    public ?NavigationData $navigation = null;
53
54
    public function __construct(string $identifier = '', FrontMatter|array $matter = [])
55
    {
56
        $this->identifier = $identifier;
57
        $this->routeKey = static::routeKey($identifier);
58
59
        $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...
60
        $this->constructPageSchemas();
61
        $this->metadata = new Metadata($this);
62
    }
63
64
    // Section: Query
65
66
    /**
67
     * Parse a source file into a page model instance.
68
     *
69
     * @param  string  $identifier  The identifier of the page to parse.
70
     * @return static New page model instance for the parsed source file.
71
     */
72
    public static function parse(string $identifier): HydePage
73
    {
74
        return (new SourceFileParser(static::class, $identifier))->get();
75
    }
76
77
    /**
78
     * Get an array of all the source file identifiers for the model.
79
     *
80
     * Essentially an alias of DiscoveryService::getAbstractPageList().
81
     *
82
     * @return array<string>|false
83
     */
84
    public static function files(): array|false
85
    {
86
        return DiscoveryService::getSourceFileListForModel(static::class);
87
    }
88
89
    /**
90
     * Get a collection of all pages, parsed into page models.
91
     *
92
     * @return \Hyde\Framework\Foundation\PageCollection<\Hyde\Framework\Concerns\HydePage
93
     */
94
    public static function all(): PageCollection
95
    {
96
        return Hyde::pages()->getPages(static::class);
97
    }
98
99
    // Section: Filesystem
100
101
    /**
102
     * Get the directory in where source files are stored.
103
     */
104
    final public static function sourceDirectory(): string
105
    {
106
        return unslash(static::$sourceDirectory);
107
    }
108
109
    /**
110
     * Get the output subdirectory to store compiled HTML.
111
     */
112
    final public static function outputDirectory(): string
113
    {
114
        return unslash(static::$outputDirectory);
115
    }
116
117
    /**
118
     * Get the file extension of the source files.
119
     */
120
    final public static function fileExtension(): string
121
    {
122
        return '.'.ltrim(static::$fileExtension, '.');
123
    }
124
125
    /**
126
     * Qualify a page identifier into a referenceable local file path.
127
     */
128
    public static function sourcePath(string $identifier): string
129
    {
130
        return static::sourceDirectory().'/'.unslash($identifier).static::fileExtension();
131
    }
132
133
    /**
134
     * Get the proper site output path for a page model.
135
     */
136
    public static function outputPath(string $identifier): string
137
    {
138
        return static::routeKey($identifier).'.html';
139
    }
140
141
    /**
142
     * Get the path to the source file, relative to the project root.
143
     * In other words, qualify the identifier of the page instance.
144
     */
145
    public function getSourcePath(): string
146
    {
147
        return static::sourcePath($this->identifier);
148
    }
149
150
    /**
151
     * Get the path where the compiled page instance will be saved.
152
     */
153
    public function getOutputPath(): string
154
    {
155
        return static::outputPath($this->identifier);
156
    }
157
158
    // Section: Routing
159
160
    /**
161
     * Format a page identifier to a route key.
162
     */
163
    public static function routeKey(string $identifier): string
164
    {
165
        return unslash(static::outputDirectory().'/'.$identifier);
166
    }
167
168
    /**
169
     * Get the route key for the page.
170
     *
171
     * The route key is the URI path relative to the site root.
172
     *
173
     * For example, if the compiled page will be saved to _site/docs/index.html,
174
     * then this method will return 'docs/index'. Route keys are used to
175
     * identify pages, similar to how named routes work in Laravel.
176
     *
177
     * @return string The page's route key.
178
     */
179
    public function getRouteKey(): string
180
    {
181
        return $this->routeKey;
182
    }
183
184
    /**
185
     * Get the route for the page.
186
     *
187
     * @return RouteContract The page's route.
188
     */
189
    public function getRoute(): RouteContract
190
    {
191
        return new Route($this);
192
    }
193
194
    // Section: Getters
195
196
    /**
197
     * Get the page model's identifier property.
198
     *
199
     * The identifier is the part between the source directory and the file extension.
200
     * It may also be known as a 'slug', or previously 'basename'.
201
     *
202
     * For example, the identifier of a source file stored as '_pages/about/contact.md'
203
     * would be 'about/contact', and 'pages/about.md' would simply be 'about'.
204
     *
205
     * @return string The page's identifier.
206
     */
207
    public function getIdentifier(): string
208
    {
209
        return $this->identifier;
210
    }
211
212
    /**
213
     * Get the Blade template key for the page.
214
     */
215
    public function getBladeView(): string
216
    {
217
        return static::$template;
218
    }
219
220
    // Section: Front Matter
221
222
    /**
223
     * Get a value from the computed page data, or fallback to the page's front matter, then to the default value.
224
     *
225
     * @return \Hyde\Framework\Models\FrontMatter|mixed
226
     */
227
    public function get(string $key = null, mixed $default = null): mixed
228
    {
229
        return Arr::get(array_filter(array_merge(
230
            $this->matter->toArray(),
231
            (array) $this,
232
        )), $key, $default);
233
    }
234
235
    /**
236
     * Get the front matter object, or a value from within.
237
     *
238
     * @return \Hyde\Framework\Models\FrontMatter|mixed
239
     */
240
    public function matter(string $key = null, mixed $default = null): mixed
241
    {
242
        return $this->matter->get($key, $default);
243
    }
244
245
    /**
246
     * See if a value exists in the computed page data or the front matter.
247
     */
248
    public function has(string $key): bool
249
    {
250
        return ! blank($this->get($key));
251
    }
252
253
    // Section: Accessors
254
255
    /**
256
     * Get the page title to display in HTML tags like <title> and <meta> tags.
257
     */
258
    public function htmlTitle(): string
259
    {
260
        return config('site.name', 'HydePHP').' - '.$this->title;
261
    }
262
263
    public function renderPageMetadata(): string
264
    {
265
        return $this->metadata->render();
266
    }
267
268
    public function showInNavigation(): bool
269
    {
270
        return ! $this->navigation['hidden'];
271
    }
272
273
    public function navigationMenuPriority(): int
274
    {
275
        return $this->navigation['priority'];
276
    }
277
278
    public function navigationMenuLabel(): string
279
    {
280
        return $this->navigation['label'];
281
    }
282
283
    public function navigationMenuGroup(): ?string
284
    {
285
        return $this->navigation['group'];
286
    }
287
}
288