1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Hyde\Framework\Actions; |
6
|
|
|
|
7
|
|
|
use function file_exists; |
8
|
|
|
use Hyde\Framework\Concerns\InteractsWithDirectories; |
9
|
|
|
use Hyde\Framework\Exceptions\FileConflictException; |
10
|
|
|
use Hyde\Framework\Exceptions\UnsupportedPageTypeException; |
11
|
|
|
use Hyde\Hyde; |
12
|
|
|
use Hyde\Pages\BladePage; |
13
|
|
|
use Hyde\Pages\DocumentationPage; |
14
|
|
|
use Hyde\Pages\MarkdownPage; |
15
|
|
|
use Illuminate\Support\Str; |
16
|
|
|
use function in_array; |
17
|
|
|
use function rtrim; |
18
|
|
|
use function unslash; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* Scaffold a new Markdown, Blade, or documentation page. |
22
|
|
|
* |
23
|
|
|
* @see \Hyde\Framework\Testing\Feature\Actions\CreatesNewPageSourceFileTest |
24
|
|
|
*/ |
25
|
|
|
class CreatesNewPageSourceFile |
26
|
|
|
{ |
27
|
|
|
use InteractsWithDirectories; |
28
|
|
|
|
29
|
|
|
protected string $title; |
30
|
|
|
protected string $slug; |
31
|
|
|
protected string $outputPath; |
32
|
|
|
protected string $subDir = ''; |
33
|
|
|
protected bool $force = false; |
34
|
|
|
|
35
|
|
|
public function __construct(string $title, string $type = MarkdownPage::class, bool $force = false) |
36
|
|
|
{ |
37
|
|
|
$this->validateType($type); |
38
|
|
|
|
39
|
|
|
$this->title = $this->parseTitle($title); |
40
|
|
|
$this->slug = $this->parseSlug($title); |
41
|
|
|
$this->force = $force; |
42
|
|
|
|
43
|
|
|
$this->outputPath = $this->makeOutputPath($type); |
44
|
|
|
|
45
|
|
|
$this->createPage($type); |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
public function getOutputPath(): string |
49
|
|
|
{ |
50
|
|
|
return $this->outputPath; |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
protected function parseTitle(string $title): string |
54
|
|
|
{ |
55
|
|
|
return Str::afterLast($title, '/'); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
protected function parseSlug(string $title): string |
59
|
|
|
{ |
60
|
|
|
// If title contains a slash, it's a subdirectory |
61
|
|
|
if (str_contains($title, '/')) { |
62
|
|
|
// So we normalize the subdirectory name |
63
|
|
|
$this->subDir = $this->normalizeSubdirectory($title); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
// And return a slug made from just the title without the subdirectory |
67
|
|
|
return Str::slug(basename($title)); |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
protected function normalizeSubdirectory(string $title): string |
71
|
|
|
{ |
72
|
|
|
return unslash('/'.rtrim(Str::beforeLast($title, '/').'/', '/\\')); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
protected function makeOutputPath(string $pageClass): string |
76
|
|
|
{ |
77
|
|
|
/** @var \Hyde\Pages\Concerns\HydePage $pageClass */ |
78
|
|
|
return Hyde::path($pageClass::sourcePath($this->formatIdentifier())); |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
protected function createPage(string $type): void |
82
|
|
|
{ |
83
|
|
|
match ($type) { |
84
|
|
|
BladePage::class => $this->createBladeFile(), |
|
|
|
|
85
|
|
|
MarkdownPage::class => $this->createMarkdownFile(), |
|
|
|
|
86
|
|
|
DocumentationPage::class => $this->createDocumentationFile(), |
|
|
|
|
87
|
|
|
}; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
protected function createBladeFile(): void |
91
|
|
|
{ |
92
|
|
|
$this->createFile(<<<BLADE |
93
|
|
|
@extends('hyde::layouts.app') |
94
|
|
|
@section('content') |
95
|
|
|
@php(\$title = "$this->title") |
96
|
|
|
|
97
|
|
|
<main class="mx-auto max-w-7xl py-16 px-8"> |
98
|
|
|
<h1 class="text-center text-3xl font-bold">$this->title</h1> |
99
|
|
|
</main> |
100
|
|
|
|
101
|
|
|
@endsection |
102
|
|
|
|
103
|
|
|
BLADE |
104
|
|
|
); |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
protected function createMarkdownFile(): void |
108
|
|
|
{ |
109
|
|
|
$this->createFile("---\ntitle: $this->title\n---\n\n# $this->title\n"); |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
protected function createDocumentationFile(): void |
113
|
|
|
{ |
114
|
|
|
$this->createFile("# $this->title\n"); |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
protected function formatIdentifier(): string |
118
|
|
|
{ |
119
|
|
|
return "$this->subDir/$this->slug"; |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
protected function validateType(string $pageClass): void |
123
|
|
|
{ |
124
|
|
|
if (! in_array($pageClass, [MarkdownPage::class, BladePage::class, DocumentationPage::class])) { |
125
|
|
|
throw new UnsupportedPageTypeException('The page type must be either "markdown", "blade", or "documentation"'); |
126
|
|
|
} |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
protected function failIfFileCannotBeSaved(string $path): void |
130
|
|
|
{ |
131
|
|
|
if (file_exists($path) && ! $this->force) { |
132
|
|
|
throw new FileConflictException($path); |
133
|
|
|
} |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
protected function prepareOutputDirectory(): void |
137
|
|
|
{ |
138
|
|
|
$this->needsParentDirectory($this->outputPath); |
139
|
|
|
$this->failIfFileCannotBeSaved($this->outputPath); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
protected function createFile(string $contents): void |
143
|
|
|
{ |
144
|
|
|
$this->prepareOutputDirectory(); |
145
|
|
|
|
146
|
|
|
file_put_contents($this->outputPath, $contents); |
147
|
|
|
} |
148
|
|
|
} |
149
|
|
|
|
This check looks for function or method calls that always return null and whose return value is used.
The method
getObject()
can return nothing but null, so it makes no sense to use the return value.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.