-
-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Yii\Gii\Generator\CRUD; | ||
|
||
use Yiisoft\Strings\Inflector; | ||
use Yiisoft\Strings\StringHelper; | ||
use Yiisoft\Validator\Rule\Each; | ||
use Yiisoft\Validator\Rule\Regex; | ||
use Yiisoft\Validator\Rule\Required; | ||
use Yiisoft\Yii\Gii\Generator\AbstractGeneratorCommand; | ||
use Yiisoft\Yii\Gii\Validator\ClassExistsRule; | ||
use Yiisoft\Yii\Gii\Validator\NewClassRule; | ||
use Yiisoft\Yii\Gii\Validator\TemplateRule; | ||
|
||
final class Command extends AbstractGeneratorCommand | ||
{ | ||
#[Each([ | ||
new Regex( | ||
pattern: '/^[a-z][a-z0-9]*$/', | ||
message: 'Only a-z, 0-9, dashes (-), spaces and commas are allowed.' | ||
), | ||
])] | ||
private readonly array $actions; | ||
|
||
public function __construct( | ||
#[Required] | ||
#[Regex( | ||
pattern: '/^(?:[a-z][a-z0-9]*)(?:\\\\[a-z][a-z0-9]*)*$/i', | ||
message: 'Invalid namespace' | ||
)] | ||
private readonly string $controllerNamespace = 'App\\Controller', | ||
#[Required] | ||
#[ClassExistsRule] | ||
private readonly string $model = 'App\\Model\\User', | ||
#[Required] | ||
#[Regex( | ||
pattern: '/^[A-Z][a-zA-Z0-9]*Controller$/', | ||
message: 'Only word characters are allowed, and the class name must start with a capital letter and end with "Controller".' | ||
)] | ||
#[NewClassRule] | ||
private readonly string $controllerClass = 'IndexController', | ||
/** | ||
* @var string the controller path | ||
*/ | ||
private readonly string $controllerPath = '@src/Controller', | ||
/** | ||
* @var string the controller's views path | ||
*/ | ||
private readonly string $viewsPath = '@views/', | ||
#[Regex( | ||
pattern: '/^[a-z\\\\]*$/i', | ||
message: 'Only word characters and backslashes are allowed.', | ||
skipOnEmpty: true, | ||
)] | ||
private readonly string $baseClass = '', | ||
array $actions = ['index'], | ||
#[Required(message: 'A code template must be selected.')] | ||
#[TemplateRule] | ||
protected string $template = 'default', | ||
) { | ||
parent::__construct($template); | ||
sort($actions); | ||
$this->actions = $actions; | ||
} | ||
|
||
/** | ||
* @return string the controller ID | ||
*/ | ||
public function getControllerID(): string | ||
{ | ||
$name = StringHelper::baseName($this->controllerClass); | ||
return (new Inflector())->pascalCaseToId(substr($name, 0, -10)); | ||
} | ||
|
||
public function getControllerClass(): string | ||
{ | ||
return $this->controllerClass; | ||
} | ||
|
||
public function getActions(): array | ||
{ | ||
return $this->actions; | ||
} | ||
|
||
public function getViewsPath(): string | ||
{ | ||
return $this->viewsPath; | ||
} | ||
|
||
public function getModel(): string | ||
{ | ||
return $this->model; | ||
} | ||
|
||
public function getControllerNamespace(): string | ||
{ | ||
return $this->controllerNamespace; | ||
} | ||
|
||
public function getBaseClass(): string | ||
{ | ||
return $this->baseClass; | ||
} | ||
|
||
public function getDirectory(): string | ||
{ | ||
return $this->controllerPath; | ||
} | ||
|
||
public static function getAttributeLabels(): array | ||
{ | ||
return [ | ||
'controllerNamespace' => 'Controller Namespace', | ||
'controllerClass' => 'Controller Class', | ||
'baseClass' => 'Base Class', | ||
'model' => 'Active record class', | ||
'controllerPath' => 'Controller Path', | ||
'actions' => 'Action IDs', | ||
'viewsPath' => 'Views Path', | ||
'template' => 'Action IDs', | ||
]; | ||
} | ||
|
||
public static function getHints(): array | ||
{ | ||
return [ | ||
'controllerClass' => 'This is the name of the controller class to be generated. You should | ||
provide a fully qualified namespaced class (e.g. <code>App\Controller\PostController</code>), | ||
and class name should be in CamelCase ending with the word <code>Controller</code>. Make sure the class | ||
is using the same namespace as specified by your application\'s controllerNamespace property.', | ||
'actions' => 'Provide one or multiple action IDs to generate empty action method(s) in the controller. Separate multiple action IDs with commas or spaces. | ||
Action IDs should be in lower case. For example: | ||
<ul> | ||
<li><code>index</code> generates <code>index()</code></li> | ||
<li><code>create-order</code> generates <code>createOrder()</code></li> | ||
</ul>', | ||
'viewsPath' => 'Specify the directory for storing the view scripts for the controller. You may use path alias here, e.g., | ||
<code>/var/www/app/controllers/views/order</code>, <code>@app/views/order</code>. If not set, it will default | ||
to <code>@app/views/ControllerID</code>', | ||
'baseClass' => 'This is the class that the new controller class will extend from. Please make sure the class exists and can be autoloaded.', | ||
]; | ||
} | ||
|
||
public static function getAttributes(): array | ||
{ | ||
return [ | ||
'controllerNamespace', | ||
'controllerClass', | ||
'baseClass', | ||
'model', | ||
'viewsPath', | ||
'actions', | ||
'template', | ||
'controllerPath', | ||
]; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Yii\Gii\Generator\CRUD; | ||
|
||
use InvalidArgumentException; | ||
use Yiisoft\ActiveRecord\ActiveRecordFactory; | ||
use Yiisoft\Aliases\Aliases; | ||
use Yiisoft\Validator\ValidatorInterface; | ||
use Yiisoft\Yii\Gii\Component\CodeFile\CodeFile; | ||
use Yiisoft\Yii\Gii\Generator\AbstractGenerator; | ||
use Yiisoft\Yii\Gii\GeneratorCommandInterface; | ||
use Yiisoft\Yii\Gii\ParametersProvider; | ||
|
||
/** | ||
* This generator will generate a controller and one or a few action view files. | ||
*/ | ||
final class Generator extends AbstractGenerator | ||
{ | ||
public function __construct( | ||
Aliases $aliases, | ||
ValidatorInterface $validator, | ||
ParametersProvider $parametersProvider, | ||
private ActiveRecordFactory $activeRecordFactory, | ||
) { | ||
parent::__construct($aliases, $validator, $parametersProvider); | ||
} | ||
|
||
public static function getId(): string | ||
{ | ||
return 'crud'; | ||
} | ||
|
||
public static function getName(): string | ||
{ | ||
return 'CRUD'; | ||
} | ||
|
||
public static function getDescription(): string | ||
{ | ||
return 'This generator helps you to quickly generate a new controller class with | ||
one or several controller actions and their corresponding views.'; | ||
} | ||
|
||
public function getRequiredTemplates(): array | ||
{ | ||
return [ | ||
'controller.php', | ||
'view.php', | ||
]; | ||
} | ||
|
||
public function doGenerate(GeneratorCommandInterface $command): array | ||
{ | ||
if (!$command instanceof Command) { | ||
throw new InvalidArgumentException(); | ||
} | ||
|
||
$files = []; | ||
|
||
$rootPath = $this->aliases->get('@root'); | ||
|
||
$codeFile = (new CodeFile( | ||
$this->getControllerFile($command), | ||
$this->render($command, 'controller.php') | ||
))->withBasePath($rootPath); | ||
$files[$codeFile->getId()] = $codeFile; | ||
|
||
//$actions = $command->getActions(); | ||
$actions = ['index']; | ||
$model = $this->activeRecordFactory->createAR($command->getModel()); | ||
foreach ($actions as $action) { | ||
$codeFile = (new CodeFile( | ||
$this->getViewFile($command, $action), | ||
$this->render($command, $action.'.php', ['action' => $action, 'model' => $model]) | ||
))->withBasePath($rootPath); | ||
$files[$codeFile->getId()] = $codeFile; | ||
} | ||
|
||
return $files; | ||
} | ||
|
||
/** | ||
* @return string the controller class file path | ||
*/ | ||
private function getControllerFile(Command $command): string | ||
{ | ||
$directory = empty($command->getDirectory()) ? '@src/Controller/' : $command->getDirectory(); | ||
|
||
return $this->aliases->get( | ||
str_replace( | ||
['\\', '//'], | ||
'/', | ||
sprintf( | ||
'%s/%s.php', | ||
$directory, | ||
$command->getControllerClass(), | ||
), | ||
), | ||
); | ||
} | ||
|
||
/** | ||
* @param string $action the action ID | ||
* | ||
* @return string the action view file path | ||
*/ | ||
public function getViewFile(Command $command, string $action): string | ||
{ | ||
$directory = empty($command->getViewsPath()) ? '@views/' : $command->getViewsPath(); | ||
|
||
return $this->aliases->get( | ||
str_replace( | ||
['\\', '//'], | ||
'/', | ||
sprintf( | ||
'%s/%s/%s.php', | ||
$directory, | ||
$command->getControllerID(), | ||
$action, | ||
), | ||
), | ||
); | ||
} | ||
|
||
public static function getCommandClass(): string | ||
{ | ||
return Command::class; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<?php | ||
declare(strict_types=1); | ||
/** | ||
* This is the template for generating a controller class file. | ||
*/ | ||
|
||
use Yiisoft\Strings\StringHelper; | ||
|
||
/* @var $command Yiisoft\Yii\Gii\Generator\CRUD\Command */ | ||
|
||
$classDefinitionParts = []; | ||
$classDefinitionParts[] = StringHelper::baseName($command->getControllerClass()); | ||
Check failure on line 12 in src/Generator/CRUD/default/controller.php GitHub Actions / psalm / PHP 8.1-ubuntu-latestUndefinedGlobalVariable
Check failure on line 12 in src/Generator/CRUD/default/controller.php GitHub Actions / psalm / PHP 8.2-ubuntu-latestUndefinedGlobalVariable
|
||
if (!empty($command->getBaseClass())) { | ||
$classDefinitionParts[] = 'extends \\' . trim($command->getBaseClass(), '\\'); | ||
Check failure on line 14 in src/Generator/CRUD/default/controller.php GitHub Actions / psalm / PHP 8.1-ubuntu-latestUndefinedGlobalVariable
Check failure on line 14 in src/Generator/CRUD/default/controller.php GitHub Actions / psalm / PHP 8.2-ubuntu-latestUndefinedGlobalVariable
|
||
} | ||
$classDefinition = implode(' ', $classDefinitionParts) . PHP_EOL; | ||
|
||
|
||
echo "<?php\n"; | ||
?> | ||
|
||
declare(strict_types=1); | ||
|
||
namespace <?= $command->getControllerNamespace() ?>; | ||
Check failure on line 24 in src/Generator/CRUD/default/controller.php GitHub Actions / psalm / PHP 8.1-ubuntu-latestUndefinedGlobalVariable
Check failure on line 24 in src/Generator/CRUD/default/controller.php GitHub Actions / psalm / PHP 8.2-ubuntu-latestUndefinedGlobalVariable
|
||
|
||
use Yiisoft\Yii\View\ViewRenderer; | ||
|
||
final class <?= $classDefinition; ?> | ||
{ | ||
public function __construct(private ViewRenderer $viewRenderer) | ||
{ | ||
$this->viewRenderer = $viewRenderer->withController($this); | ||
} | ||
<?php foreach ($command->getActions() as $action) : ?> | ||
Check failure on line 34 in src/Generator/CRUD/default/controller.php GitHub Actions / psalm / PHP 8.1-ubuntu-latestUndefinedGlobalVariable
Check failure on line 34 in src/Generator/CRUD/default/controller.php GitHub Actions / psalm / PHP 8.2-ubuntu-latestUndefinedGlobalVariable
|
||
|
||
public function <?= $action ?>() | ||
{ | ||
return $this->viewRenderer->render('<?= $action ?>'); | ||
} | ||
<?php endforeach; ?> | ||
} | ||