Files
trf_certest/vendor/vanguardapp/plugins/src/Console/Commands/GeneratePluginCommand.php
T
2025-03-28 08:52:46 +01:00

190 lines
5.4 KiB
PHP

<?php
namespace Vanguard\Plugins\Console\Commands;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;
class GeneratePluginCommand extends PluginCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'vanguard:make-plugin';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Scaffold all the necessary files for the new plugin.';
/**
* Execute the console command.
*
* @throws FileNotFoundException
*/
public function handle()
{
if ($this->pluginExists($this->pluginPath())) {
$this->error('Plugin already exists!');
return;
}
$this->warn('Generating plugin folder structure...');
$this->generateFolderStructure();
$this->generateFiles();
$this->info('Plugin folder structure generated successfully.');
$this->warn('Installing plugin as a local composer dependency...');
$this->updateApplicationComposerFile();
$this->installPlugin();
$this->info('Plugin installed successfully.');
}
/**
* Generate the plugin folder structure.
*/
private function generateFolderStructure(): void
{
$pluginPath = $this->pluginPath();
foreach ($this->getFolders() as $folder) {
$this->makeDirectory($pluginPath."/{$folder}");
}
}
/**
* Get the list of folders to create.
*/
protected function getFolders(): array
{
return [
'database/factories',
'database/migrations',
'database/seeds',
'resources/views',
'routes',
'src/Http/Controllers/Api',
'src/Http/Controllers/Web',
'src/Http/Requests',
'tests',
];
}
/**
* Generate necessary plugin files.
*
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
private function generateFiles(): void
{
$pluginPath = $this->pluginPath();
foreach ($this->getFiles() as $stubPath => $filePath) {
$this->makeDirectory($pluginPath."/{$filePath}");
$stub = $this->files->get(__DIR__.'/stubs/'.$stubPath);
$stub = $this->replacePlaceholders($stub);
$this->files->put($pluginPath."/{$filePath}", $stub);
}
}
/**
* Get the list of files that should be created for the plugin.
*/
protected function getFiles(): array
{
return [
'routes/web.stub' => 'routes/web.php',
'routes/api.stub' => 'routes/api.php',
'views/index.stub' => 'resources/views/index.blade.php',
'config.stub' => 'config/config.php',
'composer.stub' => 'composer.json',
'assets/js/app.stub' => 'resources/assets/js/app.js',
'assets/sass/app.stub' => 'resources/assets/sass/app.scss',
'webpack.stub' => 'webpack.mix.js',
'package.stub' => 'package.json',
'unit-test.stub' => 'tests/Unit/ExampleTest.php',
'feature-test.stub' => 'tests/Feature/FeatureTest.php',
'gitignore.stub' => '.gitignore',
'plugin.stub' => 'src/'.$this->studlyName().'.php',
'controller.stub' => 'src/Http/Controllers/Web/'.$this->studlyName().'Controller.php',
];
}
/**
* Replace placeholders within the stub files.
*
* @return mixed
*/
private function replacePlaceholders(string $stub)
{
return str_replace(
[
'$ROOT_NAMESPACE$',
'$PLUGIN_NAMESPACE$',
'$VENDOR$',
'$AUTHOR_NAME$',
'$AUTHOR_EMAIL$',
'$SNAKE_NAME$',
'$STUDLY_NAME$',
],
[
$this->rootNamespace(),
$this->pluginNamespace(),
config('plugins.composer.vendor'),
config('plugins.composer.author.name'),
config('plugins.composer.author.email'),
$this->snakeName(),
$this->studlyName(),
],
$stub
);
}
/**
* Update the main application composer file to include the
* newly generated plugin.
*
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
private function updateApplicationComposerFile(): void
{
$composer = json_decode($this->files->get(base_path('composer.json')), true);
$composer['repositories'][] = [
'type' => 'path',
'url' => './plugins/'.$this->studlyName(),
];
$this->files->put(
base_path('composer.json'),
json_encode($composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
);
}
/**
* Install the plugin via composer.
*/
private function installPlugin(): void
{
$pluginFullName = sprintf('%s/%s', config('plugins.composer.vendor'), $this->snakeName());
$command = Process::fromShellCommandline("composer require {$pluginFullName} \"*\"");
$command->setWorkingDirectory(base_path());
$command->run();
if (! $command->isSuccessful()) {
throw new ProcessFailedException($command);
}
}
}