Passed
Push — master ( 856b52...5c51b9 )
by Caen
03:00 queued 12s
created

BuildService::compilePagesForClass()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 5
c 3
b 0
f 0
dl 0
loc 11
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Framework\Services;
6
7
use function collect;
8
use Hyde\Facades\Site;
9
use Hyde\Foundation\RouteCollection;
10
use Hyde\Framework\Actions\StaticPageBuilder;
11
use Hyde\Framework\Concerns\InteractsWithDirectories;
12
use Hyde\Hyde;
13
use Hyde\Support\Models\Route;
14
use Illuminate\Console\Concerns\InteractsWithIO;
15
use Illuminate\Console\OutputStyle;
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
        collect(Hyde::getDiscoveredPageTypes())->each(function (string $pageClass) {
0 ignored issues
show
Bug introduced by
Hyde\Hyde::getDiscoveredPageTypes() of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

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

42
        collect(/** @scrutinizer ignore-type */ Hyde::getDiscoveredPageTypes())->each(function (string $pageClass) {
Loading history...
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
     * @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...
74
     */
75
    protected function compilePagesForClass(string $pageClass): void
76
    {
77
        $this->comment("Creating {$this->getClassPluralName($pageClass)}...");
78
79
        $collection = $this->router->getRoutes($pageClass);
80
81
        $this->withProgressBar($collection, function (Route $route): void {
82
            (new StaticPageBuilder($route->getPage()))->__invoke();
83
        });
84
85
        $this->newLine(2);
86
    }
87
88
    protected function getClassPluralName(string $pageClass): string
89
    {
90
        return preg_replace('/([a-z])([A-Z])/', '$1 $2', class_basename($pageClass)).'s';
91
    }
92
93
    protected function isItSafeToCleanOutputDirectory(): bool
94
    {
95
        if (! $this->isOutputDirectoryWhitelisted() && ! $this->askIfUnsafeDirectoryShouldBeEmptied()) {
96
            $this->info('Output directory will not be emptied.');
97
98
            return false;
99
        }
100
101
        return true;
102
    }
103
104
    protected function isOutputDirectoryWhitelisted(): bool
105
    {
106
        return in_array(basename(Hyde::sitePath()), $this->safeOutputDirectories());
107
    }
108
109
    protected function askIfUnsafeDirectoryShouldBeEmptied(): bool
110
    {
111
        return $this->confirm(sprintf(
112
            'The configured output directory (%s) is potentially unsafe to empty. '.
113
            'Are you sure you want to continue?',
114
            Site::$outputPath
115
        ));
116
    }
117
118
    protected function safeOutputDirectories(): array
119
    {
120
        return config('hyde.safe_output_directories', ['_site', 'docs', 'build']);
121
    }
122
}
123