Passed
Push — master ( 604c70...f4f5f5 )
by Caen
03:01 queued 12s
created

HydePage::getRoute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Pages\Concerns;
6
7
use Hyde\Foundation\Facades;
8
use Hyde\Foundation\PageCollection;
9
use Hyde\Framework\Actions\SourceFileParser;
10
use Hyde\Framework\Concerns\InteractsWithFrontMatter;
11
use Hyde\Framework\Factories\Concerns\HasFactory;
12
use Hyde\Framework\Features\Metadata\PageMetadataBag;
13
use Hyde\Framework\Features\Navigation\NavigationData;
14
use Hyde\Framework\Services\DiscoveryService;
15
use Hyde\Hyde;
16
use Hyde\Markdown\Contracts\FrontMatter\PageSchema;
17
use Hyde\Markdown\Models\FrontMatter;
18
use Hyde\Support\Models\Route;
19
use Hyde\Support\Models\RouteKey;
20
use function unslash;
21
22
/**
23
 * The base class for all Hyde pages.
24
 *
25
 * To ensure compatibility with the Hyde Framework, all page models should extend this class.
26
 * Markdown-based pages can extend the BaseMarkdownPage class to get relevant helpers.
27
 *
28
 * Unlike other frameworks, in general you don't instantiate pages yourself in Hyde,
29
 * instead, the page models acts as blueprints defining information for Hyde to
30
 * know how to parse a file, and what data around it should be generated.
31
 *
32
 * To create a parsed file instance, you'd typically just create a source file,
33
 * and you can then access the parsed file from the HydeKernel's page index.
34
 * The source files are usually parsed by the SourceFileParser action.
35
 *
36
 * In Blade views, you can always access the current page instance being rendered using the $page variable.
37
 *
38
 * @see \Hyde\Pages\Concerns\BaseMarkdownPage
39
 * @see \Hyde\Framework\Testing\Feature\HydePageTest
40
 */
41
abstract class HydePage implements PageSchema
42
{
43
    use InteractsWithFrontMatter;
44
    use HasFactory;
0 ignored issues
show
Bug introduced by
The trait Hyde\Framework\Factories\Concerns\HasFactory requires the property $markdown which is not provided by Hyde\Pages\Concerns\HydePage.
Loading history...
45
46
    public static string $sourceDirectory;
47
    public static string $outputDirectory;
48
    public static string $fileExtension;
49
    public static string $template;
50
51
    public string $identifier;
52
    public string $routeKey;
53
54
    public FrontMatter $matter;
55
    public PageMetadataBag $metadata;
56
57
    public string $title;
58
    public ?string $canonicalUrl = null;
59
    public ?NavigationData $navigation = null;
60
61
    public static function make(string $identifier = '', FrontMatter|array $matter = []): static
62
    {
63
        return new static($identifier, $matter);
64
    }
65
66
    public function __construct(string $identifier = '', FrontMatter|array $matter = [])
67
    {
68
        $this->identifier = $identifier;
69
        $this->routeKey = RouteKey::fromPage(static::class, $identifier)->get();
70
71
        $this->matter = $matter instanceof FrontMatter ? $matter : new FrontMatter($matter);
0 ignored issues
show
introduced by
$matter is never a sub-type of Hyde\Markdown\Models\FrontMatter.
Loading history...
72
        $this->constructPageSchemas();
73
        $this->metadata = new PageMetadataBag($this);
74
    }
75
76
    // Section: Query
77
78
    /**
79
     * Parse a source file into a page model instance.
80
     *
81
     * @param  string  $identifier  The identifier of the page to parse.
82
     * @return static New page model instance for the parsed source file.
83
     */
84
    public static function parse(string $identifier): HydePage
85
    {
86
        return (new SourceFileParser(static::class, $identifier))->get();
87
    }
88
89
    /**
90
     * Get an array of all the source file identifiers for the model.
91
     *
92
     * Essentially an alias of DiscoveryService::getAbstractPageList().
93
     *
94
     * @return array<string>|false
95
     */
96
    public static function files(): array|false
97
    {
98
        return DiscoveryService::getSourceFileListForModel(static::class);
99
    }
100
101
    /**
102
     * Get a collection of all pages, parsed into page models.
103
     *
104
     * @return \Hyde\Foundation\PageCollection<\Hyde\Pages\Concerns\HydePage>
105
     */
106
    public static function all(): PageCollection
107
    {
108
        return Facades\PageCollection::getPages(static::class);
0 ignored issues
show
Bug introduced by
The method getPages() does not exist on Hyde\Foundation\Facades\PageCollection. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

108
        return Facades\PageCollection::/** @scrutinizer ignore-call */ getPages(static::class);
Loading history...
109
    }
110
111
    // Section: Filesystem
112
113
    /**
114
     * Get the directory in where source files are stored.
115
     */
116
    final public static function sourceDirectory(): string
117
    {
118
        return unslash(static::$sourceDirectory);
119
    }
120
121
    /**
122
     * Get the output subdirectory to store compiled HTML.
123
     */
124
    final public static function outputDirectory(): string
125
    {
126
        return unslash(static::$outputDirectory);
127
    }
128
129
    /**
130
     * Get the file extension of the source files.
131
     */
132
    final public static function fileExtension(): string
133
    {
134
        return '.'.ltrim(static::$fileExtension, '.');
135
    }
136
137
    /**
138
     * Qualify a page identifier into a local file path for the page source file relative to the project root.
139
     */
140
    public static function sourcePath(string $identifier): string
141
    {
142
        return static::sourceDirectory().'/'.unslash($identifier).static::fileExtension();
143
    }
144
145
    /**
146
     * Qualify a page identifier into a target output file path relative to the _site output directory.
147
     */
148
    public static function outputPath(string $identifier): string
149
    {
150
        return RouteKey::fromPage(static::class, $identifier).'.html';
151
    }
152
153
    /**
154
     * Get an absolute file path to the page's source directory, or a file within it.
155
     */
156
    public static function path(string $path = ''): string
157
    {
158
        return Hyde::path(unslash(static::sourceDirectory().'/'.unslash($path)));
159
    }
160
161
    /**
162
     * Compile the page into static HTML.
163
     *
164
     * @return string The compiled HTML for the page.
165
     */
166
    abstract public function compile(): string;
167
168
    /**
169
     * Get the path to the instance source file, relative to the project root.
170
     */
171
    public function getSourcePath(): string
172
    {
173
        return static::sourcePath($this->identifier);
174
    }
175
176
    /**
177
     * Get the path where the compiled page will be saved.
178
     *
179
     * @return string Path relative to the site output directory.
180
     */
181
    public function getOutputPath(): string
182
    {
183
        return static::outputPath($this->identifier);
184
    }
185
186
    // Section: Routing
187
188
    /**
189
     * Get the route key for the page.
190
     *
191
     * The route key is the URL path relative to the site root.
192
     *
193
     * For example, if the compiled page will be saved to _site/docs/index.html,
194
     * then this method will return 'docs/index'. Route keys are used to
195
     * identify pages, similar to how named routes work in Laravel.
196
     *
197
     * @return string The page's route key.
198
     */
199
    public function getRouteKey(): string
200
    {
201
        return $this->routeKey;
202
    }
203
204
    /**
205
     * Get the route for the page.
206
     *
207
     * @return \Hyde\Support\Models\Route The page's route.
208
     */
209
    public function getRoute(): Route
210
    {
211
        return new Route($this);
212
    }
213
214
    /**
215
     * Format the page instance to a URL path (relative to site root) with support for pretty URLs if enabled.
216
     */
217
    public function getLink(): string
218
    {
219
        return Hyde::formatLink($this->getOutputPath());
220
    }
221
222
    // Section: Getters
223
224
    /**
225
     * Get the page model's identifier property.
226
     *
227
     * The identifier is the part between the source directory and the file extension.
228
     * It may also be known as a 'slug', or previously 'basename'.
229
     *
230
     * For example, the identifier of a source file stored as '_pages/about/contact.md'
231
     * would be 'about/contact', and 'pages/about.md' would simply be 'about'.
232
     *
233
     * @return string The page's identifier.
234
     */
235
    public function getIdentifier(): string
236
    {
237
        return $this->identifier;
238
    }
239
240
    /**
241
     * Get the Blade template for the page.
242
     *
243
     * @return string Blade template/view key.
244
     */
245
    public function getBladeView(): string
246
    {
247
        return static::$template;
248
    }
249
250
    // Section: Accessors
251
252
    /**
253
     * Get the page title to display in HTML tags like <title> and <meta> tags.
254
     */
255
    public function htmlTitle(): string
256
    {
257
        return config('site.name', 'HydePHP').' - '.$this->title;
258
    }
259
260
    public function metadata(): PageMetadataBag
261
    {
262
        return $this->metadata;
263
    }
264
265
    public function showInNavigation(): bool
266
    {
267
        return ! $this->navigation['hidden'];
268
    }
269
270
    public function navigationMenuPriority(): int
271
    {
272
        return $this->navigation['priority'];
273
    }
274
275
    public function navigationMenuLabel(): string
276
    {
277
        return $this->navigation['label'];
278
    }
279
280
    public function navigationMenuGroup(): ?string
281
    {
282
        return $this->navigation['group'];
283
    }
284
}
285