Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
8 / 8
CRAP
100.00% covered (success)
100.00%
1 / 1
PublishHomepageCommand
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
8 / 8
14
100.00% covered (success)
100.00%
1 / 1
 handle
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
5
 parseSelection
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 promptForHomepage
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 formatPublishableChoices
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getTemplateOptions
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 parseChoiceIntoKey
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 canExistingFileBeOverwritten
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 isTheExistingFileADefaultOne
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Hyde\Console\Commands;
6
7use Hyde\Pages\BladePage;
8use Hyde\Console\Concerns\Command;
9use Hyde\Console\Concerns\AsksToRebuildSite;
10use Hyde\Framework\Services\ViewDiffService;
11use Illuminate\Support\Facades\Artisan;
12use Illuminate\Support\Collection;
13
14use function Hyde\unixsum_file;
15use function array_key_exists;
16use function file_exists;
17use function str_replace;
18use function strstr;
19
20/**
21 * Publish one of the default homepages to index.blade.php.
22 */
23class PublishHomepageCommand extends Command
24{
25    use AsksToRebuildSite;
26
27    /** @var string */
28    protected $signature = 'publish:homepage {homepage? : The name of the page to publish}
29                                {--force : Overwrite any existing files}';
30
31    /** @var string */
32    protected $description = 'Publish one of the default homepages to index.blade.php';
33
34    /** @var array<string, array{name: string, description: string, group: string}> */
35    protected array $options = [
36        'welcome' => [
37            'name' => 'Welcome',
38            'description' => 'The default welcome page.',
39            'group' => 'hyde-welcome-page',
40        ],
41        'posts' => [
42            'name' => 'Posts Feed',
43            'description' => 'A feed of your latest posts. Perfect for a blog site!',
44            'group' => 'hyde-posts-page',
45        ],
46        'blank' => [
47            'name' => 'Blank Starter',
48            'description' => 'A blank Blade template with just the base layout.',
49            'group' => 'hyde-blank-page',
50        ],
51    ];
52
53    public function handle(): int
54    {
55        $selected = $this->parseSelection();
56
57        if (! $this->canExistingFileBeOverwritten()) {
58            $this->error('A modified index.blade.php file already exists. Use --force to overwrite.');
59
60            return 409;
61        }
62
63        $tagExists = array_key_exists($selected, $this->options);
64
65        Artisan::call('vendor:publish', [
66            '--tag' => $this->options[$selected]['group'] ?? $selected,
67            '--force' => true,
68        ], $tagExists ? null : $this->output); // If the tag doesn't exist, we pass the output to use the called command's error output.
69
70        if ($tagExists) {
71            $this->infoComment("Published page [$selected]");
72
73            $this->askToRebuildSite();
74        }
75
76        return $tagExists ? Command::SUCCESS : 404;
77    }
78
79    protected function parseSelection(): string
80    {
81        return $this->argument('homepage') ?? $this->parseChoiceIntoKey($this->promptForHomepage());
82    }
83
84    protected function promptForHomepage(): string
85    {
86        return $this->choice(
87            'Which homepage do you want to publish?',
88            $this->formatPublishableChoices(),
89            0
90        );
91    }
92
93    protected function formatPublishableChoices(): array
94    {
95        return $this->getTemplateOptions()->map(function (array $option, string $key): string {
96            return  "<comment>$key</comment>: {$option['description']}";
97        })->values()->toArray();
98    }
99
100    /** @return Collection<array{name: string, description: string, group: string}> */
101    protected function getTemplateOptions(): Collection
102    {
103        return new Collection($this->options);
104    }
105
106    protected function parseChoiceIntoKey(string $choice): string
107    {
108        return strstr(str_replace(['<comment>', '</comment>'], '', $choice), ':', true);
109    }
110
111    protected function canExistingFileBeOverwritten(): bool
112    {
113        if ($this->option('force')) {
114            return true;
115        }
116
117        if (! file_exists(BladePage::path('index.blade.php'))) {
118            return true;
119        }
120
121        return $this->isTheExistingFileADefaultOne();
122    }
123
124    protected function isTheExistingFileADefaultOne(): bool
125    {
126        return ViewDiffService::checksumMatchesAny(unixsum_file(BladePage::path('index.blade.php')));
127    }
128}