Skip to content
Merged
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
3 changes: 3 additions & 0 deletions phpstan.dist.neon
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ parameters:
ignoreErrors:
-
identifier: missingType.generics
-
identifier: trait.unused
path: system/CLI/GeneratorTrait.php
checkMissingCallableSignature: true
treatPhpDocTypesAsCertain: false
strictRules:
Expand Down
193 changes: 98 additions & 95 deletions system/Commands/Generators/ScaffoldGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,117 +13,120 @@

namespace CodeIgniter\Commands\Generators;

use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;
use CodeIgniter\CLI\GeneratorTrait;

/**
* Generates a complete set of scaffold files.
*/
class ScaffoldGenerator extends BaseCommand
use CodeIgniter\CLI\AbstractCommand;
use CodeIgniter\CLI\Attributes\Command;
use CodeIgniter\CLI\Input\Argument;
use CodeIgniter\CLI\Input\Option;
use CodeIgniter\CLI\PromptsForMissingInputInterface;

#[Command(name: 'make:scaffold', description: 'Generates a complete set of scaffold files.', group: 'Generators')]
class ScaffoldGenerator extends AbstractCommand implements PromptsForMissingInputInterface
{
use GeneratorTrait;
protected function configure(): void
{
$this
->addArgument(new Argument(name: 'name', description: 'The class name.', required: true))
->addOption(new Option(
name: 'bare',
shortcut: 'b',
description: 'Pass "--bare" to the controller.',
))
->addOption(new Option(
name: 'restful',
description: 'Pass "--restful" to the controller.',
acceptsValue: true,
valueLabel: 'type',
))
->addOption(new Option(
name: 'table',
shortcut: 't',
description: 'Pass "--table" to the model.',
acceptsValue: true,
valueLabel: 'name',
))
->addOption(new Option(
name: 'dbgroup',
shortcut: 'g',
description: 'Pass "--dbgroup" to the model.',
acceptsValue: true,
valueLabel: 'group',
))
->addOption(new Option(
name: 'return',
description: 'Pass "--return" to the model.',
acceptsValue: true,
valueLabel: 'type',
))
->addOption(new Option(
name: 'namespace',
shortcut: 'n',
description: 'Set the root namespace.',
requiresValue: true,
default: APP_NAMESPACE,
))
->addOption(new Option(
name: 'suffix',
shortcut: 's',
description: 'Append the component suffix to each class name.',
))
->addOption(new Option(
name: 'force',
shortcut: 'f',
description: 'Force overwrite existing files.',
));
}

/**
* The Command's Group
*
* @var string
*/
protected $group = 'Generators';
protected function getArgumentPromptLabels(): array
{
return ['name' => lang('CLI.generator.className.default')];
}

/**
* The Command's Name
*
* @var string
*/
protected $name = 'make:scaffold';
protected function execute(array $arguments, array $options): int
{
$name = [$arguments['name']];
$shared = ['namespace' => $options['namespace']];

/**
* The Command's Description
*
* @var string
*/
protected $description = 'Generates a complete set of scaffold files.';
if ($options['suffix'] === true) {
$shared['suffix'] = null;
}

/**
* The Command's Usage
*
* @var string
*/
protected $usage = 'make:scaffold <name> [options]';
$forced = $options['force'] === true ? $shared + ['force' => null] : $shared;

/**
* The Command's Arguments
*
* @var array<string, string>
*/
protected $arguments = [
'name' => 'The class name',
];
return $this->call('make:controller', $name, $this->getControllerOptions($options) + $forced)
| $this->call('make:model', $name, $this->getModelOptions($options) + $forced)
| $this->call('make:migration', $name, $shared)
| $this->call('make:seeder', $name, $forced);
}

/**
* The Command's Options
* @param array<string, mixed> $options
*
* @var array<string, string>
*/
protected $options = [
'--bare' => 'Add the "--bare" option to controller component.',
'--restful' => 'Add the "--restful" option to controller component.',
'--table' => 'Add the "--table" option to the model component.',
'--dbgroup' => 'Add the "--dbgroup" option to model component.',
'--return' => 'Add the "--return" option to the model component.',
'--namespace' => 'Set root namespace. Default: "APP_NAMESPACE".',
'--suffix' => 'Append the component title to the class name.',
'--force' => 'Force overwrite existing file.',
];

/**
* Actually execute a command.
* @return array<string, string|null>
*/
public function run(array $params)
private function getControllerOptions(array $options): array
{
$this->params = $params;

$options = [];

if ($this->getOption('namespace')) {
$options['namespace'] = $this->getOption('namespace');
if ($options['bare'] === true) {
return ['bare' => null];
}

if ($this->getOption('suffix')) {
$options['suffix'] = null;
if (! $this->hasUnboundOption('restful')) {
return [];
}

if ($this->getOption('force')) {
$options['force'] = null;
}

$controllerOpts = [];

if ($this->getOption('bare')) {
$controllerOpts['bare'] = null;
} elseif ($this->getOption('restful')) {
$restful = $this->getOption('restful');

$controllerOpts['restful'] = is_string($restful) ? $restful : null;
}
return ['restful' => is_string($options['restful']) ? $options['restful'] : null];
}

$modelOpts = array_filter([
'table' => $this->getOption('table'),
'dbgroup' => $this->getOption('dbgroup'),
'return' => $this->getOption('return'),
/**
* @param array<string, mixed> $options
*
* @return array<string, string>
*/
private function getModelOptions(array $options): array
{
return array_filter([
'table' => $options['table'],
'dbgroup' => $options['dbgroup'],
'return' => $options['return'],
], is_string(...));

$class = $params[0] ?? CLI::getSegment(2);

// Call those commands!
$exit1 = $this->call('make:controller', array_merge([$class], $controllerOpts, $options));
$exit2 = $this->call('make:model', array_merge([$class], $modelOpts, $options));
$exit3 = $this->call('make:migration', array_merge([$class], array_diff_key($options, ['force' => null])));
$exit4 = $this->call('make:seeder', array_merge([$class], $options));

assert(is_int($exit1) && is_int($exit2) && is_int($exit3) && is_int($exit4));

return $exit1 | $exit2 | $exit3 | $exit4;
}
}
Loading
Loading