Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.x] Allow developers to extend InstallEloquentDriver command #11426

Draft
wants to merge 4 commits into
base: 5.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions src/Console/Commands/Concerns/RunsArtisanCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Statamic\Console\Commands\Concerns;

use Illuminate\Contracts\Process\ProcessResult;
use Illuminate\Support\Facades\Process;
use Statamic\Support\Str;
use Symfony\Component\Process\PhpExecutableFinder;

use function Laravel\Prompts\error;

trait RunsArtisanCommand
{
protected function runArtisanCommand(string $command, bool $writeOutput = false): ProcessResult
{
$components = array_merge(
[
(new PhpExecutableFinder())->find(false) ?: 'php',
defined('ARTISAN_BINARY') ? ARTISAN_BINARY : 'artisan',
],
explode(' ', $command)
);

$result = Process::forever()->run($components, function ($type, $line) use ($writeOutput) {
if ($writeOutput) {
$this->output->write($line);
}
});

// We're doing this instead of ->throw() so we can control the output of errors.
if ($result->failed()) {
if (Str::of($result->output())->contains('Unknown database')) {
error('The database does not exist. Please create it before running this command.');
exit(1);
}

error('Failed to run command: '.$command);
$this->output->write($result->output());
exit(1);
}

return $result;
}
}
43 changes: 43 additions & 0 deletions src/Console/Commands/Eloquent/InstallEloquentCollectionTrees.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Statamic\Console\Commands\Eloquent;

use function Laravel\Prompts\spin;

class InstallEloquentCollectionTrees extends InstallEloquentRepository
{
protected $signature = 'eloquent:install-collection-trees
{ --import : Whether existing data should be imported }
{ --without-messages : Disables output messages }';

protected $handle = 'collection_trees';

public function handle()
{
spin(
callback: function () {
$this->runArtisanCommand('vendor:publish --tag=statamic-eloquent-navigation-tree-migrations');
$this->runArtisanCommand('migrate');

$this->switchToEloquentDriver('collection_trees');
},
message: 'Migrating collection trees...'
);

$this->infoMessage('Configured collection trees');

if ($this->shouldImport('collection trees')) {
spin(
callback: fn () => $this->runArtisanCommand('statamic:eloquent:import-collections --force --only-collection-trees'),
message: 'Importing existing collections...'
);

$this->infoMessage('Imported existing collection trees');
}
}

public function hasBeenMigrated(): bool
{
return config('statamic.eloquent-driver.collection_trees.driver') === 'eloquent';
}
}
43 changes: 43 additions & 0 deletions src/Console/Commands/Eloquent/InstallEloquentCollections.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Statamic\Console\Commands\Eloquent;

use function Laravel\Prompts\spin;

class InstallEloquentCollections extends InstallEloquentRepository
{
protected $signature = 'eloquent:install-collections
{ --import : Whether existing data should be imported }
{ --without-messages : Disables output messages }';

protected $handle = 'collections';

public function handle()
{
spin(
callback: function () {
$this->runArtisanCommand('vendor:publish --tag=statamic-eloquent-collection-migrations');
$this->runArtisanCommand('migrate');

$this->switchToEloquentDriver('collections');
},
message: 'Migrating collections...'
);

$this->infoMessage('Configured collections');

if ($this->shouldImport('collections')) {
spin(
callback: fn () => $this->runArtisanCommand('statamic:eloquent:import-collections --force --only-collections'),
message: 'Importing existing collections...'
);

$this->infoMessage('Imported existing collections');
}
}

public function hasBeenMigrated(): bool
{
return config('statamic.eloquent-driver.collections.driver') === 'eloquent';
}
}
69 changes: 69 additions & 0 deletions src/Console/Commands/Eloquent/InstallEloquentEntries.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

namespace Statamic\Console\Commands\Eloquent;

use Statamic\Facades\File;
use Statamic\Support\Str;

use function Laravel\Prompts\spin;

class InstallEloquentEntries extends InstallEloquentRepository
{
protected $signature = 'eloquent:install-entries
{ --import : Whether existing data should be imported }
{ --without-messages : Disables output messages }';

protected $handle = 'entries';

public function handle()
{
$shouldImportEntries = $this->shouldImport('entries');

spin(
callback: function () use ($shouldImportEntries) {
$this->switchToEloquentDriver('entries');

if ($shouldImportEntries) {
File::put(
config_path('statamic/eloquent-driver.php'),
Str::of(File::get(config_path('statamic/eloquent-driver.php')))
->replace("'model' => \Statamic\Eloquent\Entries\EntryModel::class", "'model' => \Statamic\Eloquent\Entries\UuidEntryModel::class")
->__toString()
);

$this->runArtisanCommand('vendor:publish --tag=statamic-eloquent-entries-table-with-string-ids');
$this->runArtisanCommand('migrate');

$this->runArtisanCommand('statamic:eloquent:import-entries');

return;
}

if (File::exists(base_path('content/collections/pages/home.md'))) {
File::delete(base_path('content/collections/pages/home.md'));
}

if (File::exists(base_path('content/trees/collections/pages.yaml'))) {
File::put(base_path('content/trees/collections/pages.yaml'), 'tree: {}');
}

$this->runArtisanCommand('vendor:publish --tag=statamic-eloquent-entries-table');
$this->runArtisanCommand('migrate');
},
message: $shouldImportEntries
? 'Migrating entries...'
: 'Migrating and importing entries...'
);

$this->infoMessage(
$shouldImportEntries
? 'Configured & imported existing entries'
: 'Configured entries'
);
}

public function hasBeenMigrated(): bool
{
return config('statamic.eloquent-driver.entries.driver') === 'eloquent';
}
}
56 changes: 56 additions & 0 deletions src/Console/Commands/Eloquent/InstallEloquentRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace Statamic\Console\Commands\Eloquent;

use Illuminate\Console\Command;
use Statamic\Console\Commands\Concerns\RunsArtisanCommand;
use Statamic\Console\EnhancesCommands;
use Statamic\Console\RunsInPlease;
use Statamic\Facades\File;
use Statamic\Support\Str;

use function Laravel\Prompts\confirm;

abstract class InstallEloquentRepository extends Command
{
use EnhancesCommands, RunsArtisanCommand, RunsInPlease;

abstract public function hasBeenMigrated(): bool;

public function repoHandle(): string
{
return $this->handle;
}

public function repoTitle(): string
{
return $this->title ?? Str::of($this->repoHandle())->replace('_', ' ')->title();
}

protected function switchToEloquentDriver(): void
{
File::put(
config_path('statamic/eloquent-driver.php'),
Str::of(File::get(config_path('statamic/eloquent-driver.php')))
->replace(
"'{$this->repoHandle()}' => [\n 'driver' => 'file'",
"'{$this->repoHandle()}' => [\n 'driver' => 'eloquent'"
)
->__toString()
);
}

protected function shouldImport(string $repository): bool
{
return $this->option('import') || confirm("Would you like to import existing {$repository}?");
}

protected function infoMessage(string $message): void
{
if ($this->option('without-messages')) {
return;
}

$this->components->info($message);
}
}
Loading
Loading