Passed
Push — master ( c4a5b0...3b0e83 )
by Caen
03:01 queued 12s
created

AbstractPage::all()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Hyde\Framework\Contracts;
4
5
use Hyde\Framework\Actions\SourceFileParser;
6
use Hyde\Framework\Concerns\FrontMatter\Schemas\PageSchema;
7
use Hyde\Framework\Helpers\Meta;
8
use Hyde\Framework\Hyde;
9
use Hyde\Framework\Models\FrontMatter;
10
use Hyde\Framework\Models\Pages\MarkdownPost;
11
use Hyde\Framework\Models\Route;
12
use Hyde\Framework\Services\DiscoveryService;
13
use Illuminate\Support\Collection;
14
15
/**
16
 * To ensure compatibility with the Hyde Framework, all Page Models should extend this class.
17
 *
18
 * Markdown-based Pages can extend the AbstractMarkdownPage class to get relevant helpers.
19
 *
20
 * To learn about what the methods do, see the PHPDocs in the PageContract.
21
 *
22
 * @see \Hyde\Framework\Contracts\PageContract
23
 * @see \Hyde\Framework\Contracts\AbstractMarkdownPage
24
 * @see \Hyde\Framework\Testing\Feature\AbstractPageTest
25
 */
26
abstract class AbstractPage implements PageContract, CompilableContract
27
{
28
    use PageSchema;
29
30
    public static string $sourceDirectory;
31
    public static string $outputDirectory;
32
    public static string $fileExtension;
33
    public static string $template;
34
35
    public string $identifier;
36
    public FrontMatter $matter;
37
38
    /** @inheritDoc */
39
    final public static function getSourceDirectory(): string
40
    {
41
        return unslash(static::$sourceDirectory);
42
    }
43
44
    /** @inheritDoc */
45
    final public static function getOutputDirectory(): string
46
    {
47
        return unslash(static::$outputDirectory);
48
    }
49
50
    /** @inheritDoc */
51
    final public static function getFileExtension(): string
52
    {
53
        return '.'.ltrim(static::$fileExtension, '.');
54
    }
55
56
    /** @inheritDoc */
57
    public static function parse(string $slug): PageContract
58
    {
59
        return (new SourceFileParser(static::class, $slug))->get();
60
    }
61
62
    /** @inheritDoc */
63
    public static function files(): array|false
64
    {
65
        return DiscoveryService::getSourceFileListForModel(static::class);
66
    }
67
68
    /** @inheritDoc */
69
    public static function all(): Collection
70
    {
71
        $collection = new Collection();
72
73
        foreach (static::files() as $basename) {
74
            $collection->push(static::parse($basename));
75
        }
76
77
        return $collection;
78
    }
79
80
    /** @inheritDoc */
81
    public static function qualifyBasename(string $basename): string
82
    {
83
        return static::getSourceDirectory().'/'.unslash($basename).static::getFileExtension();
84
    }
85
86
    /** @inheritDoc */
87
    public static function getOutputLocation(string $basename): string
88
    {
89
        // Using the trim function we ensure we don't have a leading slash when the output directory is the root directory.
90
        return trim(
91
            static::getOutputDirectory().'/'.unslash($basename),
92
            '/'
93
        ).'.html';
94
    }
95
96
    public function __construct(string $identifier = '', FrontMatter|array $matter = [])
97
    {
98
        $this->identifier = $identifier;
99
        $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...
100
        $this->constructPageSchemas();
101
    }
102
103
    protected function constructPageSchemas(): void
104
    {
105
        $this->constructPageSchema();
106
    }
107
108
    /** @inheritDoc */
109
    public function get(string $key = null, mixed $default = null): mixed
110
    {
111
        if (property_exists($this, $key) && isset($this->$key)) {
0 ignored issues
show
Bug introduced by
It seems like $key can also be of type null; however, parameter $property of property_exists() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

111
        if (property_exists($this, /** @scrutinizer ignore-type */ $key) && isset($this->$key)) {
Loading history...
112
            return $this->$key;
113
        }
114
115
        return $this->matter($key, $default);
116
    }
117
118
    /** @inheritDoc */
119
    public function matter(string $key = null, mixed $default = null): mixed
120
    {
121
        return $this->matter->get($key, $default);
122
    }
123
124
    /** @inheritDoc */
125
    public function getIdentifier(): string
126
    {
127
        return $this->identifier;
128
    }
129
130
    /** @inheritDoc */
131
    public function getSourcePath(): string
132
    {
133
        return static::qualifyBasename($this->identifier);
134
    }
135
136
    /** @inheritDoc */
137
    public function getOutputPath(): string
138
    {
139
        return static::getCurrentPagePath().'.html';
0 ignored issues
show
Bug Best Practice introduced by
The method Hyde\Framework\Contracts...e::getCurrentPagePath() is not static, but was called statically. ( Ignorable by Annotation )

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

139
        return static::/** @scrutinizer ignore-call */ getCurrentPagePath().'.html';
Loading history...
140
    }
141
142
    /** @inheritDoc */
143
    public function getCurrentPagePath(): string
144
    {
145
        return trim(static::getOutputDirectory().'/'.$this->identifier, '/');
146
    }
147
148
    /** @inheritDoc */
149
    public function getRoute(): Route
150
    {
151
        return new Route($this);
152
    }
153
154
    /** @inheritDoc */
155
    public function htmlTitle(): string
156
    {
157
        return config('site.name', 'HydePHP').' - '.$this->title;
158
    }
159
160
    /** @inheritDoc */
161
    public function getBladeView(): string
162
    {
163
        return static::$template;
164
    }
165
166
    /** @inheritDoc */
167
    abstract public function compile(): string;
168
169
    /**
170
     * @internal
171
     *
172
     * @return string[]
173
     *
174
     * @psalm-return list<string>
175
     */
176
    public function getDynamicMetadata(): array
177
    {
178
        $array = [];
179
180
        if (! empty($this->canonicalUrl)) {
181
            $array[] = Meta::link('canonical', $this->canonicalUrl);
182
        }
183
184
        if (! empty($this->title)) {
185
            $array[] = Meta::name('twitter:title', $this->htmlTitle());
186
            $array[] = Meta::property('title', $this->htmlTitle());
187
        }
188
189
        if ($this instanceof MarkdownPost) {
190
            $array[] = "\n<!-- Blog Post Meta Tags -->";
191
            foreach ($this->getMetadata() as $name => $content) {
192
                $array[] = Meta::name($name, $content);
193
            }
194
            foreach ($this->getMetaProperties() as $property => $content) {
195
                $array[] = Meta::property($property, $content);
196
            }
197
        }
198
199
        return $array;
200
    }
201
202
    public function renderPageMetadata(): string
203
    {
204
        return Meta::render(
205
            withMergedData: $this->getDynamicMetadata()
206
        );
207
    }
208
209
    public function showInNavigation(): bool
210
    {
211
        return ! $this->navigation['hidden'];
212
    }
213
214
    public function navigationMenuPriority(): int
215
    {
216
        return $this->navigation['priority'];
217
    }
218
219
    public function navigationMenuTitle(): string
220
    {
221
        return $this->navigation['title'];
222
    }
223
224
    /**
225
     * Not yet implemented.
226
     *
227
     * If an item returns a route collection,
228
     * it will automatically be made into a dropdown.
229
     *
230
     * @return \Illuminate\Support\Collection<\Hyde\Framework\Models\Route>
231
     */
232
    // public function navigationMenuChildren(): Collection;
233
}
234