Skip to content

Commit d4388f0

Browse files
authored
Merge pull request #8119 from kenjis/feat-generator-multiple-views
feat: one generator command could have multiple views
2 parents ea357ba + 2534fdc commit d4388f0

14 files changed

+152
-36
lines changed

app/Config/Generators.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ class Generators extends BaseConfig
2323
*
2424
* YOU HAVE BEEN WARNED!
2525
*
26-
* @var array<string, string>
26+
* @var array<string, array<string, string>|string>
2727
*/
2828
public array $views = [
29-
'make:cell' => 'CodeIgniter\Commands\Generators\Views\cell.tpl.php',
30-
'make:cell_view' => 'CodeIgniter\Commands\Generators\Views\cell_view.tpl.php',
29+
'make:cell' => [
30+
'class' => 'CodeIgniter\Commands\Generators\Views\cell.tpl.php',
31+
'view' => 'CodeIgniter\Commands\Generators\Views\cell_view.tpl.php',
32+
],
3133
'make:command' => 'CodeIgniter\Commands\Generators\Views\command.tpl.php',
3234
'make:config' => 'CodeIgniter\Commands\Generators\Views\config.tpl.php',
3335
'make:controller' => 'CodeIgniter\Commands\Generators\Views\controller.tpl.php',

system/CLI/GeneratorTrait.php

Lines changed: 127 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,15 @@ trait GeneratorTrait
3636
protected $directory;
3737

3838
/**
39-
* View template name
39+
* (Optional) View template path
40+
*
41+
* We use special namespaced paths like:
42+
* `CodeIgniter\Commands\Generators\Views\cell.tpl.php`.
43+
*/
44+
protected ?string $templatePath = null;
45+
46+
/**
47+
* View template name for fallback
4048
*
4149
* @var string
4250
*/
@@ -118,6 +126,8 @@ protected function generateClass(array $params)
118126

119127
/**
120128
* Generate a view file from an existing template.
129+
*
130+
* @param string $view namespaced view name that is generated
121131
*/
122132
protected function generateView(string $view, array $params)
123133
{
@@ -135,6 +145,8 @@ protected function generateView(string $view, array $params)
135145

136146
/**
137147
* Handles writing the file to disk, and all of the safety checks around that.
148+
*
149+
* @param string $target file path
138150
*/
139151
private function generateFile(string $target, string $content): void
140152
{
@@ -143,7 +155,13 @@ private function generateFile(string $target, string $content): void
143155
CLI::write(lang('CLI.generator.usingCINamespace'), 'yellow');
144156
CLI::newLine();
145157

146-
if (CLI::prompt('Are you sure you want to continue?', ['y', 'n'], 'required') === 'n') {
158+
if (
159+
CLI::prompt(
160+
'Are you sure you want to continue?',
161+
['y', 'n'],
162+
'required'
163+
) === 'n'
164+
) {
147165
CLI::newLine();
148166
CLI::write(lang('CLI.generator.cancelOperation'), 'yellow');
149167
CLI::newLine();
@@ -160,7 +178,11 @@ private function generateFile(string $target, string $content): void
160178
// Overwriting files unknowingly is a serious annoyance, So we'll check if
161179
// we are duplicating things, If 'force' option is not supplied, we bail.
162180
if (! $this->getOption('force') && $isFile) {
163-
CLI::error(lang('CLI.generator.fileExist', [clean_path($target)]), 'light_gray', 'red');
181+
CLI::error(
182+
lang('CLI.generator.fileExist', [clean_path($target)]),
183+
'light_gray',
184+
'red'
185+
);
164186
CLI::newLine();
165187

166188
return;
@@ -179,26 +201,40 @@ private function generateFile(string $target, string $content): void
179201
// contents from the template, and then we'll do the necessary replacements.
180202
if (! write_file($target, $content)) {
181203
// @codeCoverageIgnoreStart
182-
CLI::error(lang('CLI.generator.fileError', [clean_path($target)]), 'light_gray', 'red');
204+
CLI::error(
205+
lang('CLI.generator.fileError', [clean_path($target)]),
206+
'light_gray',
207+
'red'
208+
);
183209
CLI::newLine();
184210

185211
return;
186212
// @codeCoverageIgnoreEnd
187213
}
188214

189215
if ($this->getOption('force') && $isFile) {
190-
CLI::write(lang('CLI.generator.fileOverwrite', [clean_path($target)]), 'yellow');
216+
CLI::write(
217+
lang('CLI.generator.fileOverwrite', [clean_path($target)]),
218+
'yellow'
219+
);
191220
CLI::newLine();
192221

193222
return;
194223
}
195224

196-
CLI::write(lang('CLI.generator.fileCreate', [clean_path($target)]), 'green');
225+
CLI::write(
226+
lang('CLI.generator.fileCreate', [clean_path($target)]),
227+
'green'
228+
);
197229
CLI::newLine();
198230
}
199231

200232
/**
201233
* Prepare options and do the necessary replacements.
234+
*
235+
* @param string $class namespaced classname or namespaced view.
236+
*
237+
* @return string generated file content
202238
*/
203239
protected function prepare(string $class): string
204240
{
@@ -244,15 +280,34 @@ protected function qualifyClassName(): string
244280
$class = $matches[1] . ucfirst($matches[2]);
245281
}
246282

247-
if ($this->enabledSuffixing && $this->getOption('suffix') && preg_match($pattern, $class) !== 1) {
283+
if (
284+
$this->enabledSuffixing && $this->getOption('suffix')
285+
&& preg_match($pattern, $class) !== 1
286+
) {
248287
$class .= ucfirst($component);
249288
}
250289

251290
// Trims input, normalize separators, and ensure that all paths are in Pascalcase.
252-
$class = ltrim(implode('\\', array_map('pascalize', explode('\\', str_replace('/', '\\', trim($class))))), '\\/');
291+
$class = ltrim(
292+
implode(
293+
'\\',
294+
array_map(
295+
'pascalize',
296+
explode('\\', str_replace('/', '\\', trim($class)))
297+
)
298+
),
299+
'\\/'
300+
);
253301

254302
// Gets the namespace from input. Don't forget the ending backslash!
255-
$namespace = trim(str_replace('/', '\\', $this->getOption('namespace') ?? APP_NAMESPACE), '\\') . '\\';
303+
$namespace = trim(
304+
str_replace(
305+
'/',
306+
'\\',
307+
$this->getOption('namespace') ?? APP_NAMESPACE
308+
),
309+
'\\'
310+
) . '\\';
256311

257312
if (strncmp($class, $namespace, strlen($namespace)) === 0) {
258313
return $class; // @codeCoverageIgnore
@@ -268,21 +323,41 @@ protected function qualifyClassName(): string
268323
protected function renderTemplate(array $data = []): string
269324
{
270325
try {
271-
return view(config(Generators::class)->views[$this->name], $data, ['debug' => false]);
326+
$template = $this->templatePath ?? config(Generators::class)->views[$this->name];
327+
328+
return view($template, $data, ['debug' => false]);
272329
} catch (Throwable $e) {
273330
log_message('error', (string) $e);
274331

275-
return view("CodeIgniter\\Commands\\Generators\\Views\\{$this->template}", $data, ['debug' => false]);
332+
return view(
333+
"CodeIgniter\\Commands\\Generators\\Views\\{$this->template}",
334+
$data,
335+
['debug' => false]
336+
);
276337
}
277338
}
278339

279340
/**
280341
* Performs pseudo-variables contained within view file.
342+
*
343+
* @param string $class namespaced classname or namespaced view.
344+
*
345+
* @return string generated file content
281346
*/
282-
protected function parseTemplate(string $class, array $search = [], array $replace = [], array $data = []): string
283-
{
347+
protected function parseTemplate(
348+
string $class,
349+
array $search = [],
350+
array $replace = [],
351+
array $data = []
352+
): string {
284353
// Retrieves the namespace part from the fully qualified class name.
285-
$namespace = trim(implode('\\', array_slice(explode('\\', $class), 0, -1)), '\\');
354+
$namespace = trim(
355+
implode(
356+
'\\',
357+
array_slice(explode('\\', $class), 0, -1)
358+
),
359+
'\\'
360+
);
286361
$search[] = '<@php';
287362
$search[] = '{namespace}';
288363
$search[] = '{class}';
@@ -302,7 +377,14 @@ protected function buildContent(string $class): string
302377
{
303378
$template = $this->prepare($class);
304379

305-
if ($this->sortImports && preg_match('/(?P<imports>(?:^use [^;]+;$\n?)+)/m', $template, $match)) {
380+
if (
381+
$this->sortImports
382+
&& preg_match(
383+
'/(?P<imports>(?:^use [^;]+;$\n?)+)/m',
384+
$template,
385+
$match
386+
)
387+
) {
306388
$imports = explode("\n", trim($match['imports']));
307389
sort($imports);
308390

@@ -314,25 +396,50 @@ protected function buildContent(string $class): string
314396

315397
/**
316398
* Builds the file path from the class name.
399+
*
400+
* @param string $class namespaced classname or namespaced view.
317401
*/
318402
protected function buildPath(string $class): string
319403
{
320-
$namespace = trim(str_replace('/', '\\', $this->getOption('namespace') ?? APP_NAMESPACE), '\\');
404+
$namespace = trim(
405+
str_replace(
406+
'/',
407+
'\\',
408+
$this->getOption('namespace') ?? APP_NAMESPACE
409+
),
410+
'\\'
411+
);
321412

322413
// Check if the namespace is actually defined and we are not just typing gibberish.
323414
$base = Services::autoloader()->getNamespace($namespace);
324415

325416
if (! $base = reset($base)) {
326-
CLI::error(lang('CLI.namespaceNotDefined', [$namespace]), 'light_gray', 'red');
417+
CLI::error(
418+
lang('CLI.namespaceNotDefined', [$namespace]),
419+
'light_gray',
420+
'red'
421+
);
327422
CLI::newLine();
328423

329424
return '';
330425
}
331426

332427
$base = realpath($base) ?: $base;
333-
$file = $base . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, trim(str_replace($namespace . '\\', '', $class), '\\')) . '.php';
334-
335-
return implode(DIRECTORY_SEPARATOR, array_slice(explode(DIRECTORY_SEPARATOR, $file), 0, -1)) . DIRECTORY_SEPARATOR . $this->basename($file);
428+
$file = $base . DIRECTORY_SEPARATOR
429+
. str_replace(
430+
'\\',
431+
DIRECTORY_SEPARATOR,
432+
trim(str_replace($namespace . '\\', '', $class), '\\')
433+
) . '.php';
434+
435+
return implode(
436+
DIRECTORY_SEPARATOR,
437+
array_slice(
438+
explode(DIRECTORY_SEPARATOR, $file),
439+
0,
440+
-1
441+
)
442+
) . DIRECTORY_SEPARATOR . $this->basename($file);
336443
}
337444

338445
/**

system/Commands/Generators/CellGenerator.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use CodeIgniter\CLI\BaseCommand;
1515
use CodeIgniter\CLI\GeneratorTrait;
16+
use Config\Generators;
1617

1718
/**
1819
* Generates a skeleton Cell and its view.
@@ -78,17 +79,23 @@ public function run(array $params)
7879

7980
$params = array_merge($params, ['suffix' => null]);
8081

82+
$this->templatePath = config(Generators::class)->views[$this->name]['class'];
8183
$this->template = 'cell.tpl.php';
8284
$this->classNameLang = 'CLI.generator.className.cell';
85+
8386
$this->generateClass($params);
8487

85-
$this->name = 'make:cell_view';
88+
$this->templatePath = config(Generators::class)->views[$this->name]['view'];
8689
$this->template = 'cell_view.tpl.php';
8790
$this->classNameLang = 'CLI.generator.viewName.cell';
8891

8992
$className = $this->qualifyClassName();
9093
$viewName = decamelize(class_basename($className));
91-
$viewName = preg_replace('/([a-z][a-z0-9_\/\\\\]+)(_cell)$/i', '$1', $viewName) ?? $viewName;
94+
$viewName = preg_replace(
95+
'/([a-z][a-z0-9_\/\\\\]+)(_cell)$/i',
96+
'$1',
97+
$viewName
98+
) ?? $viewName;
9299
$namespace = substr($className, 0, strrpos($className, '\\') + 1);
93100

94101
$this->generateView($namespace . $viewName, $params);

system/Commands/Generators/CommandGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public function run(array $params)
8383
$this->template = 'command.tpl.php';
8484

8585
$this->classNameLang = 'CLI.generator.className.command';
86-
$this->execute($params);
86+
$this->generateClass($params);
8787
}
8888

8989
/**

system/Commands/Generators/ConfigGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public function run(array $params)
7979
$this->template = 'config.tpl.php';
8080

8181
$this->classNameLang = 'CLI.generator.className.config';
82-
$this->execute($params);
82+
$this->generateClass($params);
8383
}
8484

8585
/**

system/Commands/Generators/ControllerGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public function run(array $params)
8585
$this->template = 'controller.tpl.php';
8686

8787
$this->classNameLang = 'CLI.generator.className.controller';
88-
$this->execute($params);
88+
$this->generateClass($params);
8989
}
9090

9191
/**

system/Commands/Generators/EntityGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,6 @@ public function run(array $params)
7979
$this->template = 'entity.tpl.php';
8080

8181
$this->classNameLang = 'CLI.generator.className.entity';
82-
$this->execute($params);
82+
$this->generateClass($params);
8383
}
8484
}

system/Commands/Generators/FilterGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,6 @@ public function run(array $params)
7979
$this->template = 'filter.tpl.php';
8080

8181
$this->classNameLang = 'CLI.generator.className.filter';
82-
$this->execute($params);
82+
$this->generateClass($params);
8383
}
8484
}

system/Commands/Generators/MigrationGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public function run(array $params)
9090
}
9191

9292
$this->classNameLang = 'CLI.generator.className.migration';
93-
$this->execute($params);
93+
$this->generateClass($params);
9494
}
9595

9696
/**

system/Commands/Generators/ModelGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public function run(array $params)
8383
$this->template = 'model.tpl.php';
8484

8585
$this->classNameLang = 'CLI.generator.className.model';
86-
$this->execute($params);
86+
$this->generateClass($params);
8787
}
8888

8989
/**

system/Commands/Generators/SeederGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,6 @@ public function run(array $params)
7979
$this->template = 'seeder.tpl.php';
8080

8181
$this->classNameLang = 'CLI.generator.className.seeder';
82-
$this->execute($params);
82+
$this->generateClass($params);
8383
}
8484
}

system/Commands/Generators/ValidationGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,6 @@ public function run(array $params)
7979
$this->template = 'validation.tpl.php';
8080

8181
$this->classNameLang = 'CLI.generator.className.validation';
82-
$this->execute($params);
82+
$this->generateClass($params);
8383
}
8484
}

0 commit comments

Comments
 (0)