Skip to content

Commit

Permalink
Merge pull request #664 from hydephp/refactor-view-publishers
Browse files Browse the repository at this point in the history
Refactor publishable templates
  • Loading branch information
caendesilva authored Nov 13, 2022
2 parents f4f5f57 + 019eda7 commit 69e5ba3
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 134 deletions.
84 changes: 40 additions & 44 deletions packages/framework/src/Console/Commands/PublishHomepageCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

namespace Hyde\Console\Commands;

use Hyde\Framework\Actions\PublishesHomepageView;
use Hyde\Console\Concerns\AsksToRebuildSite;
use Hyde\Framework\Features\Templates\Homepages;
use Hyde\Framework\Features\Templates\PublishableContract;
use Hyde\Framework\Services\ChecksumService;
use Hyde\Hyde;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Collection;
use LaravelZero\Framework\Commands\Command;

/**
Expand All @@ -17,94 +19,88 @@
*/
class PublishHomepageCommand extends Command
{
use AsksToRebuildSite;

/** @var string */
protected $signature = 'publish:homepage {homepage? : The name of the page to publish}
{--force : Overwrite any existing files}';

/** @var string */
protected $description = 'Publish one of the default homepages to index.blade.php.';

protected string $selected;

public function handle(): int
{
$this->selected = $this->argument('homepage') ?? $this->promptForHomepage();
$selected = $this->parseSelection();

if (! $this->canExistingIndexFileBeOverwritten()) {
$this->error('A modified index.blade.php file already exists. Use --force to overwrite.');
if (! Homepages::exists($selected)) {
$this->error("Homepage $selected does not exist.");

return 409;
return 404;
}

$returnValue = (new PublishesHomepageView(
$this->selected
))->execute();

if (is_numeric($returnValue)) {
if ($returnValue == 404) {
$this->error('Homepage '.$this->selected.' does not exist.');
if (! $this->canExistingFileBeOverwritten()) {
$this->error('A modified index.blade.php file already exists. Use --force to overwrite.');

return 404;
}
return 409;
}

$this->line("<info>Published page</info> [<comment>$this->selected</comment>]");
Homepages::get($selected)->publish(true);

$this->line("<info>Published page</info> [<comment>$selected</comment>]");

$this->askToRebuildSite();

return Command::SUCCESS;
}

protected function parseSelection(): string
{
return $this->argument('homepage') ?? $this->parseChoiceIntoKey($this->promptForHomepage());
}

protected function promptForHomepage(): string
{
/** @var string $choice */
$choice = $this->choice(
return $this->choice(
'Which homepage do you want to publish?',
$this->formatPublishableChoices(),
0
);

return $this->parseChoiceIntoKey($choice);
}

protected function formatPublishableChoices(): array
{
$keys = [];
foreach (PublishesHomepageView::$homePages as $key => $value) {
$keys[] = "<comment>$key</comment>: {$value['description']}";
}
return $this->getTemplateOptions()->map(function (array $option, string $key): string {
return "<comment>$key</comment>: {$option['description']}";
})->values()->toArray();
}

return $keys;
protected function getTemplateOptions(): Collection
{
return Homepages::options()->map(fn (PublishableContract $page): array => $page::toArray());
}

protected function parseChoiceIntoKey(string $choice): string
{
return strstr(str_replace(['<comment>', '</comment>'], '', $choice), ':', true);
}

protected function canExistingIndexFileBeOverwritten(): bool
protected function canExistingFileBeOverwritten(): bool
{
if (! file_exists(Hyde::getBladePagePath('index.blade.php')) || $this->option('force')) {
if ($this->option('force')) {
return true;
}

return ChecksumService::checksumMatchesAny(ChecksumService::unixsumFile(
Hyde::getBladePagePath('index.blade.php')
)) || $this->option('force');
if (! file_exists(Hyde::getBladePagePath('index.blade.php'))) {
return true;
}

return $this->isTheExistingFileADefaultOne();
}

protected function askToRebuildSite(): void
protected function isTheExistingFileADefaultOne(): bool
{
if ($this->option('no-interaction')) {
return;
}

if ($this->confirm('Would you like to rebuild the site?', 'Yes')) {
$this->line('Okay, building site!');
Artisan::call('build');
$this->info('Site is built!');
} else {
$this->line('Okay, you can always run the build later!');
}
return ChecksumService::checksumMatchesAny(ChecksumService::unixsumFile(
Hyde::getBladePagePath('index.blade.php')
));
}
}
25 changes: 25 additions & 0 deletions packages/framework/src/Console/Concerns/AsksToRebuildSite.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Hyde\Console\Concerns;

use Illuminate\Support\Facades\Artisan;

trait AsksToRebuildSite
{
protected function askToRebuildSite(): void
{
if ($this->option('no-interaction')) {
return;
}

if ($this->confirm('Would you like to rebuild the site?', 'Yes')) {
$this->line('Okay, building site!');
Artisan::call('build');
$this->info('Site is built!');
} else {
$this->line('Okay, you can always run the build later!');
}
}
}
52 changes: 0 additions & 52 deletions packages/framework/src/Framework/Actions/PublishesHomepageView.php

This file was deleted.

63 changes: 63 additions & 0 deletions packages/framework/src/Framework/Features/Templates/Homepages.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

declare(strict_types=1);

namespace Hyde\Framework\Features\Templates;

use Illuminate\Support\Collection;

/** @internal */
final class Homepages
{
public static function options(): Collection
{
return new Collection([
'welcome' => self::welcome(),
'posts' => self::posts(),
'blank' => self::blank(),
]);
}

public static function exists(string $page): bool
{
return self::options()->has($page);
}

public static function get(string $page): ?PublishableContract
{
return self::options()->get($page);
}

public static function welcome(): PublishableContract
{
return new class extends PublishableView
{
protected static string $title = 'Welcome';
protected static string $desc = 'The default welcome page.';
protected static string $path = 'resources/views/homepages/welcome.blade.php';
protected static ?string $outputPath = 'index.blade.php';
};
}

public static function posts(): PublishableContract
{
return new class extends PublishableView
{
protected static string $title = 'Posts Feed';
protected static string $desc = 'A feed of your latest posts. Perfect for a blog site!';
protected static string $path = 'resources/views/homepages/post-feed.blade.php';
protected static ?string $outputPath = 'index.blade.php';
};
}

public static function blank(): PublishableContract
{
return new class extends PublishableView
{
protected static string $title = 'Blank Starter';
protected static string $desc = 'A blank Blade template with just the base layout.';
protected static string $path = 'resources/views/homepages/blank.blade.php';
protected static ?string $outputPath = 'index.blade.php';
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Hyde\Framework\Features\Templates;

interface PublishableContract
{
public static function publish(bool $force = false): bool;

public static function getTitle(): string;

public static function getDescription(): string;

public static function getOutputPath(): string;

public static function toArray(): array;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);

namespace Hyde\Framework\Features\Templates;

use Hyde\Hyde;

abstract class PublishableView implements PublishableContract
{
protected static string $title;
protected static string $desc;
protected static string $path;
protected static ?string $outputPath;

public static function publish(bool $force = false): bool
{
$path = static::getOutputPath();

if (file_exists($path) && ! $force) {
return false;
}

return copy(static::getSourcePath(), $path);
}

public static function getTitle(): string
{
return static::$title;
}

public static function getDescription(): string
{
return static::$desc;
}

public static function getOutputPath(): string
{
// All publishable views at this time are Blade templates so to
// reduce premature complexity we just use the Blade paths here.

return Hyde::getBladePagePath(static::$outputPath ?? static::$path);
}

protected static function getSourcePath(): string
{
return Hyde::vendorPath(static::$path);
}

public static function toArray(): array
{
return [
'name' => static::getTitle(),
'description' => static::getDescription(),
];
}
}
Loading

0 comments on commit 69e5ba3

Please sign in to comment.