You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
user_center/app/Console/Commands/ApiControllerGenerator.php

182 lines
6.2 KiB

4 years ago
<?php
namespace App\Console\Commands;
use Illuminate\Console\GeneratorCommand;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Symfony\Component\Console\Input\InputOption;
class ApiControllerGenerator extends GeneratorCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'make:apiController';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new controller class';
/**
* The type of class being generated.
*
* @var string
*/
protected $type = 'Controller';
/**
* Get the stub file for the generator.
*
* @return string
*/
protected function getStub()
{
return $this->resolveStubPath('/stubs/controller.model.api.stub');
}
/**
* Resolve the fully-qualified path to the stub.
*
* @param string $stub
* @return string
*/
protected function resolveStubPath($stub)
{
return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))
? $customPath
: __DIR__.$stub;
}
/**
* Get the default namespace for the class.
*
* @param string $rootNamespace
* @return string
*/
protected function getDefaultNamespace($rootNamespace)
{
return $rootNamespace.'\Http\Controllers\Api';
}
/**
* Build the class with the given name.
*
* Remove the base controller import if we are already in base namespace.
*
* @param string $name
* @return string
*/
protected function buildClass($name)
{
$modelClass = $this->parseModel(Str::replaceLast('Controller', 'T', class_basename($name)));
if (! class_exists($modelClass)) {
if ($this->confirm("A {$modelClass} model does not exist. Do you want to generate it?", true)) {
$this->call('make:apiModel', ['name' => $modelClass]);
}
}
$resourceClass = $this->qualifyResource(Str::replaceLast('Controller', '', class_basename($name)));
if (! class_exists($resourceClass)) {
if ($this->confirm("A {$resourceClass} resource does not exist. Do you want to generate it?", true)) {
$this->call('make:apiResource', ['name' => $resourceClass]);
}
}
$resourceCollectionClass = $resourceClass . 'Collection';
if (! class_exists($resourceCollectionClass)) {
if ($this->confirm("A {$resourceCollectionClass} resource collection does not exist. Do you want to generate it?", true)) {
$this->call('make:resource', ['name' => $resourceCollectionClass]);
}
}
$table_name = env('DB_PREFIX') . Str::snake(str_replace([$this->getNamespace($name).'\\', 'Controller'], ['','T'], $name));
$columns = DB::select("select COLUMN_NAME,DATA_TYPE,IS_NULLABLE,COLUMN_DEFAULT from information_schema.COLUMNS where table_name = '$table_name'");
$attributes = '';
$rules = '';
foreach ($columns as $column){
if(!in_array($column->COLUMN_NAME, ['id', 'created_at', 'updated_at'])){
$attributes .= ' $this->model->'. $column->COLUMN_NAME .' = $this->params[\''. $column->COLUMN_NAME .'\']';
$rule = " '{$column->COLUMN_NAME}' => '";
if ($column->IS_NULLABLE == 'NO' && $column->COLUMN_DEFAULT === null) {
$rule .= 'required|';
}
if(in_array($column->DATA_TYPE, ['int','integer', 'tinyint','smallint','mediumint','bigint','decimal'])){
$rule .= 'numeric|';
$attributes .= ' ?? 0';
}
if(in_array($column->DATA_TYPE, ['varchar','char'])){
$rule .= 'string|';
$attributes .= ' ?? \'\'';
}
$attributes .= ';'. PHP_EOL;
if (Str::endsWith($rule,'|')) {
$rules .= Str::replaceLast('|', '', $rule) .'\',' . PHP_EOL;
}
}
}
$replace = [
'{{ namespacedModel }}' => $modelClass,
'{{ model }}' => class_basename($modelClass),
'{{ namespacedResource }}' => $resourceClass,
'{{ resource }}' => class_basename($resourceClass),
'{{ namespacedResourceCollection }}' => $resourceCollectionClass,
'{{ resourceCollection }}' => class_basename($resourceCollectionClass),
'{{ attrList }}' => Str::replaceLast(PHP_EOL, '', $attributes),
'{{ ruleList }}' => Str::replaceLast(PHP_EOL, '', $rules),
];
return str_replace(
array_keys($replace), array_values($replace), parent::buildClass($name)
);
}
protected function qualifyResource(string $name)
{
$rootNamespace = $this->rootNamespace();
return $rootNamespace. 'Http' . DIRECTORY_SEPARATOR .'Resources'. DIRECTORY_SEPARATOR . $name;
}
/**
* Get the fully-qualified model class name.
*
* @param string $model
* @return string
*
* @throws \InvalidArgumentException
*/
protected function parseModel($model)
{
if (preg_match('([^A-Za-z0-9_/\\\\])', $model)) {
throw new InvalidArgumentException('Model name contains invalid characters.');
}
return $this->qualifyModel($model);
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['api', null, InputOption::VALUE_NONE, 'Exclude the create and edit methods from the controller.'],
['force', null, InputOption::VALUE_NONE, 'Create the class even if the controller already exists'],
['invokable', 'i', InputOption::VALUE_NONE, 'Generate a single method, invokable controller class.'],
['model', 'm', InputOption::VALUE_OPTIONAL, 'Generate a resource controller for the given model.'],
['parent', 'p', InputOption::VALUE_OPTIONAL, 'Generate a nested resource controller class.'],
['resource', 'r', InputOption::VALUE_NONE, 'Generate a resource controller class.'],
];
}
}