Passed
Push — master ( 69e5ba...ec3c40 )
by Caen
03:39 queued 13s
created

getClassNamesForDiscoveredPageModels()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
c 0
b 0
f 0
dl 0
loc 5
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Framework\Services;
6
7
use Hyde\Facades\Site;
8
use Hyde\Foundation\RouteCollection;
9
use Hyde\Framework\Actions\StaticPageBuilder;
10
use Hyde\Framework\Concerns\InteractsWithDirectories;
11
use Hyde\Hyde;
12
use Hyde\Support\Models\Route;
13
use Illuminate\Console\Concerns\InteractsWithIO;
14
use Illuminate\Console\OutputStyle;
15
use Illuminate\Support\Collection;
16
use Illuminate\Support\Facades\File;
17
18
/**
19
 * Moves logic from the build command to a service.
20
 *
21
 * Handles the build loop which generates the static site.
22
 *
23
 * @see \Hyde\Console\Commands\BuildSiteCommand
24
 * @see \Hyde\Framework\Testing\Feature\StaticSiteServiceTest
25
 */
26
class BuildService
27
{
28
    use InteractsWithIO;
29
    use InteractsWithDirectories;
30
31
    protected RouteCollection $router;
32
33
    public function __construct(OutputStyle $output)
34
    {
35
        $this->output = $output;
36
37
        $this->router = Hyde::routes();
38
    }
39
40
    public function compileStaticPages(): void
41
    {
42
        $this->getClassNamesForDiscoveredPageModels()->each(function (string $pageClass) {
43
            $this->compilePagesForClass($pageClass);
44
        });
45
    }
46
47
    public function cleanOutputDirectory(): void
48
    {
49
        if (config('hyde.empty_output_directory', true)) {
50
            $this->warn('Removing all files from build directory.');
51
52
            if ($this->isItSafeToCleanOutputDirectory()) {
53
                array_map('unlink', glob(Hyde::sitePath('*.{html,json}'), GLOB_BRACE));
54
                File::cleanDirectory(Hyde::sitePath('media'));
55
            }
56
        }
57
    }
58
59
    public function transferMediaAssets(): void
60
    {
61
        $this->needsDirectory(Hyde::sitePath('media'));
62
63
        $this->comment('Transferring Media Assets...');
64
65
        $this->withProgressBar(DiscoveryService::getMediaAssetFiles(), function (string $filepath): void {
66
            copy($filepath, Hyde::sitePath('media/'.basename($filepath)));
67
        });
68
69
        $this->newLine(2);
70
    }
71
72
    /**
73
     * @return \Illuminate\Support\Collection<array-key, class-string<\Hyde\Pages\Concerns\HydePage>>
74
     */
75
    protected function getClassNamesForDiscoveredPageModels(): Collection
76
    {
77
        return $this->router->getRoutes()->map(function (Route $route): string {
78
            return $route->getPageClass();
79
        })->unique();
80
    }
81
82
    /**
83
     * @param  class-string<\Hyde\Pages\Concerns\HydePage>  $pageClass
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<\Hyde\Pages\Concerns\HydePage> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<\Hyde\Pages\Concerns\HydePage>.
Loading history...
84
     */
85
    protected function compilePagesForClass(string $pageClass): void
86
    {
87
        $this->comment("Creating {$this->getClassPluralName($pageClass)}...");
88
89
        $collection = $this->router->getRoutes($pageClass);
90
91
        $this->withProgressBar($collection, function (Route $route): void {
92
            (new StaticPageBuilder($route->getPage()))->__invoke();
93
        });
94
95
        $this->newLine(2);
96
    }
97
98
    protected function getClassPluralName(string $pageClass): string
99
    {
100
        return preg_replace('/([a-z])([A-Z])/', '$1 $2', class_basename($pageClass)).'s';
101
    }
102
103
    protected function isItSafeToCleanOutputDirectory(): bool
104
    {
105
        if (! $this->isOutputDirectoryWhitelisted() && ! $this->askIfUnsafeDirectoryShouldBeEmptied()) {
106
            $this->info('Output directory will not be emptied.');
107
108
            return false;
109
        }
110
111
        return true;
112
    }
113
114
    protected function isOutputDirectoryWhitelisted(): bool
115
    {
116
        return in_array(basename(Hyde::sitePath()), $this->safeOutputDirectories());
117
    }
118
119
    protected function askIfUnsafeDirectoryShouldBeEmptied(): bool
120
    {
121
        return $this->confirm(sprintf(
122
            'The configured output directory (%s) is potentially unsafe to empty. '.
123
            'Are you sure you want to continue?',
124
            Site::$outputPath
125
        ));
126
    }
127
128
    protected function safeOutputDirectories(): array
129
    {
130
        return config('hyde.safe_output_directories', ['_site', 'docs', 'build']);
131
    }
132
}
133