Last active
October 31, 2021 05:07
-
-
Save jeff-silva/f8eeb7f7dab044fe842a2c3402dbd486 to your computer and use it in GitHub Desktop.
LaravelCommands
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console\Commands; | |
use Illuminate\Console\Command; | |
class AppBase extends Command | |
{ | |
protected $signature = 'app:base'; | |
protected $description = 'Classe base'; | |
public function handle() | |
{ | |
// | |
} | |
public function getFieldSchema($field) { | |
$field = (array) $field; | |
$schema = [ $field['Type'] ]; | |
$schema[] = (($field['Null']=='NO' || $field['Key']=='PRI')? 'NOT NULL': 'NULL'); | |
if ($field['Extra']=='auto_increment') $schema[] = 'AUTO_INCREMENT'; | |
if ($field['Key'] != 'PRI' AND !str_contains($field['Type'], 'varchar') AND !str_contains($field['Type'], 'int') AND $field['Type']!='longtext' AND $field['Type']!='timestamp') { | |
$schema[] = ($field['Default']===NULL? 'DEFAULT NULL': "DEFAULT '{$field['Default']}'"); | |
} | |
return implode(' ', $schema); | |
} | |
public function varExport($data) { | |
$dump = var_export($data, true); | |
$dump = preg_replace('#(?:\A|\n)([ ]*)array \(#i', '[', $dump); // Starts | |
$dump = preg_replace('#\n([ ]*)\),#', "\n$1],", $dump); // Ends | |
$dump = preg_replace('#=> \[\n\s+\],\n#', "=> [],\n", $dump); // Empties | |
if (gettype($data) == 'object') { // Deal with object states | |
$dump = str_replace('__set_state(array(', '__set_state([', $dump); | |
$dump = preg_replace('#\)\)$#', "])", $dump); | |
} | |
else { $dump = preg_replace('#\)$#', "]", $dump); } | |
return $dump; | |
} | |
public function classSource($class) { | |
if (is_string($class)) { | |
$class = app($this->Model->Namespace); | |
} | |
$class = new \ReflectionClass($class); | |
$fileName = $class->getFileName(); | |
$startLine = $class->getStartLine()-1; | |
$endLine = $class->getEndLine(); | |
$numLines = $endLine - $startLine; | |
$fileContents = null; | |
if(!empty($fileName)) { | |
$fileContents = file_get_contents($fileName); | |
$classSource = trim(implode('', array_slice(file($fileName), $startLine, $numLines))); // not perfect; if the class starts or ends on the same line as something else, this will be incorrect | |
// $hash = crc32($classSource); | |
} | |
return $fileContents; | |
} | |
public function classWriteMethod($class, $method_name, $method_content) { | |
$file = (new \ReflectionClass($class))->getFileName(); | |
if (is_string($class)) { | |
$class = app($class); | |
} | |
$source = $this->classSource($class); | |
if (method_exists($class, $method_name)) { | |
$source = preg_replace("/\t+public function {$method_name}(.+?)\}/s", $method_content, $source); | |
} | |
else { | |
$source = rtrim(rtrim($source), '}') ."\n{$method_content}\n}"; | |
} | |
file_put_contents($file, $source); | |
} | |
public function classWriteMethodOld($class, $method_name, $method_content) { | |
$class = "{$table['ModelNamespace']}\\{$table['Model']}"; | |
if (is_string($class)) { | |
$class = app($class); | |
} | |
$source = $this->classSource($class); | |
dd($source); | |
if (method_exists($class, $method_name)) { | |
// $source = preg_replace("/\t+public function {$method_name}(.+?)\}/s", $method_content, $source); | |
} | |
else { | |
$source = rtrim(rtrim($source), '}') ."\n{$method_content}\n}"; | |
} | |
file_put_contents(base_path($table['ModelFile']), $source); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console\Commands; | |
use Illuminate\Console\Command; | |
class AppBuild extends Command | |
{ | |
/** | |
* The name and signature of the console command. | |
* | |
* @var string | |
*/ | |
protected $signature = 'app:build'; | |
/** | |
* The console command description. | |
* | |
* @var string | |
*/ | |
protected $description = 'Build de aplicação'; | |
/** | |
* Create a new command instance. | |
* | |
* @return void | |
*/ | |
public function __construct() | |
{ | |
parent::__construct(); | |
} | |
/** | |
* Execute the console command. | |
* | |
* @return mixed | |
*/ | |
public function handle() | |
{ | |
// $this->comment('⚙️ Criando/alterando models'); | |
// if (app()->environment('production')) { | |
// // Sincronizar tabelas | |
// return; | |
// } | |
$commands = []; | |
$commands[] = [ | |
'title' => 'Migrate', | |
'command' => 'migrate', | |
]; | |
$commands[] = [ | |
'title' => 'Seed', | |
'command' => 'db:seed', | |
]; | |
$commands[] = [ | |
'title' => 'Limpar caches', | |
'command' => 'app:clear', | |
]; | |
$commands[] = [ | |
'title' => 'Cria configurações e schemas', | |
'command' => 'app:schema', | |
]; | |
$commands[] = [ | |
'title' => 'Gera/altera arquivos de model', | |
'command' => 'app:make-models', | |
]; | |
$commands[] = [ | |
'title' => 'Gera/altera arquivos de controllers', | |
'command' => 'app:make-controllers', | |
]; | |
$commands[] = [ | |
'title' => 'Gera/altera arquivo de rotas', | |
'command' => 'app:make-routes', | |
]; | |
$commands[] = [ | |
'title' => 'Gera/altera arquivos de UI', | |
'command' => 'app:make-ui', | |
]; | |
foreach($commands as $com) { | |
$this->comment("⚙️ {$com['title']}"); | |
try { | |
\Artisan::call($com['command']); | |
} | |
catch(\Exception $e) { | |
$this->comment('Error: '. $e->getMessage()); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console\Commands; | |
use Illuminate\Console\Command; | |
class AppClear extends Command | |
{ | |
/** | |
* The name and signature of the console command. | |
* | |
* @var string | |
*/ | |
protected $signature = 'app:clear'; | |
/** | |
* The console command description. | |
* | |
* @var string | |
*/ | |
protected $description = 'Limpar caches'; | |
/** | |
* Create a new command instance. | |
* | |
* @return void | |
*/ | |
public function __construct() | |
{ | |
parent::__construct(); | |
} | |
/** | |
* Execute the console command. | |
* | |
* @return mixed | |
*/ | |
public function handle() | |
{ | |
$commands[] = [ | |
'title' => 'Limpando cache de configurações', | |
'command' => 'config:clear', | |
]; | |
$commands[] = [ | |
'title' => 'Limpando cache de rotas', | |
'command' => 'route:clear', | |
]; | |
$commands[] = [ | |
'title' => 'Limpando cache de views', | |
'command' => 'view:clear', | |
]; | |
$commands[] = [ | |
'title' => 'Optimize clear', | |
'command' => 'optimize:clear', | |
]; | |
$commands[] = [ | |
'title' => 'Criando link de storage', | |
'command' => 'storage:link', | |
]; | |
foreach($commands as $com) { | |
$this->comment($com['title']); | |
\Artisan::call($com['command']); | |
} | |
$this->comment('Concluído'); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console\Commands; | |
use Illuminate\Console\Command; | |
class AppCommandsUpdate extends Command | |
{ | |
/** | |
* The name and signature of the console command. | |
* | |
* @var string | |
*/ | |
protected $signature = 'app:commands-update'; | |
/** | |
* The console command description. | |
* | |
* @var string | |
*/ | |
protected $description = 'Atualiza comandos'; | |
/** | |
* Create a new command instance. | |
* | |
* @return void | |
*/ | |
public function __construct() | |
{ | |
parent::__construct(); | |
} | |
/** | |
* Execute the console command. | |
* | |
* @return int | |
*/ | |
public function handle() | |
{ | |
$files = [ | |
'AppBuild.php', | |
'AppClear.php', | |
'AppCommandsUpdate.php', | |
'AppDbExport.php', | |
'AppDbImport.php', | |
'AppDeploy.php', | |
'AppMakeControllers.php', | |
'AppMakeModels.php', | |
'AppMakeRoutes.php', | |
'AppMakeUi.php', | |
'AppMigrate.php', | |
'AppSchema.php', | |
]; | |
foreach($files as $file) { | |
$filepath = implode(DIRECTORY_SEPARATOR, [__DIR__, $file]); | |
$content = "https://gist.githubusercontent.com/jeff-silva/f8eeb7f7dab044fe842a2c3402dbd486/raw/{$file}"; | |
$content = \Illuminate\Support\Facades\Http::get($content)->body(); | |
file_put_contents($filepath, $content); | |
$this->comment("Atualizando {$file} - {$filepath}"); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console\Commands; | |
use Illuminate\Console\Command; | |
class AppDbExport extends AppBase | |
{ | |
protected $signature = 'app:db-export'; | |
protected $description = 'Exporta banco de dados para schema.sql'; | |
public function handle() | |
{ | |
$this->comment('⚙️ Gerando config/database-schema.php'); | |
$database_schema = $this->getSchema(); | |
file_put_contents(config_path('database-schema.php'), implode("\n\n", [ | |
'<?php', | |
"/* Para gerar este arquivo, execute 'php artisan app:db-export'\nPara criar tabelas e colunas, execute 'php artisan app:db-import' */", | |
('return '. $this->varExport($database_schema) .';'), | |
])); | |
} | |
public function getSchema() { | |
$database_schema = [ | |
'tables' => [], | |
'fks' => [], | |
]; | |
foreach(\DB::select('SHOW TABLE STATUS') as $table) { | |
$deletes = [ | |
'Version', 'Row_format', 'Rows', 'Avg_row_length', 'Data_length', 'Max_data_length', 'Index_length', | |
'Data_free', 'Create_time', 'Update_time', 'Check_time', 'Checksum', 'Create_options', | |
]; | |
foreach($deletes as $delete) { | |
unset($table->$delete); | |
} | |
$table->Model = ((string) \Str::of($table->Name)->slug()->studly()); | |
$table->ModelNamespace = '\App\Models'; | |
$table->ModelFile = '\app\Models\\'. ((string) \Str::of($table->Name)->slug()->studly()) .'.php'; | |
$table->Controller = ((string) \Str::of($table->Name)->slug()->studly()) .'Controller'; | |
$table->ControllerNamespace = '\App\Http\Controllers'; | |
$table->ControllerFile = '\app\Http\Controllers\\'. ((string) \Str::of($table->Name)->slug()->studly()) .'Controller.php'; | |
$statement = collect(\DB::select("SHOW CREATE TABLE `{$table->Name}`;"))->pluck('Create Table')->first(); | |
$statement = str_replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS', $statement); | |
$table->Sql = str_replace(["\n", "\t"], '', $statement); | |
$table->Fields = []; | |
foreach(\DB::select("SHOW COLUMNS FROM {$table->Name}") as $col) { | |
$col->Sql = $this->getFieldSchema($col); | |
$table->Fields[ $col->Field ] = $col; | |
} | |
$database_schema['tables'][ $table->Name ] = $table; | |
} | |
$database = env('DB_DATABASE'); | |
foreach(\DB::select("SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE CONSTRAINT_SCHEMA='{$database}' AND CONSTRAINT_NAME != 'PRIMARY' ") as $fk) { | |
$database_schema['fks'][ $fk->CONSTRAINT_NAME ] = $fk; | |
} | |
return json_decode(json_encode($database_schema), true); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console\Commands; | |
class AppDbImport extends AppBase | |
{ | |
protected $signature = 'app:db-import'; | |
protected $description = 'Importa schema.sql'; | |
public function handle() | |
{ | |
$schema = config('database-schema', []); | |
foreach($schema['tables'] as $table_name => $table) { | |
if (\Schema::hasTable($table_name)) { | |
foreach($table['Fields'] as $field_name => $field) { | |
if (\Schema::hasColumn($table_name, $field_name)) { | |
// \DB::statement("ALTER TABLE `{$table_name}` MODIFY COLUMN `{$field_name}` {$field['Sql']};"); | |
} | |
else { | |
$this->comment("criando coluna {$table_name}.{$field_name}"); | |
\DB::statement("ALTER TABLE `{$table_name}` ADD COLUMN `{$field_name}` {$field['Sql']};"); | |
} | |
} | |
} | |
else { | |
$this->comment("criando tabela {$table_name}"); | |
\DB::statement($table['Sql']); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console\Commands; | |
use Illuminate\Console\Command; | |
class AppDeploy extends Command | |
{ | |
/** | |
* The name and signature of the console command. | |
* | |
* @var string | |
*/ | |
protected $signature = 'app:deploy'; | |
/** | |
* The console command description. | |
* | |
* @var string | |
*/ | |
protected $description = 'Deploy de aplicação'; | |
/** | |
* Create a new command instance. | |
* | |
* @return void | |
*/ | |
public function __construct() | |
{ | |
parent::__construct(); | |
} | |
/** | |
* Execute the console command. | |
* | |
* @return int | |
*/ | |
public function handle() | |
{ | |
$this->comment('Iniciando deploy'); | |
$commands[] = [ | |
'title' => 'Migrate', | |
'command' => 'migrate', | |
]; | |
$commands[] = [ | |
'title' => 'Seed', | |
'command' => 'db:seed', | |
]; | |
$commands[] = [ | |
'title' => 'Limpando cache de configurações:', | |
'command' => 'config:clear', | |
]; | |
$commands[] = [ | |
'title' => 'Migrando banco de dados:', | |
'command' => 'app:migrate', | |
]; | |
foreach($commands as $com) { | |
$this->comment($com['title']); | |
$this->call($com['command']); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console\Commands; | |
class AppMakeControllers extends AppBase | |
{ | |
protected $signature = 'app:make-controllers'; | |
protected $description = 'Criar/alterar controllers de acordo com modelo do banco'; | |
public function handle() | |
{ | |
// $this->comment('⚙️ Criando/alterando models'); | |
$tables = config('database-schema.tables', []); | |
foreach($tables as $table_name=>$table) { | |
if (! file_exists(base_path($table['ControllerFile']))) { | |
file_put_contents(base_path($table['ControllerFile']), implode("\n", [ | |
'<?php', | |
'', | |
"namespace App\Http\Controllers;", | |
'', | |
"class {$table['Controller']} extends Controller", | |
'{', | |
'}', | |
])); | |
} | |
$methods = []; | |
$methods['search'] = implode("\n", [ | |
"\tpublic function search() {", | |
"\t\treturn {$table['ModelNamespace']}::querySearch();", | |
"\t}", | |
]); | |
$methods['find'] = implode("\n", [ | |
"\tpublic function find(\$id) {", | |
"\t\treturn {$table['ModelNamespace']}::find(\$id);", | |
"\t}", | |
]); | |
$methods['save'] = implode("\n", [ | |
"\tpublic function save() {", | |
"\t\treturn {$table['ModelNamespace']}::fill(request()->all())->save();", | |
"\t}", | |
]); | |
$methods['delete'] = implode("\n", [ | |
"\tpublic function delete(\$id) {", | |
"\t\treturn {$table['ModelNamespace']}::find(\$id)->remove();", | |
"\t}", | |
]); | |
$methods['clone'] = implode("\n", [ | |
"\tpublic function clone(\$id) {", | |
"\t\treturn {$table['ModelNamespace']}::find(\$id)->clone();", | |
"\t}", | |
]); | |
$methods['export'] = implode("\n", [ | |
"\tpublic function export(\$id) {", | |
"\t\treturn {$table['ModelNamespace']}::find(\$id)->export();", | |
"\t}", | |
]); | |
foreach($methods as $method_name=>$method_content) { | |
$this->classWriteMethod("{$table['ControllerNamespace']}\\{$table['Controller']}", $method_name, $method_content); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console\Commands; | |
use Illuminate\Console\Command; | |
class AppMakeModels extends AppBase | |
{ | |
protected $signature = 'app:make-models'; | |
protected $description = 'Criar/alterar models de acordo com modelo do banco'; | |
public function handle() | |
{ | |
// $this->comment('⚙️ Criando/alterando models'); | |
$schema = config('database-schema', []); | |
foreach($schema['tables'] as $table_name=>$table) { | |
if ($table_name=='users') continue; | |
if (! file_exists(base_path($table['ModelFile']))) { | |
file_put_contents(base_path($table['ModelFile']), implode("\n", [ | |
'<?php', | |
'', | |
"namespace App\Models;", | |
'', | |
"class {$table['Model']} extends \Illuminate\Database\Eloquent\Model", | |
'{', | |
"\tuse \App\Traits\Model;", | |
'', | |
"\tprotected \$fillable = [\n\t\t'". implode("',\n\t\t'", array_keys($table['Fields'])) ."',\n\t];", | |
'', | |
"\tpublic function validate(\$data=[]) {", | |
"\t\treturn \Validator::make(\$data, [", | |
"\t\t\t'name' => ['required'],", | |
"\t\t]);", | |
"\t}", | |
'}', | |
])); | |
} | |
$content = file_get_contents(base_path($table['ModelFile'])); | |
$me = $this; | |
// Criando protected $fillable | |
$content = preg_replace_callback('/protected \$fillable(.+?);/s', function($finds) use($me, $table) { | |
$fillable = "'". implode("',\n\t\t'", array_keys($table['Fields'])) ."'"; | |
return "protected \$fillable = [\n\t\t{$fillable}\n\t];"; | |
}, $content); | |
file_put_contents(base_path($table['ModelFile']), $content); | |
// Criando métodos belongsTo e hasMany | |
$methods = []; | |
$fks = config('database-schema.fks', []); | |
foreach($fks as $fk_table=>$fk) { | |
if (! $fk['REFERENCED_TABLE_NAME']) continue; | |
// hasMany | |
if ($fk['REFERENCED_TABLE_NAME']==$table_name) { | |
$methodName = (string) \Str::of($fk['TABLE_NAME'])->camel()->plural(); | |
$modelName = "{$table['ModelNamespace']}\\{$table['Model']}"; | |
$methods[ $methodName ] = "\tpublic function {$methodName}() {\n\t\treturn \$this->hasMany({$modelName}::class, '{$fk['COLUMN_NAME']}', '{$fk['REFERENCED_COLUMN_NAME']}');\n\t}"; | |
} | |
// belongsTo | |
if ($fk['TABLE_NAME']==$table_name) { | |
$methodName = (string) \Str::of($fk['REFERENCED_TABLE_NAME'])->camel()->singular(); | |
$modelName = "{$table['ModelNamespace']}\\{$table['Model']}"; | |
$methods[ $methodName ] = "\tpublic function {$methodName}() {\n\t\treturn \$this->belongsTo({$modelName}::class, '{$fk['COLUMN_NAME']}', '{$fk['REFERENCED_COLUMN_NAME']}');\n\t}"; | |
} | |
} | |
foreach($methods as $method_name=>$method_content) { | |
$this->classWriteMethod("{$table['ModelNamespace']}\\{$table['Model']}", $method_name, $method_content); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console\Commands; | |
use Illuminate\Console\Command; | |
class AppMakeRoutes extends Command | |
{ | |
/** | |
* The name and signature of the console command. | |
* | |
* @var string | |
*/ | |
protected $signature = 'app:make-routes'; | |
/** | |
* The console command description. | |
* | |
* @var string | |
*/ | |
protected $description = 'Criar/alterar rotas de acordo com métodos de controllers'; | |
/** | |
* Create a new command instance. | |
* | |
* @return void | |
*/ | |
public function __construct() | |
{ | |
parent::__construct(); | |
} | |
/** | |
* Execute the console command. | |
* | |
* @return mixed | |
*/ | |
public function handle() | |
{ | |
// $this->comment('⚙️ Criando/alterando models'); | |
$content = ['<?php', '', '// File generated automatically', '// Do not edit or your changes will be lost', '']; | |
$paths = [app_path(implode(DIRECTORY_SEPARATOR, ['Http', 'Controllers']))]; | |
foreach((new \Symfony\Component\Finder\Finder)->in($paths)->files() as $file) { | |
$filename = str_replace('.php', '', $file->getFilename()); | |
$namespace = "\App\Http\Controllers\\{$filename}"; | |
$prefix = (string) \Str::of(str_replace('Controller', '', $filename))->kebab(); | |
foreach ((new \ReflectionClass($namespace))->getMethods() as $rmethod) { | |
$method_name = $rmethod->getName(); | |
$ignore = [ | |
'getValidationFactory', | |
'getMiddleware', | |
]; | |
if (in_array($method_name, $ignore)) continue; | |
$route = [$prefix]; | |
foreach(['any', 'get', 'post', 'put'] as $method) { | |
if (! \Str::startsWith($method_name, $method)) continue; | |
$route[] = (string) \Str::of(str_replace($method, '', $method_name))->studly()->kebab(); | |
foreach($rmethod->getParameters() as $param) { | |
if (in_array($param->name, ['request'])) continue; | |
$route[] = '{'. $param->name .'}'; | |
} | |
$route = implode('/', $route); | |
$content[] = "Route::{$method}('{$route}', '{$namespace}@{$method_name}');"; | |
} | |
} | |
$content[] = ''; | |
} | |
$content = implode("\n", $content); | |
$file = base_path(implode(DIRECTORY_SEPARATOR, ['routes', 'api-generated.php'])); | |
file_put_contents($file, $content); | |
} | |
} | |
// Route::get('email-sent/search', '\App\Http\Controllers\EmailSentController@getSearch'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console\Commands; | |
use Illuminate\Console\Command; | |
class AppMakeUi extends Command | |
{ | |
/** | |
* The name and signature of the console command. | |
* | |
* @var string | |
*/ | |
protected $signature = 'app:make-ui'; | |
/** | |
* The console command description. | |
* | |
* @var string | |
*/ | |
protected $description = 'Gerar interfaces'; | |
/** | |
* Create a new command instance. | |
* | |
* @return void | |
*/ | |
public function __construct() | |
{ | |
parent::__construct(); | |
} | |
/** | |
* Execute the console command. | |
* | |
* @return mixed | |
*/ | |
public function handle() | |
{ | |
$tables = config('database-schema.tables', []); | |
foreach($tables as $table_name=>$table) { | |
if (config("database-settings.models.{$table_name}")) { | |
$model = new \stdClass; | |
$model->name = (string) \Str::of($table_name)->studly()->kebab()->singular(); | |
$model->file = base_path(implode(DIRECTORY_SEPARATOR, ['resources', 'nuxt', 'components', 'app', "ui-{$model->name}.vue"])); | |
$model->route = (string) \Str::of($table_name)->studly()->kebab()->singular(); | |
$content = implode("\n", [ | |
'<template><div>', | |
"\t<el-select v-model=\"props.value\" :multiple=\"props.multiple\"", | |
"\t\t@change=\"emitValue()\" class=\"form-control p-0\"", | |
"\t\tfilterable remote :placeholder=\"props.placeholder\"", | |
"\t\treserve-keyword :remote-method=\"remoteSearch\"", | |
"\t>", | |
"\t\t<el-option :value=\"i.id\" :label=\"i.name||i.id\" v-for=\"i in items\" :key=\"i.id\">{{ i.name||i.id }}</el-option>", | |
"\t</el-select>", | |
'</div></template>', | |
'', | |
'<script>', | |
'export default {', | |
"\tname: \"ui-{$model->name}\",", | |
"\t", | |
"\tprops: {", | |
"\t\tvalue: {default:\"\", type:[Number, String, Array]},", | |
"\t\tplaceholder: {default:'Selecionar'},", | |
"\t\tmultiple: {default:false},", | |
"\t},", | |
"\t", | |
"\twatch: {", | |
"\t\t\$props: {deep:true, handler(value) {", | |
"\t\t\tthis.props = JSON.parse(JSON.stringify(value));", | |
"\t\t\tthis.remoteSearch('', this.props.value);", | |
"\t\t}},", | |
"\t},", | |
"\t", | |
"\tmethods: {", | |
"\t\temitValue() {", | |
"\t\t\tthis.\$emit('input', this.props.value);", | |
"\t\t\tthis.\$emit('change', this.props.value);", | |
"\t\t},", | |
"\t\t", | |
"\t\tremoteSearch(q='', id=null) {", | |
"\t\t\tthis.\$axios.get('/api/{$model->route}/search', {params:{q, id}}).then(resp => {", | |
"\t\t\t\tthis.items = resp.data.data;", | |
"\t\t\t});", | |
"\t\t},", | |
"\t},", | |
"\t", | |
"\tdata() {", | |
"\t\treturn {", | |
"\t\t\tprops: JSON.parse(JSON.stringify(this.\$props)),", | |
"\t\t\titems: [],", | |
"\t\t};", | |
"\t},", | |
'}', | |
'</script>', | |
]); | |
file_put_contents($model->file, $content); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console\Commands; | |
use Illuminate\Console\Command; | |
class AppMigrate extends Command | |
{ | |
/** | |
* The name and signature of the console command. | |
* | |
* @var string | |
*/ | |
protected $signature = 'app:migrate'; | |
/** | |
* The console command description. | |
* | |
* @var string | |
*/ | |
protected $description = 'Sincronização de schema'; | |
/** | |
* Create a new command instance. | |
* | |
* @return void | |
*/ | |
public function __construct() | |
{ | |
parent::__construct(); | |
} | |
/** | |
* Execute the console command. | |
* | |
* @return int | |
*/ | |
public function handle() | |
{ | |
$this->comment('🗂️ Iniciando migração'); | |
$database = env('DB_DATABASE'); | |
$schema = $this->getSchema(); | |
$schema_cfg = config('database-schema'); | |
$sqls = []; | |
// Criar tabelas que não existem | |
foreach($schema_cfg['tables'] as $table_cfg_name => $table_cfg) { | |
if (isset($schema['tables'][ $table_cfg_name ])) continue; | |
$sql_create = []; | |
foreach($table_cfg['Fields'] as $field_cfg_name => $field_cfg) { | |
$field_cfg_type = $this->getFieldSchema($field_cfg); | |
$sql_create[] = "\t{$field_cfg_name} {$field_cfg_type}"; | |
} | |
foreach($table_cfg['Fields'] as $field_cfg_name => $field_cfg) { | |
if ($field_cfg['Key']=='PRI') { | |
$sql_create[] = "\tPRIMARY KEY (`{$field_cfg_name}`) USING BTREE"; | |
break; | |
} | |
} | |
$sql_create = implode(",\n", $sql_create); | |
$sql_create = "CREATE TABLE `{$table_cfg_name}` (\n{$sql_create}\n) COLLATE='{$table_cfg['Collation']}' ENGINE={$table_cfg['Engine']};"; | |
$sqls[] = $sql_create; | |
} | |
// Alterar tabelas existentes | |
foreach($schema_cfg['tables'] as $table_cfg_name => $table_cfg) { | |
if (! isset($schema['tables'][ $table_cfg_name ])) continue; | |
$table = $schema['tables'][ $table_cfg_name ]; | |
// Verificando colunas | |
foreach($table_cfg['Fields'] as $field_cfg_name => $field_cfg) { | |
$field_cfg_type = $this->getFieldSchema($field_cfg); | |
// Alterando colunas que existem | |
if (isset($table['Fields'][ $field_cfg_name ])) { | |
$sqls[] = "ALTER TABLE `{$table_cfg_name}` CHANGE COLUMN `{$field_cfg_name}` `{$field_cfg_name}` {$field_cfg_type};"; | |
} | |
// Criando colunas que não existem | |
else { | |
$sqls[] = "ALTER TABLE `{$table_cfg_name}` ADD COLUMN `{$field_cfg_name}` {$field_cfg_type};"; | |
} | |
} | |
} | |
// Criar chaves estrangeiras | |
foreach($schema_cfg['fks'] as $fk_cfg_name => $fk_cfg) { | |
if (isset($schema['fks'][ $fk_cfg_name ])) continue; | |
// Criando chave estrangeira | |
$sqls[] = "ALTER TABLE `{$fk_cfg['TABLE_NAME']}` ADD CONSTRAINT `{$fk_cfg['CONSTRAINT_NAME']}` FOREIGN KEY (`{$fk_cfg['COLUMN_NAME']}`) REFERENCES `{$fk_cfg['REFERENCED_TABLE_NAME']}` (`{$fk_cfg['REFERENCED_COLUMN_NAME']}`);"; | |
} | |
$this->comment("\nAlterando tabela:"); | |
foreach($sqls as $sql) { | |
$this->comment($sql); | |
\DB::select(\DB::raw($sql)); | |
} | |
} | |
public function getFieldSchema($field) { | |
$schema = [ $field['Type'] ]; | |
$schema[] = (($field['Null']=='NO' || $field['Key']=='PRI')? 'NOT NULL': 'NULL'); | |
if ($field['Extra']=='auto_increment') $schema[] = 'AUTO_INCREMENT'; | |
if ($field['Key'] != 'PRI' AND !\Str::contains($field['Type'], 'varchar') AND !\Str::contains($field['Type'], 'int') AND $field['Type']!='longtext' AND $field['Type']!='timestamp') { | |
$schema[] = ($field['Default']===NULL? 'DEFAULT NULL': "DEFAULT '{$field['Default']}'"); | |
} | |
return implode(' ', $schema); | |
} | |
public function getSchema() { | |
$database_schema = [ | |
'tables' => [], | |
'fks' => [], | |
]; | |
foreach(\DB::select('SHOW TABLE STATUS') as $table) { | |
$table->Fields = []; | |
foreach(\DB::select("SHOW COLUMNS FROM {$table->Name}") as $col) { | |
$table->Fields[ $col->Field ] = $col; | |
} | |
$database_schema['tables'][ $table->Name ] = $table; | |
} | |
$database = env('DB_DATABASE'); | |
foreach(\DB::select("SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE CONSTRAINT_SCHEMA='{$database}' AND CONSTRAINT_NAME != 'PRIMARY' ") as $fk) { | |
$database_schema['fks'][ $fk->CONSTRAINT_NAME ] = $fk; | |
} | |
return json_decode(json_encode($database_schema), true); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console\Commands; | |
use Illuminate\Console\Command; | |
class AppSchema extends Command | |
{ | |
/** | |
* The name and signature of the console command. | |
* | |
* @var string | |
*/ | |
protected $signature = 'app:schema'; | |
/** | |
* The console command description. | |
* | |
* @var string | |
*/ | |
protected $description = 'Cria schema do banco de dados'; | |
/** | |
* Create a new command instance. | |
* | |
* @return void | |
*/ | |
public function __construct() | |
{ | |
parent::__construct(); | |
} | |
/** | |
* Execute the console command. | |
* | |
* @return int | |
*/ | |
public function handle() | |
{ | |
$this->comment('⚙️ Gerando config/database-schema.php'); | |
$database_schema = $this->getSchema(); | |
$_procedure = function($query) { | |
$procedureName = '_temporary'; | |
return implode("\n", [ | |
"DROP PROCEDURE IF EXISTS `{$procedureName}`; DELIMITER //", | |
"CREATE PROCEDURE `{$procedureName}`() BEGIN", | |
"\tDECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;", | |
"\t{$query};", | |
"END // DELIMITER ; CALL {$procedureName}();", | |
"DROP PROCEDURE IF EXISTS `{$procedureName}`;", | |
]); | |
}; | |
$sqls = ['SET FOREIGN_KEY_CHECKS = 0;', '']; | |
foreach($database_schema['tables'] as $table_name=>$table) { | |
$sqls[] = "-- create table {$table_name} "; | |
$sql = collect(\DB::select("SHOW CREATE TABLE `{$table_name}`;"))->pluck('Create Table')->first(); | |
$sql = str_replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS', $sql) .';'; | |
$sql = preg_replace('/AUTO_INCREMENT=\d+\s/', '', $sql); | |
$sqls[] = $sql; | |
$sqls[] = ''; | |
} | |
foreach($database_schema['tables'] as $table_name=>$table) { | |
foreach($table['Fields'] as $col_field=>$col) { | |
$fieldSchema = $this->getFieldSchema((array) $col); | |
$sqls[] = "-- create field '{$col_field}' if not exists"; | |
$sqls[] = $_procedure("ALTER TABLE `{$table_name}` ADD COLUMN `{$col_field}` {$fieldSchema};"); | |
$sqls[] = ''; | |
$sqls[] = "-- modify field {$col_field} "; | |
$sqls[] = "ALTER TABLE `{$table_name}` MODIFY COLUMN `{$col_field}` {$fieldSchema};"; | |
$sqls[] = ''; | |
} | |
} | |
foreach($database_schema['fks'] as $fk_name=>$fk) { | |
$sqls[] = "-- creating fk if not exists"; | |
$sqls[] = $_procedure("ALTER TABLE {$fk['TABLE_NAME']} ADD CONSTRAINT {$fk_name} FOREIGN KEY ({$fk['COLUMN_NAME']}) REFERENCES {$fk['REFERENCED_TABLE_NAME']}({$fk['REFERENCED_COLUMN_NAME']});"); | |
$sqls[] = ''; | |
} | |
$sqls[] = 'SET FOREIGN_KEY_CHECKS = 1;'; | |
file_put_contents(database_path('schema.sql'), implode("\n", $sqls)); | |
$content = $this->varExport($database_schema); | |
$generated = "/*\n * Gerado em ". date('d/m/Y à\s H:i:s') ."\n * Por favor, não altere manualmente.\n */"; | |
file_put_contents(config_path('database-schema.php'), "<?php \n\n{$generated}\n\nreturn {$content};"); | |
$this->comment('⚙️ Gerando config/database-settings.php'); | |
$this->comment('Não se esqueça de alterar as configurações "model" para definir quais tabelas gerarão arquivos.'); | |
$database_settings_default = [ | |
'models' => [], | |
'controllers' => [], | |
]; | |
$database_settings = $database_settings_default; | |
foreach($database_schema['tables'] as $table_name=>$table) { | |
$database_settings['models'][ $table_name ] = false; | |
$database_settings['controllers'][ $table_name ] = false; | |
} | |
$database_settings2 = config('database-settings', $database_settings_default); | |
foreach($database_settings as $name=>$value) { | |
$database_settings2[$name] = isset($database_settings2[$name])? $database_settings2[$name]: []; | |
$database_settings2[$name] = array_merge($database_settings[$name], $database_settings2[$name]); | |
} | |
file_put_contents(config_path('database-settings.php'), '<?php return '. $this->varExport($database_settings2) .';'); | |
} | |
public function varExport($data) { | |
$dump = var_export($data, true); | |
$dump = preg_replace('#(?:\A|\n)([ ]*)array \(#i', '[', $dump); // Starts | |
$dump = preg_replace('#\n([ ]*)\),#', "\n$1],", $dump); // Ends | |
$dump = preg_replace('#=> \[\n\s+\],\n#', "=> [],\n", $dump); // Empties | |
if (gettype($data) == 'object') { // Deal with object states | |
$dump = str_replace('__set_state(array(', '__set_state([', $dump); | |
$dump = preg_replace('#\)\)$#', "])", $dump); | |
} | |
else { $dump = preg_replace('#\)$#', "]", $dump); } | |
return $dump; | |
} | |
public function getSchema() { | |
$database_schema = [ | |
'tables' => [], | |
'fks' => [], | |
]; | |
foreach(\DB::select('SHOW TABLE STATUS') as $table) { | |
$table->Fields = []; | |
foreach(\DB::select("SHOW COLUMNS FROM {$table->Name}") as $col) { | |
$table->Fields[ $col->Field ] = $col; | |
} | |
$database_schema['tables'][ $table->Name ] = $table; | |
} | |
$database = env('DB_DATABASE'); | |
foreach(\DB::select("SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE CONSTRAINT_SCHEMA='{$database}' AND CONSTRAINT_NAME != 'PRIMARY' ") as $fk) { | |
$database_schema['fks'][ $fk->CONSTRAINT_NAME ] = $fk; | |
} | |
return json_decode(json_encode($database_schema), true); | |
} | |
public function getFieldSchema($field) { | |
$schema = [ $field['Type'] ]; | |
$schema[] = (($field['Null']=='NO' || $field['Key']=='PRI')? 'NOT NULL': 'NULL'); | |
if ($field['Extra']=='auto_increment') $schema[] = 'AUTO_INCREMENT'; | |
if ($field['Key'] != 'PRI' AND !\Str::contains($field['Type'], 'varchar') AND !\Str::contains($field['Type'], 'int') AND $field['Type']!='longtext' AND $field['Type']!='timestamp') { | |
$schema[] = ($field['Default']===NULL? 'DEFAULT NULL': "DEFAULT '{$field['Default']}'"); | |
} | |
return implode(' ', $schema); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment