Skip to content

Commit 849a589

Browse files
committed
refactor: migrate make:controller to AbstractGeneratorCommand
1 parent ccf5fe2 commit 849a589

9 files changed

Lines changed: 196 additions & 160 deletions

File tree

‎system/CLI/AbstractGeneratorCommand.php‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ protected function configure(): void
8080

8181
protected function provideDefaultOptions(): void
8282
{
83-
parent::provideDefaultOptions();
84-
8583
$this->provideGeneratorOptions();
84+
85+
parent::provideDefaultOptions();
8686
}
8787

8888
/**

‎system/Commands/Generators/ControllerGenerator.php‎

Lines changed: 75 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -13,126 +13,103 @@
1313

1414
namespace CodeIgniter\Commands\Generators;
1515

16-
use CodeIgniter\CLI\BaseCommand;
16+
use CodeIgniter\CLI\AbstractGeneratorCommand;
17+
use CodeIgniter\CLI\Attributes\Command;
18+
use CodeIgniter\CLI\Attributes\GeneratorCommand;
1719
use CodeIgniter\CLI\CLI;
18-
use CodeIgniter\CLI\GeneratorTrait;
20+
use CodeIgniter\CLI\Input\Option;
1921
use CodeIgniter\Controller;
2022
use CodeIgniter\RESTful\ResourceController;
2123
use CodeIgniter\RESTful\ResourcePresenter;
2224

23-
/**
24-
* Generates a skeleton controller file.
25-
*/
26-
class ControllerGenerator extends BaseCommand
25+
#[Command(name: 'make:controller', description: 'Generates a new controller file.', group: 'Generators')]
26+
#[GeneratorCommand(
27+
component: 'Controller',
28+
template: 'controller.tpl.php',
29+
directory: 'Controllers',
30+
classNameLang: 'CLI.generator.className.controller',
31+
)]
32+
class ControllerGenerator extends AbstractGeneratorCommand
2733
{
28-
use GeneratorTrait;
34+
protected function configure(): void
35+
{
36+
parent::configure();
37+
38+
$this
39+
->addOption(new Option(
40+
name: 'bare',
41+
shortcut: 'b',
42+
description: 'Extend CodeIgniter\Controller instead of BaseController.',
43+
))
44+
->addOption(new Option(
45+
name: 'restful',
46+
shortcut: 'r',
47+
description: 'Extend a RESTful resource: "controller" (default when no value is given) or "presenter".',
48+
acceptsValue: true,
49+
valueLabel: 'type',
50+
));
51+
}
2952

30-
/**
31-
* The Command's Group
32-
*
33-
* @var string
34-
*/
35-
protected $group = 'Generators';
53+
protected function interact(array &$arguments, array &$options): void
54+
{
55+
$type = $this->getUnboundOption('restful', $options);
3656

37-
/**
38-
* The Command's Name
39-
*
40-
* @var string
41-
*/
42-
protected $name = 'make:controller';
57+
if (! is_string($type) || $type === 'controller' || $type === 'presenter') {
58+
return;
59+
}
4360

44-
/**
45-
* The Command's Description
46-
*
47-
* @var string
48-
*/
49-
protected $description = 'Generates a new controller file.';
61+
$options['restful'] = CLI::prompt(lang('CLI.generator.parentClass'), ['controller', 'presenter'], 'required');
62+
}
5063

51-
/**
52-
* The Command's Usage
53-
*
54-
* @var string
55-
*/
56-
protected $usage = 'make:controller <name> [options]';
64+
protected function execute(array $arguments, array $options): int
65+
{
66+
$type = $this->getResourceType();
5767

58-
/**
59-
* The Command's Arguments
60-
*
61-
* @var array<string, string>
62-
*/
63-
protected $arguments = [
64-
'name' => 'The controller class name.',
65-
];
68+
if (! in_array($type, [null, 'controller', 'presenter'], true)) {
69+
CLI::error(lang('CLI.generator.invalidParentClass', [$type]));
6670

67-
/**
68-
* The Command's Options
69-
*
70-
* @var array<string, string>
71-
*/
72-
protected $options = [
73-
'--bare' => 'Extends from CodeIgniter\Controller instead of BaseController.',
74-
'--restful' => 'Extends from a RESTful resource, Options: [controller, presenter]. Default: "controller".',
75-
'--namespace' => 'Set root namespace. Default: "APP_NAMESPACE".',
76-
'--suffix' => 'Append the component title to the class name (e.g. User => UserController).',
77-
'--force' => 'Force overwrite existing file.',
78-
];
71+
return EXIT_ERROR;
72+
}
7973

80-
/**
81-
* Actually execute a command.
82-
*/
83-
public function run(array $params)
74+
return $this->generateClass();
75+
}
76+
77+
protected function getReplacements(string $class): array
8478
{
85-
$this->component = 'Controller';
86-
$this->directory = 'Controllers';
87-
$this->template = 'controller.tpl.php';
79+
$parent = $this->getParentClass();
8880

89-
$this->classNameLang = 'CLI.generator.className.controller';
90-
$this->generateClass($params);
81+
return ['{useStatement}' => $parent, '{extends}' => class_basename($parent)];
82+
}
83+
84+
protected function getTemplateData(string $class): array
85+
{
86+
return ['type' => $this->getValidatedOption('bare') === true ? null : $this->getResourceType()];
87+
}
9188

92-
return EXIT_SUCCESS;
89+
private function getParentClass(): string
90+
{
91+
if ($this->getValidatedOption('bare') === true) {
92+
return Controller::class;
93+
}
94+
95+
return match ($this->getResourceType()) {
96+
'controller' => ResourceController::class,
97+
'presenter' => ResourcePresenter::class,
98+
default => trim(APP_NAMESPACE, '\\') . '\\Controllers\\BaseController',
99+
};
93100
}
94101

95102
/**
96-
* Prepare options and do the necessary replacements.
103+
* Returns the RESTful resource type, or `null` when `--restful` was not passed.
97104
*/
98-
protected function prepare(string $class): string
105+
private function getResourceType(): ?string
99106
{
100-
$bare = $this->getOption('bare');
101-
$rest = $this->getOption('restful');
102-
103-
$useStatement = trim(APP_NAMESPACE, '\\') . '\Controllers\BaseController';
104-
$extends = 'BaseController';
105-
106-
// Gets the appropriate parent class to extend.
107-
if ($bare || $rest) {
108-
if ($bare) {
109-
$useStatement = Controller::class;
110-
$extends = 'Controller';
111-
} elseif ($rest) {
112-
$rest = is_string($rest) ? $rest : 'controller';
113-
114-
if (! in_array($rest, ['controller', 'presenter'], true)) {
115-
// @codeCoverageIgnoreStart
116-
$rest = CLI::prompt(lang('CLI.generator.parentClass'), ['controller', 'presenter'], 'required');
117-
CLI::newLine();
118-
// @codeCoverageIgnoreEnd
119-
}
120-
121-
if ($rest === 'controller') {
122-
$useStatement = ResourceController::class;
123-
$extends = 'ResourceController';
124-
} elseif ($rest === 'presenter') {
125-
$useStatement = ResourcePresenter::class;
126-
$extends = 'ResourcePresenter';
127-
}
128-
}
107+
if (! $this->hasUnboundOption('restful')) {
108+
return null;
129109
}
130110

131-
return $this->parseTemplate(
132-
$class,
133-
['{useStatement}', '{extends}'],
134-
[$useStatement, $extends],
135-
['type' => $rest],
136-
);
111+
$type = $this->getValidatedOption('restful');
112+
113+
return is_string($type) ? $type : 'controller';
137114
}
138115
}

‎system/Commands/Generators/ScaffoldGenerator.php‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ public function run(array $params)
103103
if ($this->getOption('bare')) {
104104
$controllerOpts['bare'] = null;
105105
} elseif ($this->getOption('restful')) {
106-
$controllerOpts['restful'] = $this->getOption('restful');
106+
$restful = $this->getOption('restful');
107+
108+
$controllerOpts['restful'] = is_string($restful) ? $restful : null;
107109
}
108110

109111
$modelOpts = [

‎system/Language/en/CLI.php‎

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,20 @@
3636
'transformer' => 'Transformer class name',
3737
'validation' => 'Validation class name',
3838
],
39-
'commandType' => 'Command type',
40-
'confirmContinue' => 'Are you sure you want to continue?',
41-
'databaseGroup' => 'Database group',
42-
'fileCreate' => 'File created: {0}',
43-
'fileError' => 'Error while creating file: "{0}"',
44-
'fileExist' => 'File exists: "{0}"',
45-
'fileOverwrite' => 'File overwritten: "{0}"',
46-
'invalidClassName' => 'Class name "{0}" is not valid.',
47-
'parentClass' => 'Parent class',
48-
'returnType' => 'Return type',
49-
'tableName' => 'Table name',
50-
'usingCINamespace' => 'Warning: Using the "CodeIgniter" namespace will generate the file in the system directory.',
51-
'viewName' => [
39+
'commandType' => 'Command type',
40+
'confirmContinue' => 'Are you sure you want to continue?',
41+
'databaseGroup' => 'Database group',
42+
'fileCreate' => 'File created: {0}',
43+
'fileError' => 'Error while creating file: "{0}"',
44+
'fileExist' => 'File exists: "{0}"',
45+
'fileOverwrite' => 'File overwritten: "{0}"',
46+
'invalidClassName' => 'Class name "{0}" is not valid.',
47+
'invalidParentClass' => 'Parent class "{0}" is not valid.',
48+
'parentClass' => 'Parent class',
49+
'returnType' => 'Return type',
50+
'tableName' => 'Table name',
51+
'usingCINamespace' => 'Warning: Using the "CodeIgniter" namespace will generate the file in the system directory.',
52+
'viewName' => [
5253
'cell' => 'Cell view name',
5354
],
5455
],

‎tests/system/CLI/AbstractGeneratorCommandTest.php‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,11 @@ public function testCommandDeclaresGeneratorDefinition(): void
8484
$this->assertSame(['name'], array_keys($arguments));
8585
$this->assertTrue($arguments['name']->required);
8686
$this->assertSame(
87-
['help', 'no-header', 'no-interaction', 'namespace', 'suffix', 'force'],
87+
['namespace', 'suffix', 'force', 'help', 'no-header', 'no-interaction'],
8888
array_keys($command->getOptionsDefinition()),
8989
);
9090
$this->assertSame(
91-
['h' => 'help', 'N' => 'no-interaction', 'n' => 'namespace', 's' => 'suffix', 'f' => 'force'],
91+
['n' => 'namespace', 's' => 'suffix', 'f' => 'force', 'h' => 'help', 'N' => 'no-interaction'],
9292
$command->getShortcuts(),
9393
);
9494
$this->assertSame('make:testwidget [options] [--] <name>', $command->getUsages()[0]);
@@ -99,7 +99,7 @@ public function testTrimmedCommandDeclaresReducedDefinition(): void
9999
$command = new TrimmedOptionsGeneratorCommand(new Commands());
100100

101101
$this->assertSame(
102-
['help', 'no-header', 'no-interaction', 'namespace'],
102+
['namespace', 'help', 'no-header', 'no-interaction'],
103103
array_keys($command->getOptionsDefinition()),
104104
);
105105
}

0 commit comments

Comments
 (0)