added code generator back to repository

This commit is contained in:
omair saleh
2020-09-14 16:36:40 +08:00
parent 0cab8e6456
commit 06b024ce9f
84 changed files with 5955 additions and 1 deletions
-1
View File
@@ -11,4 +11,3 @@ Homestead.json
Homestead.yaml Homestead.yaml
npm-debug.log npm-debug.log
yarn-error.log yarn-error.log
/app/Classes/CodeGenerator
@@ -0,0 +1,277 @@
<?php
namespace App\Classes\CodeGenerator\Commands;
use App\Classes\CodeGenerator\Common\CommandData;
use App\Classes\CodeGenerator\Generators\FactoryGenerator;
use App\Classes\CodeGenerator\Generators\Micros\DataTransferObjectGenerator;
use App\Classes\CodeGenerator\Generators\Micros\ResourceGenerator;
use App\Classes\CodeGenerator\Generators\Micros\RulesGenerator;
use App\Classes\CodeGenerator\Generators\Micros\ServicesGenerator;
use App\Classes\CodeGenerator\Generators\Micros\ValidatorsGenerator;
use App\Classes\CodeGenerator\Generators\MigrationGenerator;
use App\Classes\CodeGenerator\Generators\ModelGenerator;
use App\Classes\CodeGenerator\Generators\Scaffold\ControllersGenerator;
use App\Classes\CodeGenerator\Generators\Scaffold\ControllerLogicGenerator;
use App\Classes\CodeGenerator\Generators\Scaffold\RoutesGenerator;
use App\Classes\CodeGenerator\Generators\Scaffold\ViewsGenerator;
use App\Classes\CodeGenerator\Generators\Scaffold\VueGenerator;
use App\Classes\CodeGenerator\Generators\Scaffold\WebRouteGenerator;
use App\Classes\CodeGenerator\Generators\SeederGenerator;
use App\Classes\CodeGenerator\Utils\FileUtil;
use Illuminate\Console\Command;
use Illuminate\Support\Composer;
use Illuminate\Support\Str;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class BaseCommand extends Command
{
/**
* The command Data.
*
* @var CommandData
*/
public $commandData;
/**
* @var Composer
*/
public $composer;
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
$this->composer = app()['composer'];
}
public function handle()
{
$this->commandData->modelName = $this->argument('model');
$this->commandData->initCommandData();
$this->commandData->getFields();
}
public function generateCommonItems()
{
if (!$this->commandData->getOption('fromTable')) {
$migrationGenerator = new MigrationGenerator($this->commandData);
$migrationGenerator->generate();
}
$modelGenerator = new ModelGenerator($this->commandData);
$modelGenerator->generate();
$factoryGenerator = new FactoryGenerator($this->commandData);
$factoryGenerator->generate();
$seederGenerator = new SeederGenerator($this->commandData);
$seederGenerator->generate();
if($this->confirm("\nDo you want to include this seeder to the main seeder? [y|N]", false)){
$seederGenerator->updateMainSeeder();
}
}
public function generateMicroItems()
{
$dataTransferObjectGenerator = new DataTransferObjectGenerator($this->commandData);
$dataTransferObjectGenerator->generate();
$serviceGenerator = new ServicesGenerator($this->commandData);
$serviceGenerator->generate();
}
public function generateScaffoldItems()
{
$resourceGenerator = new ResourceGenerator($this->commandData);
$resourceGenerator->generate();
$validatorsGenerator = new ValidatorsGenerator($this->commandData);
$validatorsGenerator->generate();
$rulesGenerator = new RulesGenerator($this->commandData);
$rulesGenerator->generate();
if (!$this->isSkip('controllers') and !$this->isSkip('scaffold_controller')) {
$controllerLogicGenerator = new ControllerLogicGenerator($this->commandData);
$controllerLogicGenerator->generate();
$controllerGenerator = new ControllersGenerator($this->commandData);
$controllerGenerator->generate();
}
$routesGenerator = new RoutesGenerator($this->commandData);
$routesGenerator->generate();
// $webRouteGenerator = new WebRouteGenerator($this->commandData);
// $webRouteGenerator->generate();
}
public function generateViews(){
$viewGenerator = new ViewsGenerator($this->commandData);
$viewGenerator->generate();
$vueGenerator = new vueGenerator($this->commandData);
$vueGenerator->generate();
if($this->confirm("\nDo you want to compile your vue files? [y|N]", false)){
shell_exec('yarn dev');
}
}
public function performPostActions($runMigration = false)
{
if ($this->commandData->getOption('save')) {
$this->saveSchemaFile();
}
if ($runMigration) {
if ($this->commandData->getOption('forceMigrate')) {
$this->runMigration();
} elseif (!$this->commandData->getOption('fromTable') and !$this->isSkip('migration')) {
$requestFromConsole = (php_sapi_name() == 'cli') ? true : false;
if ($this->commandData->getOption('jsonFromGUI') && $requestFromConsole) {
$this->runMigration();
} elseif ($requestFromConsole && $this->confirm("\nDo you want to migrate database? [y|N]", false)) {
$this->runMigration();
}
}
}
if (!$this->isSkip('dump-autoload')) {
$this->info('Generating autoload files');
$this->composer->dumpOptimized();
}
}
public function runMigration()
{
$migrationPath = database_path('migrations/');
$path = Str::after($migrationPath, base_path()); // get path after base_path
$this->call('migrate', ['--path' => $path, '--force' => true]);
return true;
}
public function isSkip($skip)
{
if ($this->commandData->getOption('skip')) {
return in_array($skip, (array) $this->commandData->getOption('skip'));
}
return false;
}
public function performPostActionsWithMigration()
{
$this->performPostActions(true);
}
private function saveSchemaFile()
{
$fileFields = [];
foreach ($this->commandData->fields as $field) {
$fileFields[] = [
'name' => $field->name,
'dbType' => $field->dbInput,
'htmlType' => $field->htmlInput,
'validations' => $field->validations,
'searchable' => $field->isSearchable,
'fillable' => $field->isFillable,
'primary' => $field->isPrimary,
'inForm' => $field->inForm,
'inIndex' => $field->inIndex,
'inView' => $field->inView,
];
}
foreach ($this->commandData->relations as $relation) {
$fileFields[] = [
'type' => 'relation',
'relation' => $relation->type.','.implode(',', $relation->inputs),
];
}
$path = app_path('Classes/CodeGenerator/Schemas/');
$fileName = $this->commandData->modelName.'.json';
if (file_exists($path.$fileName) && !$this->confirmOverwrite($fileName)) {
return;
}
FileUtil::createFile($path, $fileName, json_encode($fileFields, JSON_PRETTY_PRINT));
$this->commandData->commandComment("\nSchema File saved: ");
$this->commandData->commandInfo($fileName);
}
/**
* @param $fileName
* @param string $prompt
*
* @return bool
*/
protected function confirmOverwrite($fileName, $prompt = '')
{
$prompt = (empty($prompt))
? $fileName.' already exists. Do you want to overwrite it? [y|N]'
: $prompt;
return $this->confirm($prompt, false);
}
/**
* Get the console command options.
*
* @return array
*/
public function getOptions()
{
return [
['fieldsFile', null, InputOption::VALUE_REQUIRED, 'Fields input as json file'],
['jsonFromGUI', null, InputOption::VALUE_REQUIRED, 'Direct Json string while using GUI interface'],
['plural', null, InputOption::VALUE_REQUIRED, 'Plural Model name'],
['tableName', null, InputOption::VALUE_REQUIRED, 'Table Name'],
['fromTable', null, InputOption::VALUE_NONE, 'Generate from existing table'],
['ignoreFields', null, InputOption::VALUE_REQUIRED, 'Ignore fields while generating from table'],
['save', null, InputOption::VALUE_NONE, 'Save model schema to file'],
['primary', null, InputOption::VALUE_REQUIRED, 'Custom primary key'],
['prefix', null, InputOption::VALUE_REQUIRED, 'Prefix for all files'],
['paginate', null, InputOption::VALUE_REQUIRED, 'Pagination for index.blade.php'],
['skip', null, InputOption::VALUE_REQUIRED, 'Skip Specific Items to Generate (migration,model,controllers,api_controller,scaffold_controller,repository,requests,api_requests,scaffold_requests,routes,api_routes,scaffold_routes,views,tests,menu,dump-autoload)'],
['datatables', null, InputOption::VALUE_REQUIRED, 'Override datatables settings'],
['views', null, InputOption::VALUE_REQUIRED, 'Specify only the views you want generated: index,create,edit,show'],
['relations', null, InputOption::VALUE_NONE, 'Specify if you want to pass relationships for fields'],
['softDelete', null, InputOption::VALUE_NONE, 'Soft Delete Option'],
['forceMigrate', null, InputOption::VALUE_NONE, 'Specify if you want to run migration or not'],
['factory', null, InputOption::VALUE_NONE, 'To generate factory'],
['seeder', null, InputOption::VALUE_NONE, 'To generate seeder'],
['localized', null, InputOption::VALUE_NONE, 'Localize files.'],
['repositoryPattern', null, InputOption::VALUE_REQUIRED, 'Repository Pattern'],
['connection', null, InputOption::VALUE_REQUIRED, 'Specify connection name'],
];
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['model', InputArgument::REQUIRED, 'Singular Model name'],
];
}
}
@@ -0,0 +1,187 @@
<?php
namespace App\Classes\CodeGenerator\Commands;
use App\Classes\CodeGenerator\Common\CommandData;
use App\Classes\CodeGenerator\Generators\FactoryGenerator;
use App\Classes\CodeGenerator\Generators\Micros\DataTransferObjectGenerator;
use App\Classes\CodeGenerator\Generators\Micros\ResourceGenerator;
use App\Classes\CodeGenerator\Generators\Micros\RulesGenerator;
use App\Classes\CodeGenerator\Generators\Micros\ServicesGenerator;
use App\Classes\CodeGenerator\Generators\Micros\ValidatorsGenerator;
use App\Classes\CodeGenerator\Generators\MigrationGenerator;
use App\Classes\CodeGenerator\Generators\ModelGenerator;
use App\Classes\CodeGenerator\Generators\Scaffold\ControllersGenerator;
use App\Classes\CodeGenerator\Generators\Scaffold\ControllerLogicGenerator;
use App\Classes\CodeGenerator\Generators\Scaffold\RoutesGenerator;
use App\Classes\CodeGenerator\Generators\Scaffold\ViewsGenerator;
use App\Classes\CodeGenerator\Generators\Scaffold\VueGenerator;
use App\Classes\CodeGenerator\Generators\Scaffold\WebRouteGenerator;
use App\Classes\CodeGenerator\Generators\SeederGenerator;
use Illuminate\Console\Command;
use Illuminate\Support\Composer;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class RollbackGeneratorCommand extends Command
{
/**
* The command Data.
*
* @var CommandData
*/
public $commandData;
/**
* The console command name.
*
* @var string
*/
protected $name = 'code:rollback';
/**
* The console command description.
*
* @var string
*/
protected $description = 'rollback all files required for CRUD operations';
/**
* @var Composer
*/
public $composer;
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
$this->composer = app()['composer'];
}
/**
* Execute the command.
*
* @return void
*/
public function handle()
{
if (!in_array($this->argument('type'), [
'scaffold', 'micro'
])) {
$this->error('invalid rollback type');
}
$this->commandData = new CommandData($this, $this->argument('type'));
$this->commandData->config->mName = $this->commandData->modelName = $this->argument('model');
$this->commandData->config->init($this->commandData, ['tableName', 'prefix', 'plural', 'views']);
$this->rollbackCommon();
$this->rollbackMicros();
if($this->commandData->commandType === 'scaffold'){
$this->rollbackScaffold();
$this->rollbackViews();
}
$this->info('Generating autoload files');
$this->composer->dumpOptimized();
}
private function rollbackCommon(){
$migrationGenerator = new MigrationGenerator($this->commandData);
$migrationGenerator->rollback();
$modelGenerator = new ModelGenerator($this->commandData);
$modelGenerator->rollback();
$factoryGenerator = new FactoryGenerator($this->commandData);
$factoryGenerator->rollback();
$seederGenerator = new SeederGenerator($this->commandData);
$seederGenerator->rollback();
}
private function rollbackMicros(){
$dataTransferObjectGenerator = new DataTransferObjectGenerator($this->commandData);
$dataTransferObjectGenerator->rollback();
$serviceGenerator = new ServicesGenerator($this->commandData);
$serviceGenerator->rollback();
}
private function rollbackScaffold(){
$resourceGenerator = new ResourceGenerator($this->commandData);
$resourceGenerator->rollback();
$validatorsGenerator = new ValidatorsGenerator($this->commandData);
$validatorsGenerator->rollback();
$rulesGenerator = new RulesGenerator($this->commandData);
$rulesGenerator->rollback();
File::deleteDirectories(app_path('Classes/Modules/'. str::pluralStudly($this->commandData->modelName).'/Standards/'));
$routesGenerator = new RoutesGenerator($this->commandData);
$routesGenerator->rollback();
$webRouteGenerator = new WebRouteGenerator($this->commandData);
$webRouteGenerator->rollback();
$controllerGenerator = new ControllersGenerator($this->commandData);
$controllerGenerator->rollback();
$controllerLogicGenerator = new ControllerLogicGenerator($this->commandData);
$controllerLogicGenerator->rollback();
File::deleteDirectories(app_path('Classes/Modules/'. str::pluralStudly($this->commandData->modelName).'/'));
}
private function rollbackViews(){
$viewGenerator = new ViewsGenerator($this->commandData);
$viewGenerator->rollback();
$vueGenerator = new vueGenerator($this->commandData);
$vueGenerator->rollback();
}
/**
* Get the console command options.
*
* @return array
*/
public function getOptions()
{
return [
['tableName', null, InputOption::VALUE_REQUIRED, 'Table Name'],
['prefix', null, InputOption::VALUE_REQUIRED, 'Prefix for all files'],
['plural', null, InputOption::VALUE_REQUIRED, 'Plural Model name'],
['views', null, InputOption::VALUE_REQUIRED, 'Views to rollback'],
];
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['model', InputArgument::REQUIRED, 'Singular Model name'],
['type', InputArgument::REQUIRED, 'Rollback type: (micro / scaffold )'],
];
}
}
@@ -0,0 +1,91 @@
<?php
namespace App\Classes\CodeGenerator\Commands\Scaffold;
use App\Classes\CodeGenerator\Commands\BaseCommand;
use App\Classes\CodeGenerator\Common\CommandData;
class MicroGeneratorCommand extends BaseCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'code:micro';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Generate all files required for CRUD operations';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
$this->commandData = new CommandData($this, 'micro');
}
/**
* Execute the command.
*
* @return void
*/
public function handle()
{
parent::handle();
if ($this->checkIsThereAnyDataToGenerate()) {
$this->generateCommonItems();
$this->generateMicroItems();
$this->performPostActionsWithMigration();
} else {
$this->commandData->commandInfo('There are not enough input fields for scaffold generation.');
}
}
/**
* Get the console command options.
*
* @return array
*/
public function getOptions()
{
return array_merge(parent::getOptions(), []);
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return array_merge(parent::getArguments(), []);
}
/**
* Check if there is anything to generate.
*
* @return bool
*/
protected function checkIsThereAnyDataToGenerate()
{
if (count($this->commandData->fields) > 1) {
return true;
}
}
}
@@ -0,0 +1,96 @@
<?php
namespace App\Classes\CodeGenerator\Commands\Scaffold;
use App\Classes\CodeGenerator\Commands\BaseCommand;
use App\Classes\CodeGenerator\Common\CommandData;
class ScaffoldGeneratorCommand extends BaseCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'code:scaffold';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Generate all files required for CRUD operations';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
$this->commandData = new CommandData($this, 'scaffold');
}
/**
* Execute the command.
*
* @return void
*/
public function handle()
{
parent::handle();
if ($this->checkIsThereAnyDataToGenerate()) {
$this->generateCommonItems();
$this->generateMicroItems();
$this->generateScaffoldItems();
// $this->generateViews();
$this->performPostActionsWithMigration();
} else {
$this->commandData->commandInfo('There are not enough input fields for scaffold generation.');
}
}
/**
* Get the console command options.
*
* @return array
*/
public function getOptions()
{
return array_merge(parent::getOptions(), []);
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return array_merge(parent::getArguments(), []);
}
/**
* Check if there is anything to generate.
*
* @return bool
*/
protected function checkIsThereAnyDataToGenerate()
{
if (count($this->commandData->fields) > 1) {
return true;
}
}
}
@@ -0,0 +1,294 @@
<?php
namespace App\Classes\CodeGenerator\Common;
use App\Classes\CodeGenerator\Utils\GeneratorFieldsInputUtil;
use App\Classes\CodeGenerator\Utils\TableFieldsGenerator;
use Exception;
use Illuminate\Console\Command;
use Illuminate\Support\Str;
class CommandData
{
/** @var string */
public $modelName;
public $commandType;
/** @var GeneratorConfig */
public $config;
/** @var GeneratorField[] */
public $fields = [];
/** @var GeneratorFieldRelation[] */
public $relations = [];
/** @var Command */
public $commandObj;
/** @var TemplatesManager */
private $templateManager;
/** @var array */
public $dynamicVars = [];
public $fieldNamesMapping = [];
/** @var CommandData */
protected static $instance = null;
public static function getInstance()
{
return self::$instance;
}
public function getTemplatesManager()
{
return $this->templateManager;
}
/**
* @param Command $commandObj
* @param $commandType
* @param TemplatesManager $templatesManager
*/
public function __construct(Command $commandObj, $commandType, TemplatesManager $templatesManager = null)
{
$this->commandObj = $commandObj;
if (is_null($templatesManager)) {
$this->templateManager = app(TemplatesManager::class);
} else {
$this->templateManager = $templatesManager;
}
$this->commandType = $commandType;
$this->fieldNamesMapping = [
'$FIELD_NAME_TITLE$' => 'fieldTitle',
'$FIELD_NAME$' => 'name',
];
$this->config = new GeneratorConfig();
}
public function commandError($error)
{
$this->commandObj->error($error);
}
public function commandComment($message)
{
$this->commandObj->comment($message);
}
public function commandWarn($warning)
{
$this->commandObj->warn($warning);
}
public function commandInfo($message)
{
$this->commandObj->info($message);
}
public function initCommandData()
{
$this->config->init($this);
}
public function getOption($option)
{
return $this->config->getOption($option);
}
public function getAddOn($option)
{
return $this->config->getAddOn($option);
}
public function setOption($option, $value)
{
$this->config->setOption($option, $value);
}
public function addDynamicVariable($name, $val)
{
$this->dynamicVars[$name] = $val;
}
public function getFields()
{
$this->fields = [];
if ($this->getOption('fieldsFile') or $this->getOption('jsonFromGUI')) {
$this->getInputFromFileOrJson();
} elseif ($this->getOption('fromTable')) {
$this->getInputFromTable();
} else {
$this->getInputFromConsole();
}
}
private function getInputFromConsole()
{
$this->commandInfo('Specify fields for the model (skip id & timestamp fields, we will add it automatically)');
$this->commandInfo('Read docs carefully to specify field inputs)');
$this->commandInfo('Enter "exit" to finish');
$this->addPrimaryKey();
while (true) {
$fieldInputStr = $this->commandObj->ask('Field: (name db_type html_type options)', '');
if (empty($fieldInputStr) || $fieldInputStr == false || $fieldInputStr == 'exit') {
break;
}
if (!GeneratorFieldsInputUtil::validateFieldInput($fieldInputStr)) {
$this->commandError('Invalid Input. Try again');
continue;
}
$validations = $this->commandObj->ask('Enter validations: ', false);
$validations = ($validations == false) ? '' : $validations;
if ($this->getOption('relations')) {
$relation = $this->commandObj->ask('Enter relationship (Leave Blank to skip):', false);
} else {
$relation = '';
}
$this->fields[] = GeneratorFieldsInputUtil::processFieldInput(
$fieldInputStr,
$validations
);
if (!empty($relation)) {
$this->relations[] = GeneratorFieldRelation::parseRelation($relation);
}
}
$this->addTimestamps();
}
private function addPrimaryKey()
{
$primaryKey = new GeneratorField();
if ($this->getOption('primary')) {
$primaryKey->name = $this->getOption('primary');
} else {
$primaryKey->name = 'id';
}
$primaryKey->parseDBType('increments');
$primaryKey->parseOptions('s,f,p,if,ii');
$this->fields[] = $primaryKey;
}
private function addTimestamps()
{
$createdAt = new GeneratorField();
$createdAt->name = 'created_at';
$createdAt->parseDBType('timestamp');
$createdAt->parseOptions('s,f,if,ii');
$this->fields[] = $createdAt;
$updatedAt = new GeneratorField();
$updatedAt->name = 'updated_at';
$updatedAt->parseDBType('timestamp');
$updatedAt->parseOptions('s,f,if,ii');
$this->fields[] = $updatedAt;
}
private function getInputFromFileOrJson()
{
// fieldsFile option will get high priority than json option if both options are passed
try {
if ($this->getOption('fieldsFile')) {
$fieldsFileValue = $this->getOption('fieldsFile');
if (file_exists($fieldsFileValue)) {
$filePath = $fieldsFileValue;
} elseif (file_exists(base_path($fieldsFileValue))) {
$filePath = base_path($fieldsFileValue);
} else {
$schemaFileDirector = app_path('Classes/CodeGenerator/Schemas/');
$filePath = $schemaFileDirector.$fieldsFileValue;
}
if (!file_exists($filePath)) {
$this->commandError('Fields file not found');
exit;
}
$fileContents = file_get_contents($filePath);
$jsonData = json_decode($fileContents, true);
$this->fields = [];
foreach ($jsonData as $field) {
if (isset($field['type']) && $field['relation']) {
$this->relations[] = GeneratorFieldRelation::parseRelation($field['relation']);
} else {
$this->fields[] = GeneratorField::parseFieldFromFile($field);
if (isset($field['relation'])) {
$this->relations[] = GeneratorFieldRelation::parseRelation($field['relation']);
}
}
}
} else {
$fileContents = $this->getOption('jsonFromGUI');
$jsonData = json_decode($fileContents, true);
// override config options from jsonFromGUI
$this->config->overrideOptionsFromJsonFile($jsonData);
// Manage custom table name option
if (isset($jsonData['tableName'])) {
$tableName = $jsonData['tableName'];
$this->config->tableName = $tableName;
$this->addDynamicVariable('$TABLE_NAME$', $tableName);
$this->addDynamicVariable('$TABLE_NAME_TITLE$', Str::studly($tableName));
}
// Manage migrate option
if (isset($jsonData['migrate']) && $jsonData['migrate'] == false) {
$this->config->options['skip'][] = 'migration';
}
foreach ($jsonData['fields'] as $field) {
if (isset($field['type']) && $field['relation']) {
$this->relations[] = GeneratorFieldRelation::parseRelation($field['relation']);
} else {
$this->fields[] = GeneratorField::parseFieldFromFile($field);
if (isset($field['relation'])) {
$this->relations[] = GeneratorFieldRelation::parseRelation($field['relation']);
}
}
}
}
} catch (Exception $e) {
$this->commandError($e->getMessage());
exit;
}
}
private function getInputFromTable()
{
$tableName = $this->dynamicVars['$TABLE_NAME$'];
$ignoredFields = $this->getOption('ignoreFields');
if (!empty($ignoredFields)) {
$ignoredFields = explode(',', trim($ignoredFields));
} else {
$ignoredFields = [];
}
$tableFieldsGenerator = new TableFieldsGenerator($tableName, $ignoredFields, $this->config->connection);
$tableFieldsGenerator->prepareFieldsFromTable();
$tableFieldsGenerator->prepareRelations();
$this->fields = $tableFieldsGenerator->fields;
$this->relations = $tableFieldsGenerator->relations;
}
}
@@ -0,0 +1,26 @@
<?php
namespace App\Classes\CodeGenerator\Common;
use App\Classes\CodeGenerator\Generators\BaseGenerator;
use Illuminate\Support\Str;
class GenerateGetters extends BaseGenerator
{
public function generate($name, $type){
$functionPrefix = $type !== 'bool' ? 'get':'';
$template = $this->generatorHelpers->get_template('Micros.getter_function');
$template = str_replace('$FIELD_NAME$', str::camel($name), $template);
$template = str_replace('$DATA_TYPE$', $type, $template);
$template = str_replace('$FUNCTION_NAME$', $functionPrefix.str::studly($name), $template);
return $template;
}
}
@@ -0,0 +1,413 @@
<?php
namespace App\Classes\CodeGenerator\Common;
use Illuminate\Support\Str;
class GeneratorConfig
{
/* Namespace variables */
public $nsApp;
public $nsModel;
public $nsModelExtend;
public $nsController;
public $nsBaseController;
public $nsApiTests;
public $nsTestTraits;
public $nsTests;
/* Path variables */
public $pathModel;
public $pathFactory;
public $pathSeeder;
public $pathDatabaseSeeder;
public $pathApiRoutes;
public $pathApiTests;
public $pathController;
public $pathRoutes;
/* Model Names */
public $mName;
public $mPlural;
public $mCamel;
public $mCamelPlural;
public $mSnake;
public $mSnakePlural;
public $mDashed;
public $mDashedPlural;
public $mSlash;
public $mSlashPlural;
public $mHuman;
public $mHumanPlural;
public $connection = '';
/* Generator Options */
public $options;
/* Prefixes */
public $prefixes;
/** @var CommandData */
private $commandData;
/* Command Options */
public static $availableOptions = [
'fieldsFile',
'jsonFromGUI',
'tableName',
'fromTable',
'ignoreFields',
'save',
'primary',
'prefix',
'skip',
'views',
'relations',
'plural',
'softDelete',
'forceMigrate',
'factory',
'seeder',
];
public static $excludeFields = ['id', 'created_at', 'updated_at', 'deleted_at'];
public $tableName;
/** @var string */
protected $primaryName;
/* Generator AddOns */
public $addOns;
public function init(CommandData &$commandData, $options = null)
{
if (!empty($options)) {
self::$availableOptions = $options;
}
$this->mName = $commandData->modelName;
$this->prepareAddOns();
$this->prepareOptions($commandData);
$this->prepareModelNames();
$this->preparePrefixes();
$this->loadPaths();
$this->prepareTableName();
$this->preparePrimaryName();
$this->loadNamespaces($commandData);
$commandData = $this->loadDynamicVariables($commandData);
$this->commandData = &$commandData;
}
public function loadNamespaces(CommandData &$commandData)
{
$prefix = $this->prefixes['ns'];
if (!empty($prefix)) {
$prefix = '\\'.$prefix;
}
$this->nsApp = $commandData->commandObj->getLaravel()->getNamespace();
$this->nsApp = substr($this->nsApp, 0, strlen($this->nsApp) - 1);
$this->nsModel = 'App\Models';
$this->nsModelExtend = 'App\Models\AbstractModel';
$this->nsBaseController = 'App\Http\Controllers';
$this->nsController = 'App\Http\Controllers'.$prefix;
$this->nsApiTests = 'Tests\APIs';
$this->nsTests = 'Tests';
}
public function loadPaths()
{
$prefix = $this->prefixes['path'];
if (!empty($prefix)) {
$prefix .= '/';
}
$this->pathModel = app_path('Models/');
$this->pathApiRoutes = base_path('routes/api.php');
$this->pathApiTests = base_path('tests/APIs/');
$this->pathController = app_path('Http/Controllers/').$prefix;
$this->pathRoutes = base_path('routes/web.php');
$this->pathFactory = database_path('factories/');
$this->pathSeeder = database_path('seeds/');
$this->pathDatabaseSeeder = database_path('seeds/DatabaseSeeder.php');
}
public function loadDynamicVariables(CommandData &$commandData)
{
$commandData->addDynamicVariable('$NAMESPACE_APP$', $this->nsApp);
$commandData->addDynamicVariable('$NAMESPACE_MODEL$', $this->nsModel);
$commandData->addDynamicVariable('$NAMESPACE_MODEL_EXTEND$', $this->nsModelExtend);
$commandData->addDynamicVariable('$NAMESPACE_BASE_CONTROLLER$', $this->nsBaseController);
$commandData->addDynamicVariable('$NAMESPACE_CONTROLLER$', $this->nsController);
$commandData->addDynamicVariable('$NAMESPACE_API_TESTS$', $this->nsApiTests);
$commandData->addDynamicVariable('$NAMESPACE_TESTS$', $this->nsTests);
$commandData->addDynamicVariable('$TABLE_NAME$', $this->tableName);
$commandData->addDynamicVariable('$TABLE_NAME_TITLE$', Str::studly($this->tableName));
$commandData->addDynamicVariable('$PRIMARY_KEY_NAME$', $this->primaryName);
$commandData->addDynamicVariable('$MODEL_NAME$', $this->mName);
$commandData->addDynamicVariable('$MODEL_NAME_CAMEL$', $this->mCamel);
$commandData->addDynamicVariable('$MODEL_NAME_PLURAL$', $this->mPlural);
$commandData->addDynamicVariable('$MODEL_NAME_PLURAL_CAMEL$', $this->mCamelPlural);
$commandData->addDynamicVariable('$MODEL_NAME_SNAKE$', $this->mSnake);
$commandData->addDynamicVariable('$MODEL_NAME_PLURAL_SNAKE$', $this->mSnakePlural);
$commandData->addDynamicVariable('$MODEL_NAME_DASHED$', $this->mDashed);
$commandData->addDynamicVariable('$MODEL_NAME_PLURAL_DASHED$', $this->mDashedPlural);
$commandData->addDynamicVariable('$MODEL_NAME_SLASH$', $this->mSlash);
$commandData->addDynamicVariable('$MODEL_NAME_PLURAL_SLASH$', $this->mSlashPlural);
$commandData->addDynamicVariable('$MODEL_NAME_HUMAN$', $this->mHuman);
$commandData->addDynamicVariable('$MODEL_NAME_PLURAL_HUMAN$', $this->mHumanPlural);
$commandData->addDynamicVariable('$FILES$', '');
if (!empty($this->prefixes['route'])) {
$commandData->addDynamicVariable('$ROUTE_NAMED_PREFIX$', $this->prefixes['route'].'.');
$commandData->addDynamicVariable('$ROUTE_PREFIX$', str_replace('.', '/', $this->prefixes['route']).'/');
$commandData->addDynamicVariable('$RAW_ROUTE_PREFIX$', $this->prefixes['route']);
} else {
$commandData->addDynamicVariable('$ROUTE_PREFIX$', '');
$commandData->addDynamicVariable('$ROUTE_NAMED_PREFIX$', '');
}
if (!empty($this->prefixes['ns'])) {
$commandData->addDynamicVariable('$PATH_PREFIX$', $this->prefixes['ns'].'\\');
} else {
$commandData->addDynamicVariable('$PATH_PREFIX$', '');
}
if (!empty($this->prefixes['view'])) {
$commandData->addDynamicVariable('$VIEW_PREFIX$', str_replace('/', '.', $this->prefixes['view']).'.');
} else {
$commandData->addDynamicVariable('$VIEW_PREFIX$', '');
}
if (!empty($this->prefixes['public'])) {
$commandData->addDynamicVariable('$PUBLIC_PREFIX$', $this->prefixes['public']);
} else {
$commandData->addDynamicVariable('$PUBLIC_PREFIX$', '');
}
$commandData->addDynamicVariable(
'$API_PREFIX$',
'api'
);
$commandData->addDynamicVariable(
'$API_VERSION$',
'v1'
);
$commandData->addDynamicVariable('$SEARCHABLE$', '');
return $commandData;
}
public function prepareTableName()
{
if ($this->getOption('tableName')) {
$this->tableName = $this->getOption('tableName');
} else {
$this->tableName = $this->mSnakePlural;
}
}
public function preparePrimaryName()
{
if ($this->getOption('primary')) {
$this->primaryName = $this->getOption('primary');
} else {
$this->primaryName = 'id';
}
}
public function prepareModelNames()
{
if ($this->getOption('plural')) {
$this->mPlural = $this->getOption('plural');
} else {
$this->mPlural = Str::plural($this->mName);
}
$this->mCamel = Str::camel($this->mName);
$this->mCamelPlural = Str::camel($this->mPlural);
$this->mSnake = Str::snake($this->mName);
$this->mSnakePlural = Str::snake($this->mPlural);
$this->mDashed = str_replace('_', '-', Str::snake($this->mSnake));
$this->mDashedPlural = str_replace('_', '-', Str::snake($this->mSnakePlural));
$this->mSlash = str_replace('_', '/', Str::snake($this->mSnake));
$this->mSlashPlural = str_replace('_', '/', Str::snake($this->mSnakePlural));
$this->mHuman = Str::title(str_replace('_', ' ', Str::snake($this->mSnake)));
$this->mHumanPlural = Str::title(str_replace('_', ' ', Str::snake($this->mSnakePlural)));
}
public function prepareOptions(CommandData &$commandData)
{
foreach (self::$availableOptions as $option) {
$this->options[$option] = $commandData->commandObj->option($option);
}
if (isset($options['fromTable']) and $this->options['fromTable']) {
if (!$this->options['tableName']) {
$commandData->commandError('tableName required with fromTable option.');
exit;
}
}
$this->options['softDelete'] = true;
if (!empty($this->options['skip'])) {
$this->options['skip'] = array_map('trim', explode(',', $this->options['skip']));
}
}
public function preparePrefixes()
{
$this->prefixes['route'] = explode('/', '');
$this->prefixes['path'] = explode('/', '');
$this->prefixes['view'] = explode('.', '');
$this->prefixes['public'] = explode('/', '');
if ($this->getOption('prefix')) {
$multiplePrefixes = explode('/', $this->getOption('prefix'));
$this->prefixes['route'] = array_merge($this->prefixes['route'], $multiplePrefixes);
$this->prefixes['path'] = array_merge($this->prefixes['path'], $multiplePrefixes);
$this->prefixes['view'] = array_merge($this->prefixes['view'], $multiplePrefixes);
$this->prefixes['public'] = array_merge($this->prefixes['public'], $multiplePrefixes);
}
$this->prefixes['route'] = array_diff($this->prefixes['route'], ['']);
$this->prefixes['path'] = array_diff($this->prefixes['path'], ['']);
$this->prefixes['view'] = array_diff($this->prefixes['view'], ['']);
$this->prefixes['public'] = array_diff($this->prefixes['public'], ['']);
$routePrefix = '';
foreach ($this->prefixes['route'] as $singlePrefix) {
$routePrefix .= Str::camel($singlePrefix).'.';
}
if (!empty($routePrefix)) {
$routePrefix = substr($routePrefix, 0, strlen($routePrefix) - 1);
}
$this->prefixes['route'] = $routePrefix;
$nsPrefix = '';
foreach ($this->prefixes['path'] as $singlePrefix) {
$nsPrefix .= Str::title($singlePrefix).'\\';
}
if (!empty($nsPrefix)) {
$nsPrefix = substr($nsPrefix, 0, strlen($nsPrefix) - 1);
}
$this->prefixes['ns'] = $nsPrefix;
$pathPrefix = '';
foreach ($this->prefixes['path'] as $singlePrefix) {
$pathPrefix .= Str::title($singlePrefix).'/';
}
if (!empty($pathPrefix)) {
$pathPrefix = substr($pathPrefix, 0, strlen($pathPrefix) - 1);
}
$this->prefixes['path'] = $pathPrefix;
$viewPrefix = '';
foreach ($this->prefixes['view'] as $singlePrefix) {
$viewPrefix .= Str::camel($singlePrefix).'/';
}
if (!empty($viewPrefix)) {
$viewPrefix = substr($viewPrefix, 0, strlen($viewPrefix) - 1);
}
$this->prefixes['view'] = $viewPrefix;
$publicPrefix = '';
foreach ($this->prefixes['public'] as $singlePrefix) {
$publicPrefix .= Str::camel($singlePrefix).'/';
}
if (!empty($publicPrefix)) {
$publicPrefix = substr($publicPrefix, 0, strlen($publicPrefix) - 1);
}
$this->prefixes['public'] = $publicPrefix;
}
public function overrideOptionsFromJsonFile($jsonData)
{
$options = self::$availableOptions;
foreach ($options as $option) {
if (isset($jsonData['options'][$option])) {
$this->setOption($option, $jsonData['options'][$option]);
}
}
// prepare prefixes than reload namespaces, paths and dynamic variables
if (!empty($this->getOption('prefix'))) {
$this->preparePrefixes();
$this->loadPaths();
$this->loadNamespaces($this->commandData);
$this->loadDynamicVariables($this->commandData);
}
}
public function getOption($option)
{
if (isset($this->options[$option])) {
return $this->options[$option];
}
return false;
}
public function getAddOn($addOn)
{
if (isset($this->addOns[$addOn])) {
return $this->addOns[$addOn];
}
return false;
}
public function setOption($option, $value)
{
$this->options[$option] = $value;
}
public function prepareAddOns()
{
$this->addOns['tests'] = false;
}
public function excludeFields()
{
return self::$excludeFields;
}
}
@@ -0,0 +1,173 @@
<?php
namespace App\Classes\CodeGenerator\Common;
use Illuminate\Support\Str;
class GeneratorField
{
/** @var string */
public $name;
public $dbInput;
public $htmlInput;
public $htmlType;
public $fieldType;
public $description;
/** @var array */
public $htmlValues;
/** @var string */
public $migrationText;
public $foreignKeyText;
public $validations;
/** @var bool */
public $isSearchable = true;
public $isFillable = true;
public $isPrimary = false;
public $inForm = true;
public $inIndex = true;
public $inView = true;
public $isNotNull = false;
/**
* @param Column $column
* @param $dbInput
*/
public function parseDBType($dbInput, $column = null)
{
$this->dbInput = $dbInput;
if (!is_null($column)) {
$this->dbInput = ($column->getLength() > 0) ? $this->dbInput.','.$column->getLength() : $this->dbInput;
$this->dbInput = (!$column->getNotnull()) ? $this->dbInput.':nullable' : $this->dbInput;
}
$this->prepareMigrationText();
}
public function parseHtmlInput($htmlInput)
{
$this->htmlInput = $htmlInput;
$this->htmlValues = [];
if (empty($htmlInput)) {
$this->htmlType = 'text';
return;
}
if (Str::contains($htmlInput, 'selectTable')) {
$inputsArr = explode(':', $htmlInput);
$this->htmlType = array_shift($inputsArr);
$this->htmlValues = $inputsArr;
return;
}
$inputsArr = explode(',', $htmlInput);
$this->htmlType = array_shift($inputsArr);
if (count($inputsArr) > 0) {
$this->htmlValues = $inputsArr;
}
}
public function parseOptions($options)
{
$options = strtolower($options);
$optionsArr = explode(',', $options);
if (in_array('s', $optionsArr)) {
$this->isSearchable = false;
}
if (in_array('p', $optionsArr)) {
// if field is primary key, then its not searchable, fillable, not in index & form
$this->isPrimary = true;
$this->isSearchable = false;
$this->isFillable = false;
$this->inForm = false;
$this->inIndex = false;
$this->inView = false;
}
if (in_array('f', $optionsArr)) {
$this->isFillable = false;
}
if (in_array('if', $optionsArr)) {
$this->inForm = false;
}
if (in_array('ii', $optionsArr)) {
$this->inIndex = false;
}
if (in_array('iv', $optionsArr)) {
$this->inView = false;
}
}
private function prepareMigrationText()
{
$inputsArr = explode(':', $this->dbInput);
$this->migrationText = '$table->';
$fieldTypeParams = explode(',', array_shift($inputsArr));
$this->fieldType = array_shift($fieldTypeParams);
$this->migrationText .= $this->fieldType."('".$this->name."'";
if ($this->fieldType == 'enum') {
$this->migrationText .= ', [';
foreach ($fieldTypeParams as $param) {
$this->migrationText .= "'".$param."',";
}
$this->migrationText = substr($this->migrationText, 0, strlen($this->migrationText) - 1);
$this->migrationText .= ']';
} else {
foreach ($fieldTypeParams as $param) {
$this->migrationText .= ', '.$param;
}
}
$this->migrationText .= ')';
foreach ($inputsArr as $input) {
$inputParams = explode(',', $input);
$functionName = array_shift($inputParams);
if ($functionName == 'foreign') {
$foreignTable = array_shift($inputParams);
$foreignField = array_shift($inputParams);
$this->foreignKeyText .= "\$table->foreign('".$this->name."')->references('".$foreignField."')->on('".$foreignTable."');";
} else {
$this->migrationText .= '->'.$functionName;
$this->migrationText .= '(';
$this->migrationText .= implode(', ', $inputParams);
$this->migrationText .= ')';
}
}
$this->migrationText .= ';';
}
public static function parseFieldFromFile($fieldInput)
{
$field = new self();
$field->name = $fieldInput['name'];
$field->parseDBType($fieldInput['dbType']);
$field->parseHtmlInput(isset($fieldInput['htmlType']) ? $fieldInput['htmlType'] : '');
$field->validations = isset($fieldInput['validations']) ? $fieldInput['validations'] : '';
$field->isSearchable = isset($fieldInput['searchable']) ? $fieldInput['searchable'] : false;
$field->isFillable = isset($fieldInput['fillable']) ? $fieldInput['fillable'] : true;
$field->isPrimary = isset($fieldInput['primary']) ? $fieldInput['primary'] : false;
$field->inForm = isset($fieldInput['inForm']) ? $fieldInput['inForm'] : true;
$field->inIndex = isset($fieldInput['inIndex']) ? $fieldInput['inIndex'] : true;
$field->inView = isset($fieldInput['inView']) ? $fieldInput['inView'] : true;
return $field;
}
public function __get($key)
{
if ($key == 'fieldTitle') {
return Str::title(str_replace('_', ' ', $this->name));
}
return $this->$key;
}
}
@@ -0,0 +1,103 @@
<?php
namespace App\Classes\CodeGenerator\Common;
use Illuminate\Support\Str;
class GeneratorFieldRelation
{
/** @var string */
public $type;
public $inputs;
public $relationName;
public static function parseRelation($relationInput)
{
$inputs = explode(',', $relationInput);
$relation = new self();
$relation->type = array_shift($inputs);
$modelWithRelation = explode(':', array_shift($inputs)); //e.g ModelName:relationName
if (count($modelWithRelation) == 2) {
$relation->relationName = $modelWithRelation[1];
unset($modelWithRelation[1]);
}
$relation->inputs = array_merge($modelWithRelation, $inputs);
return $relation;
}
public function getRelationFunctionText($relationText = null)
{
$singularRelation = (!empty($this->relationName)) ? $this->relationName : Str::camel($relationText);
$pluralRelation = (!empty($this->relationName)) ? $this->relationName : Str::camel(Str::plural($relationText));
switch ($this->type) {
case '1t1':
$functionName = $singularRelation;
$relation = 'hasOne';
$relationClass = 'HasOne';
break;
case '1tm':
$functionName = $pluralRelation;
$relation = 'hasMany';
$relationClass = 'HasMany';
break;
case 'mt1':
if (!empty($this->relationName)) {
$singularRelation = $this->relationName;
} elseif (isset($this->inputs[1])) {
$singularRelation = Str::camel(str_replace('_id', '', strtolower($this->inputs[1])));
}
$functionName = $singularRelation;
$relation = 'belongsTo';
$relationClass = 'BelongsTo';
break;
case 'mtm':
$functionName = $pluralRelation;
$relation = 'belongsToMany';
$relationClass = 'BelongsToMany';
break;
case 'hmt':
$functionName = $pluralRelation;
$relation = 'hasManyThrough';
$relationClass = 'HasManyThrough';
break;
default:
$functionName = '';
$relation = '';
$relationClass = '';
break;
}
if (!empty($functionName) and !empty($relation)) {
return $this->generateRelation($functionName, $relation, $relationClass);
}
return '';
}
private function generateRelation($functionName, $relation, $relationClass)
{
$inputs = $this->inputs;
$modelName = array_shift($inputs);
$template = (new GeneratorHelpers())->get_template('Models.relationship');
$template = str_replace('$RELATIONSHIP_CLASS$', $relationClass, $template);
$template = str_replace('$FUNCTION_NAME$', $functionName, $template);
$template = str_replace('$RELATION$', $relation, $template);
$template = str_replace('$RELATION_MODEL_NAME$', $modelName, $template);
if (count($inputs) > 0) {
$inputFields = implode("', '", $inputs);
$inputFields = ", '".$inputFields."'";
} else {
$inputFields = '';
}
$template = str_replace('$INPUT_FIELDS$', $inputFields, $template);
return $template;
}
}
@@ -0,0 +1,78 @@
<?php
namespace App\Classes\CodeGenerator\Common;
use Illuminate\Support\Str;
class GeneratorHelpers
{
public function generator_tab($spaces = 4)
{
return str_repeat(' ', $spaces);
}
public function generator_tabs($tabs, $spaces = 4)
{
return str_repeat($this->generator_tab($spaces), $tabs);
}
public function generator_nl($count = 1)
{
return str_repeat(PHP_EOL, $count);
}
public function generator_nls($count, $nls = 1)
{
return str_repeat($this->generator_nl($nls), $count);
}
public function generator_nl_tab($lns = 1, $tabs = 1)
{
return $this->generator_nl($lns) . $this->generator_tabs($tabs);
}
public function get_template_file_path($templateName)
{
$templateName = str_replace('.', '/', $templateName);
return base_path('App/Classes/CodeGenerator/Stubs/'.$templateName.'.stub');
}
public function get_template($templateName)
{
$path = $this->get_template_file_path($templateName);
return file_get_contents($path);
}
public function fill_template($variables, $template)
{
foreach ($variables as $variable => $value) {
$template = str_replace($variable, $value, $template);
}
return $template;
}
public function fill_field_template($variables, $template, $field)
{
foreach ($variables as $variable => $key) {
$template = str_replace($variable, $field->$key, $template);
}
return $template;
}
public function fill_template_with_field_data($variables, $fieldVariables, $template, $field)
{
$template = $this->fill_template($variables, $template);
return $this->fill_field_template($fieldVariables, $template, $field);
}
public function model_name_from_table_name($tableName)
{
return Str::ucfirst(Str::camel(Str::singular($tableName)));
}
}
@@ -0,0 +1,24 @@
<?php
namespace App\Classes\CodeGenerator\Common;
class TemplatesManager
{
protected $useLocale = false;
/**
* @return bool
*/
public function isUsingLocale(): bool
{
return $this->useLocale;
}
/**
* @param bool $useLocale
*/
public function setUseLocale(bool $useLocale): void
{
$this->useLocale = $useLocale;
}
}
@@ -0,0 +1,31 @@
<?php
namespace App\Classes\CodeGenerator\Generators;
use App\Classes\CodeGenerator\Common\GeneratorHelpers;
use App\Classes\CodeGenerator\Utils\FileUtil;
class BaseGenerator
{
/** @var GeneratorHelpers */
public $generatorHelpers;
/**
* BaseGenerator constructor.
*/
public function __construct()
{
$this->generatorHelpers = new GeneratorHelpers();
}
public function rollbackFile($path, $fileName)
{
if (file_exists($path.$fileName)) {
return FileUtil::deleteFile($path, $fileName);
}
return false;
}
}
@@ -0,0 +1,119 @@
<?php
namespace App\Classes\CodeGenerator\Generators;
use App\Classes\CodeGenerator\Common\CommandData;
use App\Classes\CodeGenerator\Utils\FileUtil;
use App\Classes\CodeGenerator\Utils\GeneratorFieldsInputUtil;
use Illuminate\Support\Str;
/**
* Class FactoryGenerator.
*/
class FactoryGenerator extends BaseGenerator
{
/** @var CommandData */
private $commandData;
/** @var string */
private $path;
/** @var string */
private $fileName;
/**
* FactoryGenerator constructor.
*
* @param CommandData $commandData
*/
public function __construct(CommandData $commandData)
{
parent::__construct();
$this->commandData = $commandData;
$this->path = $commandData->config->pathFactory;
$this->fileName = Str::studly(Str::singular($this->commandData->modelName)).'Factory.php';
}
public function generate()
{
$templateData = $this->generatorHelpers->get_template('Factories.model_factory');
$templateData = $this->fillTemplate($templateData);
FileUtil::createFile($this->path, $this->fileName, $templateData);
$this->commandData->commandObj->comment("\nFactory created: ");
$this->commandData->commandObj->info($this->fileName);
}
/**
* @param string $templateData
*
* @return mixed|string
*/
private function fillTemplate($templateData)
{
$templateData = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $templateData);
$templateData = str_replace(
'$FIELDS$',
implode(','.$this->generatorHelpers->generator_nl_tab(1, 2), $this->generateFields()),
$templateData
);
return $templateData;
}
/**
* @return array
*/
private function generateFields()
{
$fields = [];
foreach ($this->commandData->fields as $field) {
if ($field->isPrimary) {
continue;
}
$fieldData = "'".$field->name."' => ".'$faker->';
switch ($field->fieldType) {
case 'integer':
case 'float':
$fakerData = 'randomDigitNotNull';
break;
case 'string':
$fakerData = 'word';
break;
case 'text':
$fakerData = 'text';
break;
case 'datetime':
case 'timestamp':
$fakerData = "date('Y-m-d H:i:s')";
break;
case 'enum':
$fakerData = 'randomElement('.
GeneratorFieldsInputUtil::prepareValuesArrayStr($field->htmlValues).
')';
break;
default:
$fakerData = 'word';
}
$fieldData .= $fakerData;
$fields[] = $fieldData;
}
return $fields;
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->fileName)) {
$this->commandData->commandComment('Factory file deleted: '.$this->fileName);
}
}
}
@@ -0,0 +1,140 @@
<?php
namespace App\Classes\CodeGenerator\Generators\Micros;
use App\Classes\CodeGenerator\Common\CommandData;
use App\Classes\CodeGenerator\Common\GenerateGetters;
use App\Classes\CodeGenerator\Generators\BaseGenerator;
use App\Classes\CodeGenerator\Utils\FileUtil;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
class DataTransferObjectGenerator extends BaseGenerator
{
/** @var CommandData */
private $commandData;
/** @var string */
private $path;
/** @var string */
private $fileName;
/**
* FactoryGenerator constructor.
*
* @param CommandData $commandData
*/
public function __construct(CommandData $commandData)
{
parent::__construct();
$this->commandData = $commandData;
$this->path = app_path('Classes/Modules/'. str::pluralStudly($this->commandData->modelName).'/DataTransferObjects/');
$this->fileName = Str::studly(Str::singular($this->commandData->modelName)).'Object.php';
}
public function generate()
{
$templateData = $this->generatorHelpers->get_template('Micros.data_transfer_object');
$templateData = $this->fillTemplate($templateData);
FileUtil::createFile($this->path, $this->fileName, $templateData);
$this->commandData->commandComment("\nDataTransferObject created: ");
$this->commandData->commandObj->info($this->fileName);
}
/**
* @param string $templateData
*
* @return mixed|string
*/
private function fillTemplate($templateData)
{
$properties = [];
$docs = [];
$injection = [];
$body = [];
$getters = [];
foreach ($this->commandData->fields as $field) {
if(!in_array($field->name, $this->commandData->config->excludeFields())){
$docType = $this->getPHPDocType($field->fieldType);
$fieldName = $docType === 'bool' ? 'is'.str::studly($field->name) : str::camel($field->name);
$properties[] = '/** @var '.$docType.' */'.PHP_EOL.$this->generatorHelpers->generator_nl_tab(0, 1).'private $'.str::camel($fieldName).';';
$docs[] = '* @param '.$docType.' $'.str::camel($fieldName);
$injection[] = $docType.' $'.str::camel($fieldName);
$body[] = '$this->'.str::camel($fieldName).' = $'.str::camel($fieldName).';';
$getters[] = (new GenerateGetters())->generate($fieldName, $docType);
}
}
$templateData = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $templateData);
$templateData = str_replace(
'$PROPERTIES$',
implode(PHP_EOL.$this->generatorHelpers->generator_nl_tab(1, 1), $properties),
$templateData
);
$templateData = str_replace(
'$CONSTRUCTOR_DOCS$',
implode($this->generatorHelpers->generator_nl_tab(1, 2), $docs),
$templateData
);
$templateData = str_replace(
'$CONSTRUCTOR_PROPERTIES$',
implode(', ', $injection),
$templateData
);
$templateData = str_replace(
'$CONSTRUCTOR_BODY$',
implode($this->generatorHelpers->generator_nl_tab(1, 2), $body),
$templateData
);
$templateData = str_replace(
'$GETTER_FUNCTIONS$',
implode($this->generatorHelpers->generator_nl_tab(1, 0), $getters),
$templateData
);
return $templateData;
}
private function getPHPDocType($db_type){
switch ($db_type) {
case 'text':
return 'string';
case 'datetime':
return '\Carbon\Carbon';
case 'boolean':
return 'bool';
default:
return $db_type;
}
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->fileName)) {
File::deleteDirectory($this->path);
$this->commandData->commandComment('DataTransferObject file deleted: '.$this->fileName);
}
}
}
@@ -0,0 +1,75 @@
<?php
namespace App\Classes\CodeGenerator\Generators\Micros;
use App\Classes\CodeGenerator\Common\CommandData;
use App\Classes\CodeGenerator\Generators\BaseGenerator;
use App\Classes\CodeGenerator\Utils\FileUtil;
use Illuminate\Support\Str;
class ResourceGenerator extends BaseGenerator
{
/** @var CommandData */
private $commandData;
/** @var string */
private $path;
/** @var string */
private $fileName;
/**
* FactoryGenerator constructor.
*
* @param CommandData $commandData
*/
public function __construct(CommandData $commandData)
{
parent::__construct();
$this->commandData = $commandData;
$this->path = app_path('Http/Resources/');
$this->fileName = Str::studly(Str::singular($this->commandData->modelName)).'Resource.php';
}
public function generate()
{
$templateData = $this->generatorHelpers->get_template('Resource.model_resource');
$templateData = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $templateData);
$templateData = str_replace('$FIELDS$', implode(','.$this->generatorHelpers->generator_nl_tab(1, 3), $this->generateFields()), $templateData);
FileUtil::createFile($this->path, $this->fileName, $templateData);
$this->commandData->commandComment("\n Resource Object created: ");
$this->commandData->commandObj->info($this->fileName);
}
private function generateFields()
{
$fields = [];
foreach ($this->commandData->fields as $field) {
$field = "'" . $field->name . "' => " . "$" . "this->" . str::snake($field->name);
$fields[] = $field;
}
return $fields;
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->fileName)) {
$this->commandData->commandComment('Resource Object file deleted: '.$this->fileName);
}
}
}
@@ -0,0 +1,68 @@
<?php
namespace App\Classes\CodeGenerator\Generators\Micros;
use App\Classes\CodeGenerator\Common\CommandData;
use App\Classes\CodeGenerator\Generators\BaseGenerator;
use App\Classes\CodeGenerator\Utils\FileUtil;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
class RulesGenerator extends BaseGenerator
{
/** @var CommandData */
private $commandData;
/** @var string */
private $path;
/**
* FactoryGenerator constructor.
*
* @param CommandData $commandData
*/
public function __construct(CommandData $commandData)
{
parent::__construct();
$this->commandData = $commandData;
$this->path = app_path('Classes/Modules/'. str::pluralStudly($this->commandData->modelName).'/Standards/Rules/');
}
public function generate()
{
foreach(['create', 'list', 'fetch', 'update', 'delete'] as $type){
$name = $type === 'list' ? str::pluralStudly($this->commandData->modelName) : str::singular($this->commandData->modelName);
$filename = 'Can'.str::studly($type.$name).'.php';
$templateData = $this->generatorHelpers->get_template('Rules.can_'.$type);
$templateData = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $templateData);
FileUtil::createFile($this->path, $filename, $templateData);
$this->commandData->commandComment("\n" . $type . " Rules created: ");
$this->commandData->commandObj->info($filename);
}
}
public function rollback()
{
foreach(['create', 'list', 'fetch', 'update', 'delete'] as $type){
$name = $type === 'list' ? str::pluralStudly($this->commandData->modelName) : str::singular($this->commandData->modelName);
$filename ='Can'.str::studly($type.$name).'.php';
if ($this->rollbackFile($this->path, $filename)) {
$this->commandData->commandComment($type . ' Rules file deleted: '.$filename);
}
}
File::deleteDirectory($this->path);
}
}
@@ -0,0 +1,96 @@
<?php
namespace App\Classes\CodeGenerator\Generators\Micros;
use App\Classes\CodeGenerator\Common\CommandData;
use App\Classes\CodeGenerator\Generators\BaseGenerator;
use App\Classes\CodeGenerator\Utils\FileUtil;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
class ServicesGenerator extends BaseGenerator
{
/** @var CommandData */
private $commandData;
/** @var string */
private $path;
/**
* FactoryGenerator constructor.
*
* @param CommandData $commandData
*/
public function __construct(CommandData $commandData)
{
parent::__construct();
$this->commandData = $commandData;
$this->path = app_path('Classes/Modules/'. str::pluralStudly($this->commandData->modelName).'/Services/');
}
public function generate()
{
foreach(['create', 'list', 'fetch', 'update', 'delete'] as $type){
$name = $type === 'list' ? str::pluralStudly($this->commandData->modelName) : str::singular($this->commandData->modelName);
$filename = str::studly($type.($type === 'fetch'?'es':'s').$name).'.php';
$templateData = $this->generatorHelpers->get_template("Services.".str::snake($type.'_service'));
$templateData = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $templateData);
$templateData = str_replace(
'$FIELDS$',
implode($this->generatorHelpers->generator_nl_tab(1, 2), $this->generateFields()),
$templateData
);
FileUtil::createFile($this->path, $filename, $templateData);
$this->commandData->commandComment("\n" . $type . " service class created: ");
$this->commandData->commandObj->info($filename);
}
}
private function generateFields()
{
$fields = [];
foreach ($this->commandData->fields as $field) {
if(!in_array($field->name, $this->commandData->config->excludeFields())) {
$getterName = $field->dbInput === 'boolean' ? 'is' . str::studly($field->name) : 'get' . str::studly($field->name);
$field = "$" . "model->" . $field->name . " = $" . "object->" . $getterName . "();";
$fields[] = $field;
}
}
return $fields;
}
public function rollback()
{
foreach(['create', 'list', 'fetch', 'update', 'delete'] as $type){
$name = $type === 'list' ? str::pluralStudly($this->commandData->modelName) : str::singular($this->commandData->modelName);
$filename = str::studly($type.($type === 'fetch'?'es':'s').$name).'.php';
if ($this->rollbackFile($this->path, $filename)) {
$this->commandData->commandComment( $type . ' service class file deleted: '.$filename);
}
}
File::deleteDirectory(($this->path));
}
}
@@ -0,0 +1,112 @@
<?php
namespace App\Classes\CodeGenerator\Generators\Micros;
use App\Classes\CodeGenerator\Common\CommandData;
use App\Classes\CodeGenerator\Generators\BaseGenerator;
use App\Classes\CodeGenerator\Utils\FileUtil;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
class ValidatorsGenerator extends BaseGenerator
{
/** @var CommandData */
private $commandData;
/** @var string */
private $path;
/** @var string */
private $fileName;
/**
* FactoryGenerator constructor.
*
* @param CommandData $commandData
*/
public function __construct(CommandData $commandData)
{
parent::__construct();
$this->commandData = $commandData;
$this->path = app_path('Classes/Modules/'. str::pluralStudly($this->commandData->modelName).'/Standards/Validators/');
$this->fileName = Str::studly(Str::singular($this->commandData->modelName)).'Validation.php';
}
public function generate()
{
$templateData = $this->generatorHelpers->get_template('Validator.request_validation');
$templateData = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $templateData);
$templateData = str_replace('$FIELDS$', implode(','.$this->generatorHelpers->generator_nl_tab(1, 3), $this->generateFields()), $templateData);
$templateData = str_replace('$RULES$', implode(','.$this->generatorHelpers->generator_nl_tab(1, 3), $this->generateRules()), $templateData);
FileUtil::createFile($this->path, $this->fileName, $templateData);
$this->commandData->commandComment("\n Request Validator created: ");
$this->commandData->commandObj->info($this->fileName);
}
private function generateRules()
{
$dont_require_fields = [];
$rules = [];
foreach ($this->commandData->fields as $field) {
if (!$field->isPrimary && $field->isNotNull && empty($field->validations) &&
!in_array($field->name, $dont_require_fields)) {
$field->validations = 'required';
}
if (!empty($field->validations)) {
if (Str::contains($field->validations, 'unique:')) {
$rule = explode('|', $field->validations);
// move unique rule to last
usort($rule, function ($record) {
return (Str::contains($record, 'unique:')) ? 1 : 0;
});
$field->validations = implode('|', $rule);
}
$rule = "'".$field->name."' => '".$field->validations."'";
$rules[] = $rule;
}
}
return $rules;
}
private function generateFields()
{
$fields = [];
foreach ($this->commandData->fields as $field) {
if(!in_array($field->name, $this->commandData->config->excludeFields())) {
$getterName = $field->dbInput === 'boolean' ? 'is' . str::studly($field->name) : 'get' . str::studly($field->name);
$field = "'" . $field->name . "' => " . "$" . "object->" . $getterName . "()";
$fields[] = $field;
}
}
return $fields;
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->fileName)) {
File::deleteDirectory($this->path);
$this->commandData->commandComment('Request Validation file deleted: '.$this->fileName);
}
}
}
@@ -0,0 +1,92 @@
<?php
namespace App\Classes\CodeGenerator\Generators;
use Illuminate\Support\Facades\File;
use App\Classes\CodeGenerator\Common\CommandData;
use App\Classes\CodeGenerator\Utils\FileUtil;
use Illuminate\Support\Str;
class MigrationGenerator extends BaseGenerator
{
/** @var CommandData */
private $commandData;
/** @var string */
private $path;
public function __construct($commandData)
{
parent::__construct();
$this->commandData = $commandData;
$this->path = database_path('migrations/');
}
public function generate()
{
$templateData = $this->generatorHelpers->get_template('Migration.migration');
$templateData = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $templateData);
$templateData = str_replace('$FIELDS$', $this->generateFields(), $templateData);
$tableName = $this->commandData->dynamicVars['$TABLE_NAME$'];
$fileName = date('Y_m_d_His').'_'.'create_'.Str::snake(Str::plural($tableName)).'_table.php';
FileUtil::createFile($this->path, $fileName, $templateData);
$this->commandData->commandComment("\nMigration created: ");
$this->commandData->commandInfo($fileName);
}
private function generateFields()
{
$fields = [];
$foreignKeys = [];
$createdAtField = null;
$updatedAtField = null;
$fields[] = '$table->id();';
foreach ($this->commandData->fields as $field) {
$fields[] = $field->migrationText;
if (!empty($field->foreignKeyText)) {
$foreignKeys[] = $field->foreignKeyText;
}
}
$fields[] = '$table->timestamps();';
if ($this->commandData->getOption('softDelete')) {
$fields[] = '$table->softDeletes();';
}
return implode($this->generatorHelpers->generator_nl_tab(1, 3), array_merge($fields, $foreignKeys));
}
public function rollback()
{
$fileName = 'create_'.$this->commandData->config->tableName.'_table.php';
$allFiles = File::allFiles($this->path);
$files = [];
foreach ($allFiles as $file) {
$files[] = $file->getFilename();
}
$files = array_reverse($files);
foreach ($files as $file) {
if (Str::contains($file, $fileName)) {
if ($this->rollbackFile($this->path, $file)) {
$this->commandData->commandComment('Migration file deleted: '.$file);
}
break;
}
}
}
}
@@ -0,0 +1,351 @@
<?php
namespace App\Classes\CodeGenerator\Generators;
use App\Classes\CodeGenerator\Common\CommandData;
use App\Classes\CodeGenerator\Common\GeneratorFieldRelation;
use App\Classes\CodeGenerator\Utils\FileUtil;
use App\Classes\CodeGenerator\Utils\TableFieldsGenerator;
use Illuminate\Support\Str;
class ModelGenerator extends BaseGenerator
{
/**
* Fields not included in the generator by default.
*
* @var array
*/
protected $excluded_fields = [
'created_at',
'updated_at',
];
/** @var CommandData */
private $commandData;
/** @var string */
private $path;
private $fileName;
private $table;
/**
* ModelGenerator constructor.
*
* @param CommandData $commandData
*/
public function __construct(CommandData $commandData)
{
parent::__construct();
$this->commandData = $commandData;
$this->path = $commandData->config->pathModel;
$this->fileName = Str::studly(Str::singular($this->commandData->modelName)).'.php';
$this->table = $this->commandData->dynamicVars['$TABLE_NAME$'];
}
public function generate()
{
$templateData = $this->generatorHelpers->get_template('Models.model');
$templateData = $this->fillTemplate($templateData);
FileUtil::createFile($this->path, $this->fileName, $templateData);
$this->commandData->commandComment("\nModel created: ");
$this->commandData->commandInfo($this->fileName);
}
private function fillTemplate($templateData)
{
$templateData = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $templateData);
$templateData = $this->fillSoftDeletes($templateData);
$fillables = [];
foreach ($this->commandData->fields as $field) {
if ($field->isFillable) {
$fillables[] = "'".$field->name."'";
}
}
$templateData = $this->fillDocs($templateData);
$templateData = $this->fillTimestamps($templateData);
if ($this->commandData->getOption('primary')) {
$primary = $this->generatorHelpers->generator_tab()."protected \$primaryKey = '".$this->commandData->getOption('primary')."';\n";
} else {
$primary = '';
}
$templateData = str_replace('$PRIMARY$', $primary, $templateData);
$templateData = str_replace('$FIELDS$', implode(','.$this->generatorHelpers->generator_nl_tab(1, 2), $fillables), $templateData);
$templateData = str_replace('$RULES$', implode(','.$this->generatorHelpers->generator_nl_tab(1, 2), $this->generateRules()), $templateData);
$templateData = str_replace('$CAST$', implode(','.$this->generatorHelpers->generator_nl_tab(1, 2), $this->generateCasts()), $templateData);
$templateData = str_replace(
'$RELATIONS$',
$this->generatorHelpers->fill_template($this->commandData->dynamicVars, implode(PHP_EOL.$this->generatorHelpers->generator_nl_tab(1, 1), $this->generateRelations())),
$templateData
);
$templateData = str_replace('$GENERATE_DATE$', date('F j, Y, g:i a T'), $templateData);
return $templateData;
}
private function fillSoftDeletes($templateData)
{
if (!$this->commandData->getOption('softDelete')) {
$templateData = str_replace('$SOFT_DELETE_IMPORT$', '', $templateData);
$templateData = str_replace('$SOFT_DELETE$', '', $templateData);
$templateData = str_replace('$SOFT_DELETE_DATES$', '', $templateData);
} else {
$templateData = str_replace(
'$SOFT_DELETE_IMPORT$',
"use Illuminate\\Database\\Eloquent\\SoftDeletes;\n",
$templateData
);
$templateData = str_replace('$SOFT_DELETE$', $this->generatorHelpers->generator_tab()."use SoftDeletes;\n", $templateData);
$deletedAtTimestamp = 'deleted_at';
$templateData = str_replace(
'$SOFT_DELETE_DATES$',
$this->generatorHelpers->generator_nl_tab()."protected \$dates = ['".$deletedAtTimestamp."'];\n",
$templateData
);
}
return $templateData;
}
private function fillDocs($templateData)
{
$docsTemplate = $this->generatorHelpers->get_template('Docs.model');
$docsTemplate = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $docsTemplate);
$fillables = '';
$fieldsArr = [];
$count = 1;
foreach ($this->commandData->relations as $relation) {
$field = $relationText = (isset($relation->inputs[0])) ? $relation->inputs[0] : null;
if (in_array($field, $fieldsArr)) {
$relationText = $relationText.'_'.$count;
$count++;
}
$fillables .= ' * @property '.$this->getPHPDocType($relation->type, $relation, $relationText).PHP_EOL;
$fieldsArr[] = $field;
}
foreach ($this->commandData->fields as $field) {
if ($field->isFillable) {
$fillables .= ' * @property '.$this->getPHPDocType($field->fieldType).' '.$field->name.PHP_EOL;
}
}
$docsTemplate = str_replace('$GENERATE_DATE$', date('F j, Y, g:i a'), $docsTemplate);
$docsTemplate = str_replace('$PHPDOC$', $fillables, $docsTemplate);
$templateData = str_replace('$DOCS$', $docsTemplate, $templateData);
return $templateData;
}
/**
* @param $db_type
* @param GeneratorFieldRelation|null $relation
* @param string|null $relationText
*
* @return string
*/
private function getPHPDocType($db_type, $relation = null, $relationText = null)
{
$relationText = (!empty($relationText)) ? $relationText : null;
switch ($db_type) {
case 'text':
return 'string';
case 'datetime':
return 'string|\Carbon\Carbon';
case '1t1':
return '\\'.$this->commandData->config->nsModel.'\\'.$relation->inputs[0].' '.Str::camel($relationText);
case 'mt1':
if (isset($relation->inputs[1])) {
$relationName = str_replace('_id', '', strtolower($relation->inputs[1]));
} else {
$relationName = $relationText;
}
return '\\'.$this->commandData->config->nsModel.'\\'.$relation->inputs[0].' '.Str::camel($relationName);
case '1tm':
case 'mtm':
case 'hmt':
return '\Illuminate\Database\Eloquent\Collection'.' '.Str::camel(Str::plural($relationText));
default:
if (!empty($fieldData['fieldType'])) {
return $fieldData['fieldType'];
}
return $db_type;
}
}
private function fillTimestamps($templateData)
{
$timestamps = TableFieldsGenerator::getTimestampFieldNames();
$replace = '';
if (empty($timestamps)) {
$replace = $this->generatorHelpers->generator_nl_tab()."public \$timestamps = false;\n";
}
if ($this->commandData->getOption('fromTable') && !empty($timestamps)) {
list($created_at, $updated_at) = collect($timestamps)->map(function ($field) {
return !empty($field) ? "'$field'" : 'null';
});
$replace .= $this->generatorHelpers->generator_nl_tab()."const CREATED_AT = $created_at;";
$replace .= $this->generatorHelpers->generator_nl_tab()."const UPDATED_AT = $updated_at;\n";
}
return str_replace('$TIMESTAMPS$', $replace, $templateData);
}
private function generateRules()
{
$dont_require_fields = [];
$rules = [];
foreach ($this->commandData->fields as $field) {
if (!$field->isPrimary && $field->isNotNull && empty($field->validations) &&
!in_array($field->name, $dont_require_fields)) {
$field->validations = 'required';
}
if (!empty($field->validations)) {
if (Str::contains($field->validations, 'unique:')) {
$rule = explode('|', $field->validations);
// move unique rule to last
usort($rule, function ($record) {
return (Str::contains($record, 'unique:')) ? 1 : 0;
});
$field->validations = implode('|', $rule);
}
$rule = "'".$field->name."' => '".$field->validations."'";
$rules[] = $rule;
}
}
return $rules;
}
public function generateUniqueRules()
{
$tableNameSingular = Str::singular($this->commandData->config->tableName);
$uniqueRules = '';
foreach ($this->generateRules() as $rule) {
if (Str::contains($rule, 'unique:')) {
$rule = explode('=>', $rule);
$string = '$rules['.trim($rule[0]).'].","';
$uniqueRules .= '$rules['.trim($rule[0]).'] = '.$string.'.$this->route("'.$tableNameSingular.'");';
}
}
return $uniqueRules;
}
public function generateCasts()
{
$casts = [];
$timestamps = TableFieldsGenerator::getTimestampFieldNames();
foreach ($this->commandData->fields as $field) {
if (in_array($field->name, $timestamps)) {
continue;
}
$rule = "'".$field->name."' => ";
switch (strtolower($field->fieldType)) {
case 'integer':
case 'increments':
case 'smallinteger':
case 'long':
case 'biginteger':
$rule .= "'integer'";
break;
case 'double':
$rule .= "'double'";
break;
case 'float':
case 'decimal':
$rule .= "'float'";
break;
case 'boolean':
$rule .= "'boolean'";
break;
case 'datetime':
case 'datetimetz':
$rule .= "'datetime'";
break;
case 'date':
$rule .= "'date'";
break;
case 'enum':
case 'string':
case 'char':
case 'text':
$rule .= "'string'";
break;
default:
$rule = '';
break;
}
if (!empty($rule)) {
$casts[] = $rule;
}
}
return $casts;
}
private function generateRelations()
{
$relations = [];
$count = 1;
$fieldsArr = [];
foreach ($this->commandData->relations as $relation) {
$field = (isset($relation->inputs[0])) ? $relation->inputs[0] : null;
$relationShipText = $field;
if (in_array($field, $fieldsArr)) {
$relationShipText = $relationShipText.'_'.$count;
$count++;
}
$relationText = $relation->getRelationFunctionText($relationShipText);
if (!empty($relationText)) {
$fieldsArr[] = $field;
$relations[] = $relationText;
}
}
return $relations;
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->fileName)) {
$this->commandData->commandComment('Model file deleted: '.$this->fileName);
}
}
}
@@ -0,0 +1,83 @@
<?php
namespace App\Classes\CodeGenerator\Generators\Scaffold;
use App\Classes\CodeGenerator\Common\CommandData;
use App\Classes\CodeGenerator\Generators\BaseGenerator;
use App\Classes\CodeGenerator\Utils\FileUtil;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
class ControllerLogicGenerator extends BaseGenerator
{
/** @var CommandData */
private $commandData;
/** @var string */
private $path;
public function __construct(CommandData $commandData)
{
parent::__construct();
$this->commandData = $commandData;
$this->path = app_path('Classes/Modules/'. str::pluralStudly($this->commandData->modelName).'/ControllersLogic/');
}
public function generate()
{
foreach(['create', 'list', 'fetch', 'update', 'delete'] as $type){
$name = $type === 'list' ? str::pluralStudly($this->commandData->modelName) : str::singular($this->commandData->modelName);
$filename = str::studly($type.$name).'Logic.php';
$templateData = $this->generatorHelpers->get_template("Scaffold.ControllersLogic.".$type."_controller_logic");
$templateData = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $templateData);
$templateData = str_replace(
'$REQUEST_FIELDS$',
implode(', ', $this->generateFields()),
$templateData
);
FileUtil::createFile($this->path, $filename, $templateData);
$this->commandData->commandComment("\n" . $type . " Controller logic created: ");
$this->commandData->commandInfo($filename);
}
}
private function generateFields(){
$fields = [];
foreach ($this->commandData->fields as $field) {
if(!in_array($field->name, $this->commandData->config->excludeFields())) {
$fields[] = '$request->input(\'' . $field->name . '\')';
}
}
return $fields;
}
public function rollback()
{
foreach(['create', 'list', 'fetch', 'update', 'delete'] as $type){
$name = $type === 'list' ? str::pluralStudly($this->commandData->modelName) : str::singular($this->commandData->modelName);
$filename = str::studly($type.$name).'Logic.php';
if ($this->rollbackFile($this->path, $filename)) {
$this->commandData->commandComment($type . ' Controller logic file deleted: '.$filename);
}
}
File::deleteDirectory($this->path);
}
}
@@ -0,0 +1,64 @@
<?php
namespace App\Classes\CodeGenerator\Generators\Scaffold;
use App\Classes\CodeGenerator\Common\CommandData;
use App\Classes\CodeGenerator\Generators\BaseGenerator;
use App\Classes\CodeGenerator\Utils\FileUtil;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
class ControllersGenerator extends BaseGenerator
{
/** @var CommandData */
private $commandData;
/** @var string */
private $path;
public function __construct(CommandData $commandData)
{
parent::__construct();
$this->commandData = $commandData;
$this->path = $commandData->config->pathController.'/'.str::pluralStudly($this->commandData->modelName).'/';
}
public function generate()
{
foreach(['create', 'list', 'fetch', 'update', 'delete'] as $type){
$name = $type === 'list' ? str::pluralStudly($this->commandData->modelName) : str::singular($this->commandData->modelName);
$filename = str::studly($type.$name).'Controller.php';
$templateData = $this->generatorHelpers->get_template("Scaffold.Controllers.".$type."_controller");
$templateData = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $templateData);
FileUtil::createFile($this->path, $filename, $templateData);
$this->commandData->commandComment("\n" . $type . " Controller created: ");
$this->commandData->commandInfo($filename);
}
}
public function rollback()
{
foreach(['create', 'list', 'fetch', 'update', 'delete'] as $type){
$name = $type === 'list' ? str::pluralStudly($this->commandData->modelName) : str::singular($this->commandData->modelName);
$filename = str::studly($type.$name).'Controller.php';
if ($this->rollbackFile($this->path, $filename)) {
$this->commandData->commandComment($type . ' Controller file deleted: '.$filename);
}
}
File::deleteDirectory($this->path);
}
}
@@ -0,0 +1,55 @@
<?php
namespace App\Classes\CodeGenerator\Generators\Scaffold;
use App\Classes\CodeGenerator\Common\CommandData;
use App\Classes\CodeGenerator\Generators\BaseGenerator;
use Illuminate\Support\Str;
class RoutesGenerator extends BaseGenerator
{
/** @var CommandData */
private $commandData;
/** @var string */
private $path;
/** @var string */
private $routeContents;
/** @var string */
private $routesTemplate;
public function __construct(CommandData $commandData)
{
parent::__construct();
$this->commandData = $commandData;
$this->path = base_path('routes/crud.php');;
$this->routeContents = file_get_contents($this->path);
$this->routesTemplate = $this->generatorHelpers->get_template('Routes.route');
$this->routesTemplate = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $this->routesTemplate);
}
public function generate()
{
if (Str::contains($this->routeContents, "Route::group(['prefix' => '".$this->commandData->config->mSnake."',")) {
$this->commandData->commandObj->info('Routes for '.$this->commandData->config->mName.' already exists, Skipping Adjustment.');
return;
}
file_put_contents($this->path, $this->routeContents.$this->routesTemplate);
$this->commandData->commandComment("\n".$this->commandData->config->mName.' routes added.');
}
public function rollback()
{
if (Str::contains($this->routeContents, $this->routesTemplate)) {
$this->routeContents = str_replace($this->routesTemplate, '', $this->routeContents);
file_put_contents($this->path, $this->routeContents);
$this->commandData->commandComment('Routes deleted');
}
}
}
@@ -0,0 +1,53 @@
<?php
namespace App\Classes\CodeGenerator\Generators\Scaffold;
use App\Classes\CodeGenerator\Common\CommandData;
use App\Classes\CodeGenerator\Generators\BaseGenerator;
use App\Classes\CodeGenerator\Utils\FileUtil;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
class ViewsGenerator extends BaseGenerator
{
/** @var CommandData */
private $commandData;
/** @var string */
private $path;
/** @var string */
private $fileName;
public function __construct(CommandData $commandData)
{
parent::__construct();
$this->commandData = $commandData;
$this->path = resource_path('views/pages/'.str::plural(str::snake($this->commandData->modelName)).'/');
$this->fileName = 'index.blade.php';
}
public function generate()
{
$templateData = $this->generatorHelpers->get_template("Views.view");
$templateData = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $templateData);
FileUtil::createFile($this->path, $this->fileName, $templateData);
$this->commandData->commandComment("\nView created: ");
$this->commandData->commandInfo($this->fileName);
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->fileName)) {
$this->commandData->commandComment('View file deleted: '.$this->fileName);
File::deleteDirectory($this->path);
}
}
}
@@ -0,0 +1,196 @@
<?php
namespace App\Classes\CodeGenerator\Generators\Scaffold;
use App\Classes\CodeGenerator\Common\CommandData;
use App\Classes\CodeGenerator\Generators\BaseGenerator;
use App\Classes\CodeGenerator\Utils\FileUtil;
use App\Classes\CodeGenerator\Utils\HTMLFieldGenerator;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
class VueGenerator extends BaseGenerator
{
/** @var CommandData */
private $commandData;
/** @var string */
private $path;
/** @var array */
private $htmlFields;
public function __construct(CommandData $commandData)
{
parent::__construct();
$this->commandData = $commandData;
$this->path = resource_path('assets/vue/components/'.str::camel($this->commandData->modelName).'/');
}
public function generate()
{
$fields = [];
$i = 1;
foreach ($this->commandData->fields as $index => $field) {
if (!$field->inIndex) {
continue;
}
$fieldTemplate = $this->generatorHelpers->get_template("Views.column");
$fieldTemplate = str_replace('$FIRST_COLUMN_CLASS$', $i === 1 ? 'ist-item-heading truncate' : 'text-small', $fieldTemplate);
$fieldTemplate = str_replace('$COLUMN_SIZE$', $i === 1 ? 'col-3' : 'col', $fieldTemplate);
$fieldTemplate = $this->generatorHelpers->fill_template_with_field_data(
$this->commandData->dynamicVars,
$this->commandData->fieldNamesMapping,
$fieldTemplate,
$field
);
$fields[] = $fieldTemplate;
$i++;
}
$templateData = $this->generatorHelpers->get_template("VueJs.element_component");
$templateData = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $templateData);
$templateData = str_replace('$FIELD_BODY$', implode($this->generatorHelpers->generator_nl_tab(1, 0), $fields), $templateData);
$fileName = $this->commandData->modelName.'Component.vue';
FileUtil::createFile($this->path.'elements/', $fileName, $templateData);
$this->commandData->commandComment("\nvue element created: ");
$this->commandData->commandInfo($fileName);
$this->generateForm();
$this->generateFilterForm();
}
private function generateForm()
{
$this->htmlFields = [];
$formFields = [];
$validations = [];
foreach ($this->commandData->fields as $field) {
if (!$field->inForm) {
continue;
}
$formFields[] = $field->name.": ''";
$validations[] = $field->name . ": { " . implode(', ', explode('|', $field->validations)) ." }";
$fieldTemplate = $this->generatorHelpers->get_template('Fields.field');
$fieldInputTemplate = HTMLFieldGenerator::generateHTML($field);
if($field->htmlType === 'selectTable'){
$fieldTemplate = str_replace('$v.parameters.$FIELD_NAME$', '$v.parameters.'.$field->name, $fieldTemplate);
$fieldTemplate = str_replace('$FIELD_NAME$', Str::replaceLast('_id', '', $field->name), $fieldTemplate);
}
$fieldTemplate = str_replace('$FIELD$', $fieldInputTemplate, $fieldTemplate);
if (!empty($fieldTemplate)) {
$fieldTemplate = $this->generatorHelpers->fill_template_with_field_data(
$this->commandData->dynamicVars,
$this->commandData->fieldNamesMapping,
$fieldTemplate,
$field
);
$this->htmlFields[] = $fieldTemplate;
}
}
$templateData = $this->generatorHelpers->get_template('VueJs.form_component');
$templateData = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $templateData);
$templateData = str_replace('$FIELDS$', implode("\n", $this->htmlFields), $templateData);
$templateData = str_replace('$REQUEST_FIELDS$', implode(','.$this->generatorHelpers->generator_nl_tab(1, 5), $formFields), $templateData);
$templateData = str_replace('$VALIDATION$', implode(','.$this->generatorHelpers->generator_nl_tab(1, 4), $validations), $templateData);
FileUtil::createFile($this->path.'forms/', $this->commandData->modelName.'FormComponent.vue', $templateData);
$this->commandData->commandComment("\nvue form created: ");
$this->commandData->commandInfo($this->commandData->modelName.'FormComponent.vue');
}
private function generateFilterForm()
{
$filterFields = [];
$filterMap = [];
foreach ($this->commandData->fields as $field) {
if (!$field->isSearchable) {
continue;
}
$filterMap[] = $field->name.": ''";
$fieldTemplate = $this->generatorHelpers->get_template('Fields.filter_field');
$fieldInputTemplate = HTMLFieldGenerator::generateHTML($field);
if($field->htmlType === 'selectTable'){
$fieldTemplate = str_replace('$v.parameters.$FIELD_NAME$', '$v.parameters.'.$field->name, $fieldTemplate);
$fieldTemplate = str_replace('$FIELD_NAME$', Str::replaceLast('_id', '', $field->name), $fieldTemplate);
}
$fieldTemplate = str_replace('$FIELD$', $fieldInputTemplate, $fieldTemplate);
if (!empty($fieldTemplate)) {
$fieldTemplate = $this->generatorHelpers->fill_template_with_field_data(
$this->commandData->dynamicVars,
$this->commandData->fieldNamesMapping,
$fieldTemplate,
$field
);
$filterFields[] = $fieldTemplate;
}
}
$templateData = $this->generatorHelpers->get_template('VueJs.filter_component');
$templateData = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $templateData);
$templateData = str_replace('$FIELDS$', implode("\n", $filterFields), $templateData);
$templateData = str_replace('$REQUEST_FIELDS$', implode(','.$this->generatorHelpers->generator_nl_tab(1, 5), $filterMap), $templateData);
FileUtil::createFile($this->path.'forms/', $this->commandData->modelName.'FiltersComponent.vue', $templateData);
$this->commandData->commandComment("\nvue filter created: ");
$this->commandData->commandInfo($this->commandData->modelName.'FiltersComponent.vue');
}
public function rollback()
{
foreach(['elements', 'forms'] as $folderType){
if($folderType === 'elements'){
if ($this->rollbackFile($this->path.$folderType.'/', $this->commandData->modelName.'Component.vue')) {
$this->commandData->commandComment('Vue element file deleted: '.$this->commandData->modelName.'Component.vue');
}
} else {
foreach(['form', 'filter'] as $type){
if ($this->rollbackFile($this->path.$folderType.'/', $this->commandData->modelName.str::studly($type).'Component.vue')) {
$this->commandData->commandComment('Vue '.$type.' file deleted: '.$this->commandData->modelName.str::studly($type).'Component.vue');
}
}
}
File::deleteDirectory($this->path.$folderType.'/');
}
File::deleteDirectory($this->path);
}
}
@@ -0,0 +1,55 @@
<?php
namespace App\Classes\CodeGenerator\Generators\Scaffold;
use App\Classes\CodeGenerator\Common\CommandData;
use App\Classes\CodeGenerator\Generators\BaseGenerator;
use Illuminate\Support\Str;
class WebRouteGenerator extends BaseGenerator
{
/** @var CommandData */
private $commandData;
/** @var string */
private $path;
/** @var string */
private $routeContents;
/** @var string */
private $routesTemplate;
public function __construct(CommandData $commandData)
{
parent::__construct();
$this->commandData = $commandData;
$this->path = base_path('routes/web.php');;
$this->routeContents = file_get_contents($this->path);
$this->routesTemplate = $this->generatorHelpers->get_template('Routes.web');
$this->routesTemplate = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $this->routesTemplate);
}
public function generate()
{
if (Str::contains($this->routeContents, "Route::get('/".$this->commandData->config->mSnakePlural."'")) {
$this->commandData->commandObj->info('Web route for '.$this->commandData->config->mName.' already exists, Skipping Adjustment.');
return;
}
file_put_contents($this->path, $this->routeContents.$this->routesTemplate);
$this->commandData->commandComment("\n".$this->commandData->config->mName.' web route added.');
}
public function rollback()
{
if (Str::contains($this->routeContents, $this->routesTemplate)) {
$this->routeContents = str_replace($this->routesTemplate, '', $this->routeContents);
file_put_contents($this->path, $this->routeContents);
$this->commandData->commandComment('web route deleted');
}
}
}
@@ -0,0 +1,86 @@
<?php
namespace App\Classes\CodeGenerator\Generators;
use App\Classes\CodeGenerator\Common\CommandData;
use App\Classes\CodeGenerator\Utils\FileUtil;
use Illuminate\Support\Str;
/**
* Class SeederGenerator.
*/
class SeederGenerator extends BaseGenerator
{
/** @var CommandData */
private $commandData;
/** @var string */
private $path;
private $fileName;
/**
* ModelGenerator constructor.
*
* @param CommandData $commandData
*/
public function __construct(CommandData $commandData)
{
parent::__construct();
$this->commandData = $commandData;
$this->path = $commandData->config->pathSeeder;
$this->fileName = Str::studly($this->commandData->config->mPlural).'TableSeeder.php';
}
public function generate()
{
$templateData = $this->generatorHelpers->get_template('Seeds.model_seeder');
$templateData = $this->generatorHelpers->fill_template($this->commandData->dynamicVars, $templateData);
FileUtil::createFile($this->path, $this->fileName, $templateData);
$this->commandData->commandComment("\nSeeder created: ");
$this->commandData->commandInfo($this->fileName);
}
public function updateMainSeeder()
{
$mainSeederContent = file_get_contents($this->commandData->config->pathDatabaseSeeder);
$newSeederStatement = '$this->call('.$this->commandData->config->mPlural.'TableSeeder::class);';
if (strpos($mainSeederContent, $newSeederStatement) != false) {
$this->commandData->commandObj->info($this->commandData->config->mPlural.'TableSeeder entry found in DatabaseSeeder. Skipping Adjustment.');
return;
}
$newSeederStatement = $this->generatorHelpers->generator_tabs(2).$newSeederStatement.$this->generatorHelpers->generator_nl();
preg_match_all('/\\$this->call\\((.*);/', $mainSeederContent, $matches);
$totalMatches = count($matches[0]);
$lastSeederStatement = $matches[0][$totalMatches - 1];
$replacePosition = strpos($mainSeederContent, $lastSeederStatement);
$mainSeederContent = substr_replace($mainSeederContent, $newSeederStatement, $replacePosition + strlen($lastSeederStatement) + 1, 0);
file_put_contents($this->commandData->config->pathDatabaseSeeder, $mainSeederContent);
$this->commandData->commandComment('Main Seeder file updated.');
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->fileName)) {
$this->commandData->commandComment('Seeder file deleted: '.$this->fileName);
}
$mainSeederContent = file_get_contents($this->commandData->config->pathDatabaseSeeder);
$mainSeederContent = str_replace('$this->call('.$this->commandData->config->mPlural.'TableSeeder::class);', '', $mainSeederContent);
file_put_contents($this->commandData->config->pathDatabaseSeeder, $mainSeederContent);
$this->commandData->commandComment('Main Seeder file updated.');
}
}
@@ -0,0 +1,102 @@
[
{
"name": "company_id",
"dbType": "foreignId:foreign,companies,id",
"htmlType": "selectTable:companies:name,id",
"validations": "required",
"searchable": true,
"fillable": false,
"primary": false,
"inForm": false,
"inIndex": true,
"relation": "1t1,Company,company_id,id"
},
{
"name": "street_one",
"dbType": "string",
"htmlType": "text",
"validations": "required",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true
},
{
"name": "street_two",
"dbType": "string:nullable",
"htmlType": "text",
"validations": "",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true
},
{
"name": "city",
"dbType": "string",
"htmlType": "text",
"validations": "required",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true
},
{
"name": "state",
"dbType": "string",
"htmlType": "text",
"validations": "required",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true
},
{
"name": "post_code",
"dbType": "string",
"htmlType": "text",
"validations": "required",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true
},
{
"name": "country",
"dbType": "string",
"htmlType": "text",
"validations": "required",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true
},
{
"name": "default",
"dbType": "integer",
"htmlType": "number",
"validations": "required",
"searchable": false,
"fillable": false,
"primary": false,
"inForm": false,
"inIndex": false
},
{
"name": "billing",
"dbType": "integer",
"htmlType": "number",
"validations": "required",
"searchable": false,
"fillable": false,
"primary": false,
"inForm": false,
"inIndex": false
}
]
@@ -0,0 +1,35 @@
[
{
"name": "reference_no",
"dbType": "integer:unique",
"htmlType": "number",
"validations": "required",
"searchable": true,
"fillable": false,
"primary": false,
"inForm": false,
"inIndex": true
},
{
"name": "name",
"dbType": "string",
"htmlType": "text",
"validations": "required",
"searchable": true,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true
},
{
"name": "type",
"dbType": "integer",
"htmlType": "number",
"validations": "required",
"searchable": true,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true
}
]
@@ -0,0 +1,70 @@
[
{
"name": "company_id",
"dbType": "foreignId:foreign,companies,id",
"htmlType": "selectTable:companies:name,id",
"validations": "required",
"searchable": true,
"fillable": false,
"primary": false,
"inForm": false,
"inIndex": true,
"relation": "1t1,Company,company_id,id"
},
{
"name": "name",
"dbType": "string",
"htmlType": "text",
"validations": "required",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true
},
{
"name": "designation",
"dbType": "string:nullable",
"htmlType": "text",
"validations": "",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true
},
{
"name": "email",
"dbType": "string:nullable",
"htmlType": "text",
"validations": "",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true
}
,
{
"name": "phone",
"dbType": "string:nullable",
"htmlType": "text",
"validations": "",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true
},
{
"name": "wechat_id",
"dbType": "string:nullable",
"htmlType": "text",
"validations": "",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true
}
]
@@ -0,0 +1,6 @@
/**
* Class $MODEL_NAME$
* @package $NAMESPACE_MODEL$
* @version $GENERATE_DATE$
*
$PHPDOC$ */
@@ -0,0 +1,12 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
$factory->define($NAMESPACE_MODEL$\$MODEL_NAME$::class, function (Faker $faker) {
return [
$FIELDS$
];
});
@@ -0,0 +1 @@
<date-picker-component v-model="parameters.$FIELD_NAME$"></date-picker-component>
@@ -0,0 +1 @@
<input v-model="parameters.$FIELD_NAME$" type="email" class="form-control">
@@ -0,0 +1,8 @@
<div class="row mb-3 animated fadeInDown fast">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.$FIELD_NAME$">
$FIELD$
<span>$FIELD_NAME$</span>
</validation-wrapper-component>
</div>
</div>
@@ -0,0 +1,8 @@
<div class="row mb-3 animated fadeInDown fast">
<div class="col">
<label class="form-group has-float-label mb-1">
$FIELD$
<span>$FIELD_NAME$</span>
</label>
</div>
</div>
@@ -0,0 +1 @@
<input v-model="parameters.$FIELD_NAME$" type="password" class="form-control">
@@ -0,0 +1 @@
<select-component :options="$INPUT_ARR$" v-model="parameters.$FIELD_NAME$"></select-component>
@@ -0,0 +1 @@
<selectable-component :endpoint="route('api.$SELECT_TABLE$.list')" section="$SELECT_TABLE_CAMEL$Section" valueColumn="$VALUE_COLUMN$" labelColumn="$LABEL_COLUMN$" v-model="parameters.$FIELD_NAME$"></selectable-component>
@@ -0,0 +1 @@
<input v-model="parameters.$FIELD_NAME$" type="text" class="form-control">
@@ -0,0 +1 @@
<textarea v-model="parameters.$FIELD_NAME$" class="form-control"></textarea>
@@ -0,0 +1,24 @@
<?php
namespace App\Classes\Modules\$MODEL_NAME_PLURAL$\DataTransferObjects;
use App\Classes\Interfaces\DataTransferObject;
class $MODEL_NAME$Object implements DataTransferObject
{
$PROPERTIES$
/**
* $MODEL_NAME$Object constructor.
$CONSTRUCTOR_DOCS$
*/
public function __construct($CONSTRUCTOR_PROPERTIES$)
{
$CONSTRUCTOR_BODY$
}
$GETTER_FUNCTIONS$
}
@@ -0,0 +1,7 @@
/**
* @return $DATA_TYPE$
*/
public function $FUNCTION_NAME$(): $DATA_TYPE$
{
return $this->$FIELD_NAME$;
}
@@ -0,0 +1,31 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class Create$TABLE_NAME_TITLE$Table extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('$TABLE_NAME$', function (Blueprint $table) {
$FIELDS$
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('$TABLE_NAME$');
}
}
@@ -0,0 +1,44 @@
<?php
namespace $NAMESPACE_MODEL$;
use $NAMESPACE_MODEL_EXTEND$ as Model;
$SOFT_DELETE_IMPORT$
$DOCS$
class $MODEL_NAME$ extends AbstractModel
{
$SOFT_DELETE$
protected $table = '$TABLE_NAME$';
$TIMESTAMPS$
$SOFT_DELETE_DATES$
$PRIMARY$
public $fillable = [
$FIELDS$
];
/**
* The attributes that should be casted to native types.
*
* @var array
*/
protected $casts = [
$CAST$
];
/**
* Validation rules
*
* @var array
*/
public static $rules = [
$RULES$
];
$RELATIONS$
}
@@ -0,0 +1,7 @@
/**
* @return \Illuminate\Database\Eloquent\Relations\$RELATIONSHIP_CLASS$
**/
public function $FUNCTION_NAME$(): $RELATIONSHIP_CLASS$
{
return $this->$RELATION$(\$NAMESPACE_MODEL$\$RELATION_MODEL_NAME$::class$INPUT_FIELDS$);
}
@@ -0,0 +1,22 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class $MODEL_NAME$Resource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
$FIELDS$
];
}
}
@@ -0,0 +1,15 @@
Route::group(['prefix' => '$MODEL_NAME_SNAKE$', 'as' => '$MODEL_NAME_SNAKE$.', 'namespace' => '$MODEL_NAME_PLURAL$'], function () {
Route::get('/{id}/show', 'Fetch$MODEL_NAME$Controller@fetch')->name('show');
Route::get('/list', 'List$MODEL_NAME_PLURAL$Controller@list')->name('list');
Route::post('/create', 'Create$MODEL_NAME$Controller@create')->name('create');
Route::put('/update/{id}', 'Update$MODEL_NAME$Controller@update')->name('update');
Route::delete('/delete/{id}', 'Delete$MODEL_NAME$Controller@destroy')->name('delete');
});
@@ -0,0 +1,5 @@
Route::get('/$MODEL_NAME_PLURAL_SNAKE$', function () {
return view('pages.$MODEL_NAME_PLURAL_SNAKE$.index');
})->name('$MODEL_NAME_SNAKE$.dashboard');
@@ -0,0 +1,57 @@
<?php
namespace App\Classes\Modules\$MODEL_NAME_PLURAL$\Standards\Rules;
use App\Classes\General\Abstracts\AbstractRule;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\DataTransferObjects\$MODEL_NAME$Object;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\Standards\Validators\$MODEL_NAME$Validation;
class CanCreate$MODEL_NAME$ extends AbstractRule
{
/** @var $MODEL_NAME$Validation */
private $$MODEL_NAME_CAMEL$Validation;
/**
* CanCreate$MODEL_NAME$ constructor.
* @param $MODEL_NAME$Validation $$MODEL_NAME_CAMEL$Validation
*/
public function __construct($MODEL_NAME$Validation $$MODEL_NAME_CAMEL$Validation)
{
$this->$MODEL_NAME_CAMEL$Validation = $$MODEL_NAME_CAMEL$Validation;
}
/**
* @return bool
*/
protected function authorized(): bool
{
// TODO Set Authorization rules
return true;
}
/**
* @param $MODEL_NAME$Object $object
* @return bool
* @throws \App\Classes\Exceptions\RequestValidationException
*/
protected function validators($object): bool
{
return $this->$MODEL_NAME_CAMEL$Validation->validate($object);
}
/**
* @param $MODEL_NAME$Object $object
* @return bool
*/
protected function criteria($object): bool
{
return true;
}
}
@@ -0,0 +1,43 @@
<?php
namespace App\Classes\Modules\$MODEL_NAME_PLURAL$\Standards\Rules;
use App\Classes\General\Abstracts\AbstractRule;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\DataTransferObjects\$MODEL_NAME$Object;
class CanDelete$MODEL_NAME$ extends AbstractRule
{
/**
* @return bool
*/
protected function authorized(): bool
{
// TODO Set Authorization rules
return true;
}
/**
* @param $MODEL_NAME$Object $object
* @return bool
*/
protected function validators($object): bool
{
return true;
}
/**
* @param $MODEL_NAME$Object $object
* @return bool
*/
protected function criteria($object): bool
{
return true;
}
}
@@ -0,0 +1,43 @@
<?php
namespace App\Classes\Modules\$MODEL_NAME_PLURAL$\Standards\Rules;
use App\Classes\General\Abstracts\AbstractRule;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\DataTransferObjects\$MODEL_NAME$Object;
class CanFetch$MODEL_NAME$ extends AbstractRule
{
/**
* @return bool
*/
protected function authorized(): bool
{
// TODO Set Authorization rules
return true;
}
/**
* @param $MODEL_NAME$Object $object
* @return bool
*/
protected function validators($object): bool
{
return true;
}
/**
* @param $MODEL_NAME$Object $object
* @return bool
*/
protected function criteria($object): bool
{
return true;
}
}
@@ -0,0 +1,43 @@
<?php
namespace App\Classes\Modules\$MODEL_NAME_PLURAL$\Standards\Rules;
use App\Classes\General\Abstracts\AbstractRule;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\DataTransferObjects\$MODEL_NAME$Object;
class CanList$MODEL_NAME_PLURAL$ extends AbstractRule
{
/**
* @return bool
*/
protected function authorized(): bool
{
// TODO Set Authorization rules
return true;
}
/**
* @param $MODEL_NAME$Object $object
* @return bool
*/
protected function validators($object): bool
{
return true;
}
/**
* @param $MODEL_NAME$Object $object
* @return bool
*/
protected function criteria($object): bool
{
return true;
}
}
@@ -0,0 +1,57 @@
<?php
namespace App\Classes\Modules\$MODEL_NAME_PLURAL$\Standards\Rules;
use App\Classes\General\Abstracts\AbstractRule;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\DataTransferObjects\$MODEL_NAME$Object;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\Standards\Validators\$MODEL_NAME$Validation;
class CanUpdate$MODEL_NAME$ extends AbstractRule
{
/** @var $MODEL_NAME$Validation */
private $$MODEL_NAME_CAMEL$Validation;
/**
* CanUpdate$MODEL_NAME$ constructor.
* @param $MODEL_NAME$Validation $$MODEL_NAME_CAMEL$Validation
*/
public function __construct($MODEL_NAME$Validation $$MODEL_NAME_CAMEL$Validation)
{
$this->$MODEL_NAME_CAMEL$Validation = $$MODEL_NAME_CAMEL$Validation;
}
/**
* @return bool
*/
protected function authorized(): bool
{
// TODO Set Authorization rules
return true;
}
/**
* @param $MODEL_NAME$Object $object
* @return bool
* @throws \App\Classes\Exceptions\RequestValidationException
*/
protected function validators($object): bool
{
return $this->$MODEL_NAME_CAMEL$Validation->validate($object);
}
/**
* @param $MODEL_NAME$Object $object
* @return bool
*/
protected function criteria($object): bool
{
return true;
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\$MODEL_NAME_PLURAL$;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\ControllerLogic\Create$MODEL_NAME$Logic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class Create$MODEL_NAME$Controller
{
/**
* @param Request $request
* @param Create$MODEL_NAME$ControllerLogic $logic
* @return JsonResponse
*/
public function create(Request $request, Create$MODEL_NAME$ControllerLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\$MODEL_NAME_PLURAL$;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\ControllerLogic\Delete$MODEL_NAME$Logic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class Delete$MODEL_NAME$Controller
{
/**
* @param Request $request
* @param Delete$MODEL_NAME$ControllerLogic $logic
* @return JsonResponse
*/
public function destroy(Request $request, Delete$MODEL_NAME$ControllerLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\$MODEL_NAME_PLURAL$;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\ControllerLogic\Fetch$MODEL_NAME$Logic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class Fetch$MODEL_NAME$Controller
{
/**
* @param Request $request
* @param Fetch$MODEL_NAME$ControllerLogic $logic
* @return JsonResponse
*/
public function fetch(Request $request, Fetch$MODEL_NAME$ControllerLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\$MODEL_NAME_PLURAL$;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\ControllerLogic\List$MODEL_NAME_PLURAL$Logic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class List$MODEL_NAME_PLURAL$Controller
{
/**
* @param Request $request
* @param list$MODEL_NAME_PLURAL$ControllerLogic $logic
* @return JsonResponse
*/
public function list(Request $request, list$MODEL_NAME_PLURAL$ControllerLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\$MODEL_NAME_PLURAL$;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\ControllerLogic\Update$MODEL_NAME$Logic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class Update$MODEL_NAME$Controller
{
/**
* @param Request $request
* @param Update$MODEL_NAME$ControllerLogic $logic
* @return JsonResponse
*/
public function update(Request $request, Update$MODEL_NAME$ControllerLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,69 @@
<?php
namespace App\Classes\Modules\$MODEL_NAME_PLURAL$\ControllerLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\Services\Creates$MODEL_NAME$;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\Standards\Rules\CanCreate$MODEL_NAME$;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\DataTransferObjects\$MODEL_NAME$Object;
use App\Http\Resources\$MODEL_NAME$Resource;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class Create$MODEL_NAME$ControllerLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Created $MODEL_NAME_HUMAN$',
'message' => 'You have successfully created a new $MODEL_NAME_HUMAN$'
];
}
/** @var CanCreate$MODEL_NAME$ */
private $canCreate$MODEL_NAME$;
/** @var Creates$MODEL_NAME$ */
private $creates$MODEL_NAME$;
/**
* Create$MODEL_NAME$ControllerLogic constructor.
* @param CanCreate$MODEL_NAME$ $canCreate$MODEL_NAME$
* @param Creates$MODEL_NAME$ $creates$MODEL_NAME$
*/
public function __construct(CanCreate$MODEL_NAME$ $canCreate$MODEL_NAME$, Creates$MODEL_NAME$ $creates$MODEL_NAME$)
{
$this->canCreate$MODEL_NAME$ = $canCreate$MODEL_NAME$;
$this->creates$MODEL_NAME$ = $creates$MODEL_NAME$;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
try {
$object = new $MODEL_NAME$Object($REQUEST_FIELDS$);
$this->canCreate$MODEL_NAME$->passes($object);
$query = $this->creates$MODEL_NAME$->execute($object);
return $this->resourceResponse(new $MODEL_NAME$Resource($query));
} catch (\Exception $exception){
throw new ErrorException($exception->getMessage(), $exception->getCode());
}
}
}
@@ -0,0 +1,73 @@
<?php
namespace App\Classes\Modules\$MODEL_NAME_PLURAL$\ControllerLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\Services\Deletes$MODEL_NAME$;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\Services\Fetches$MODEL_NAME$;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\Standards\Rules\CanDelete$MODEL_NAME$;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class Delete$MODEL_NAME$ControllerLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Deleted $MODEL_NAME_HUMAN$',
'message' => 'You have successfully deleted a $MODEL_NAME_HUMAN$'
];
}
/** @var CanDelete$MODEL_NAME$ */
private $canDelete$MODEL_NAME$;
/** @var Deletes$MODEL_NAME$ */
private $deletes$MODEL_NAME$;
/** @var Fetches$MODEL_NAME$ */
private $fetches$MODEL_NAME$;
/**
* Delete$MODEL_NAME$ControllerLogic constructor.
* @param CanDelete$MODEL_NAME$ $canDelete$MODEL_NAME$
* @param Deletes$MODEL_NAME$ $deletes$MODEL_NAME$
* @param Fetches$MODEL_NAME$ $fetches$MODEL_NAME$
*/
public function __construct(CanDelete$MODEL_NAME$ $canDelete$MODEL_NAME$, Deletes$MODEL_NAME$ $deletes$MODEL_NAME$, Fetches$MODEL_NAME$ $fetches$MODEL_NAME$)
{
$this->canDelete$MODEL_NAME$ = $canDelete$MODEL_NAME$;
$this->deletes$MODEL_NAME$ = $deletes$MODEL_NAME$;
$this->fetches$MODEL_NAME$ = $fetches$MODEL_NAME$;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
try {
$this->canDelete$MODEL_NAME$->passes();
$query = $this->fetches$MODEL_NAME$->execute(['id' => $request->route('id')]);
$this->deletes$MODEL_NAME$->execute($query);
return $this->response([]);
} catch (\Exception $exception){
throw new ErrorException($exception->getMessage(), $exception->getCode());
}
}
}
@@ -0,0 +1,67 @@
<?php
namespace App\Classes\Modules\$MODEL_NAME_PLURAL$\ControllerLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\Services\Fetches$MODEL_NAME$;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\Standards\Rules\CanFetch$MODEL_NAME$;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\DataTransferObjects\$MODEL_NAME$Object;
use App\Http\Resources\$MODEL_NAME$Resource;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class Fetch$MODEL_NAME$ControllerLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieved $MODEL_NAME_HUMAN$',
'message' => 'You have successfully retrieved a $MODEL_NAME_HUMAN$'
];
}
/** @var CanFetch$MODEL_NAME$ */
private $canFetch$MODEL_NAME$;
/** @var Fetches$MODEL_NAME$ */
private $fetches$MODEL_NAME$;
/**
* Fetch$MODEL_NAME$ControllerLogic constructor.
* @param CanFetch$MODEL_NAME$ $canFetch$MODEL_NAME$
* @param Fetches$MODEL_NAME$ $fetches$MODEL_NAME$
*/
public function __construct(CanFetch$MODEL_NAME$ $canFetch$MODEL_NAME$, Fetches$MODEL_NAME$ $fetches$MODEL_NAME$)
{
$this->canFetch$MODEL_NAME$ = $canFetch$MODEL_NAME$;
$this->fetches$MODEL_NAME$ = $fetches$MODEL_NAME$;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
try {
$this->canFetch$MODEL_NAME$->passes();
$query = $this->fetches$MODEL_NAME$->execute(['id' => $request->route('id')]);
return $this->resourceResponse(new $MODEL_NAME$Resource($query));
} catch (\Exception $exception){
throw new ErrorException($exception->getMessage(), $exception->getCode());
}
}
}
@@ -0,0 +1,66 @@
<?php
namespace App\Classes\Modules\$MODEL_NAME_PLURAL$\ControllerLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\Services\Lists$MODEL_NAME_PLURAL$;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\Standards\Rules\CanList$MODEL_NAME_PLURAL$;
use App\Http\Resources\$MODEL_NAME$Resource;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class List$MODEL_NAME_PLURAL$ControllerLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieved $MODEL_NAME_PLURAL_HUMAN$',
'message' => 'You have successfully retrieved a list of $MODEL_NAME_PLURAL_HUMAN$'
];
}
/** @var CanList$MODEL_NAME_PLURAL$ */
private $canList$MODEL_NAME_PLURAL$;
/** @var Lists$MODEL_NAME_PLURAL$ */
private $lists$MODEL_NAME_PLURAL$;
/**
* List$MODEL_NAME_PLURAL$ControllerLogic constructor.
* @param CanList$MODEL_NAME_PLURAL$ $canList$MODEL_NAME_PLURAL$
* @param Lists$MODEL_NAME_PLURAL$ $lists$MODEL_NAME_PLURAL$
*/
public function __construct(CanList$MODEL_NAME_PLURAL$ $canList$MODEL_NAME_PLURAL$, Lists$MODEL_NAME_PLURAL$ $lists$MODEL_NAME_PLURAL$)
{
$this->canList$MODEL_NAME_PLURAL$ = $canList$MODEL_NAME_PLURAL$;
$this->lists$MODEL_NAME_PLURAL$ = $lists$MODEL_NAME_PLURAL$;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
try {
$this->canList$MODEL_NAME_PLURAL$->passes();
$query = $this->lists$MODEL_NAME_PLURAL$->execute($this->lists$MODEL_NAME_PLURAL$->deserializeFilters($request->input('filters')));
return $this->collectionResponse($MODEL_NAME$Resource::collection($query));
} catch (\Exception $exception){
throw new ErrorException($exception->getMessage(), $exception->getCode());
}
}
}
@@ -0,0 +1,78 @@
<?php
namespace App\Classes\Modules\$MODEL_NAME_PLURAL$\ControllerLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\Services\Updates$MODEL_NAME$;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\Services\Fetches$MODEL_NAME$;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\Standards\Rules\CanUpdate$MODEL_NAME$;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\DataTransferObjects\$MODEL_NAME$Object;
use App\Http\Resources\$MODEL_NAME$Resource;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class Update$MODEL_NAME$ControllerLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Updated $MODEL_NAME_HUMAN$',
'message' => 'You have successfully updated the $MODEL_NAME_HUMAN$'
];
}
/** @var CanUpdate$MODEL_NAME$ */
private $canUpdate$MODEL_NAME$;
/** @var Updates$MODEL_NAME$ */
private $updates$MODEL_NAME$;
/** @var Fetches$MODEL_NAME$ */
private $fetches$MODEL_NAME$;
/**
* Update$MODEL_NAME$ControllerLogic constructor.
* @param CanUpdate$MODEL_NAME$ $canUpdate$MODEL_NAME$
* @param Updates$MODEL_NAME$ $updates$MODEL_NAME$
* @param Fetches$MODEL_NAME$ $fetches$MODEL_NAME$
*/
public function __construct(CanUpdate$MODEL_NAME$ $canUpdate$MODEL_NAME$, Updates$MODEL_NAME$ $updates$MODEL_NAME$, Fetches$MODEL_NAME$ $fetches$MODEL_NAME$)
{
$this->canUpdate$MODEL_NAME$ = $canUpdate$MODEL_NAME$;
$this->updates$MODEL_NAME$ = $updates$MODEL_NAME$;
$this->fetches$MODEL_NAME$ = $fetches$MODEL_NAME$;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
try {
$object = new $MODEL_NAME$Object($REQUEST_FIELDS$);
$this->canUpdate$MODEL_NAME$->passes($object);
$query = $this->fetches$MODEL_NAME$->execute(['id' => $request->route('id')]);
$query = $this->updates$MODEL_NAME$->execute($query, $object);
return $this->resourceResponse(new $MODEL_NAME$Resource($query));
} catch (\Exception $exception){
throw new ErrorException($exception->getMessage(), $exception->getCode());
}
}
}
@@ -0,0 +1,16 @@
<?php
use Illuminate\Database\Seeder;
class $MODEL_NAME_PLURAL$TableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
factory($NAMESPACE_MODEL$\$MODEL_NAME$::class, 30)->create();
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Classes\Modules\$MODEL_NAME_PLURAL$\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\DataTransferObjects\$MODEL_NAME$Object;
use App\Models\$MODEL_NAME$;
class Creates$MODEL_NAME$ extends AbstractUpdateRecord
{
public function execute($MODEL_NAME$Object $object) {
$model = new $MODEL_NAME$();
$FIELDS$
return $this->handler($model);
}
}
@@ -0,0 +1,15 @@
<?php
namespace App\Classes\Modules\$MODEL_NAME_PLURAL$\Services;
use App\Classes\General\Eloquent\AbstractDeleteRecord;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\DataTransferObjects\$MODEL_NAME$Object;
use App\Models\$MODEL_NAME$;
class Deletes$MODEL_NAME$ extends AbstractDeleteRecord
{
public function execute($MODEL_NAME$ $model) {
return $this->handler($model);
}
}
@@ -0,0 +1,33 @@
<?php
namespace App\Classes\Modules\$MODEL_NAME_PLURAL$\Services;
use App\Classes\General\Eloquent\AbstractFetchRecord;
use Illuminate\Database\Eloquent\Builder;
use App\Models\$MODEL_NAME$;
class Fetches$MODEL_NAME$ extends AbstractFetchRecord
{
/** @var $MODEL_NAME$ */
private $repository;
/**
* Fetches$MODEL_NAME$ constructor.
* @param $MODEL_NAME$ $repository
*/
public function __construct($MODEL_NAME$ $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
public function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -0,0 +1,33 @@
<?php
namespace App\Classes\Modules\$MODEL_NAME_PLURAL$\Services;
use App\Classes\General\Eloquent\AbstractListRecord;
use Illuminate\Database\Eloquent\Builder;
use App\Models\$MODEL_NAME$;
class Lists$MODEL_NAME_PLURAL$ extends AbstractListRecord
{
/** @var $MODEL_NAME$ */
private $repository;
/**
* Lists$MODEL_NAME_PLURAL$ constructor.
* @param $MODEL_NAME$ $repository
*/
public function __construct($MODEL_NAME$ $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Classes\Modules\$MODEL_NAME_PLURAL$\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\DataTransferObjects\$MODEL_NAME$Object;
use App\Models\$MODEL_NAME$;
class Updates$MODEL_NAME$ extends AbstractUpdateRecord
{
public function execute($MODEL_NAME$ $model, $MODEL_NAME$Object $object) {
$FIELDS$
return $this->handler($model);
}
}
@@ -0,0 +1,39 @@
<?php
namespace App\Classes\Modules\$MODEL_NAME_PLURAL$\Standards\Validators;
use App\Classes\General\Abstracts\AbstractValidation;
use App\Classes\Modules\$MODEL_NAME_PLURAL$\DataTransferObjects\$MODEL_NAME$Object;
class $MODEL_NAME$Validation extends AbstractValidation
{
/**
* @param $MODEL_NAME$Object $object
* @return array
*/
protected function data($object): array {
return [
$FIELDS$
];
}
/**
* @return array
*/
protected function rules(): array {
return [
$RULES$
];
}
/**
* @return array
*/
protected function messages(): array {
return [];
}
}
@@ -0,0 +1,16 @@
<div class="$COLUMN_SIZE$">
<div class="row">
<div class="col">
<div class=" mb-1 w-xs-100 mt-0">
<span class="align-middle d-inline-block text-muted text-small text-uppercase" style=" font-size: 9px !important; ">$FIELD_NAME$</span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="$FIRST_COLUMN_CLASS$ mb-0 w-xs-100 mt-0">
<span class="align-middle d-inline-block">{{$MODEL_NAME_CAMEL$.$FIELD_NAME$}}</span>
</div>
</div>
</div>
</div>
@@ -0,0 +1,31 @@
@extends('layouts.base_portal')
@section('inner_content')
<div class="container-fluid">
<div class="row app-row">
<div class="col-12">
<div class="row align-items-center mb-5">
<div class="col">
<h3 class="text-uppercase m-0">$MODEL_NAME_PLURAL_HUMAN$</h3>
</div>
<div class="col-auto">
<div class="top-right-button-container parentContainer">
<button type="button" class="btn btn-primary btn-lg top-right-button mr-1 requestModal" data-type="createModal">ADD NEW</button>
<form-component section="$MODEL_NAME_CAMEL$Section">
<template slot="form" slot-scope="{section}">
<$MODEL_NAME_DASHED$-form-component :section="section"></$MODEL_NAME_DASHED$-form-component>
</template>
</form-component>
</div>
</div>
</div>
<list-component key="2" section="$MODEL_NAME_CAMEL$Section" endpoint="{{ route('api.$MODEL_NAME_SNAKE$.list') }}">
<template slot="list" slot-scope="{data}">
<$MODEL_NAME_DASHED$-component :data="data"></$MODEL_NAME_DASHED$-component>
</template>
</list-component>
</div>
</div>
</div>
<$MODEL_NAME_DASHED$-filters-component section="$MODEL_NAME_CAMEL$Section"></$MODEL_NAME_DASHED$-filters-component>
@endsection
@@ -0,0 +1,41 @@
<template>
<div class="card mb-3 parentContainer">
<div class="row pt-3 pb-3 pr-4 pl-4">
<div class="col">
<div class="row align-items-center">
$FIELD_BODY$
<div class="col text-right">
<button type="button" class="btn btn-outline-secondary icon-button mr-3 requestModal" data-type="editModal"><i class="iconsminds-pen-2"></i></button>
<button type="button" class="btn btn-outline-danger icon-button requestModal" data-type="deleteModal"><i class="simple-icon-trash"></i></button>
</div>
</div>
</div>
</div>
<form-component section="$MODEL_NAME_CAMEL$Section" :data="$MODEL_NAME_CAMEL$">
<template slot="form" slot-scope="{section, data}">
<$MODEL_NAME_DASHED$-form-component :section="section" :data="data"></$MODEL_NAME_DASHED$-form-component>
</template>
</form-component>
<delete-component section="$MODEL_NAME_CAMEL$Section" :requestRoute="route('api.$MODEL_NAME_SNAKE$.delete', $MODEL_NAME_CAMEL$.id)" name="$MODEL_NAME_DASHED$"></delete-component>
</div>
</template>
<script>
export default {
props: {
data: {
type: Object,
required: true
}
},
data() {
return {
$MODEL_NAME_CAMEL$: this.data,
}
},
watch: {
'data': function() {
this.$MODEL_NAME_CAMEL$ = this.data;
}
}
}
</script>
@@ -0,0 +1,49 @@
<template>
<div class="app-menu">
<div class="p-4 h-100">
<div class="scroll">
<p class="text-muted text-small">Filter</p>
<div class="row">
<div class="col">
<div class="row mb-3">
<div class="col">
$FIELDS$
</div>
</div>
<div class="row mb-3">
<div class="col">
<div class="row">
<div class="col">
<button type="button" class="btn btn-secondary btn-block" @click="updateFilters()">Search</button>
</div>
</div>
<div class="row mt-3">
<div class="col text-center">
<small class="text-small text-muted pointer" @click="resetForm();updateFilters()">Clear Search Filters</small>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
section: {
type: String,
required: true
}
},
data(){
return {
parameters: {
$REQUEST_FIELDS$
},
}
}
}
</script>
@@ -0,0 +1,63 @@
<template>
<div class="row" v-on:keyup.enter="submitForm()">
<div class="col">
<div class="row mb-3">
<div class="col">
$FIELDS$
</div>
</div>
<div class="row mb-3">
<div class="col">
<div class="row">
<div class="col text-right">
<button type="button" class="btn btn-outline-dark float-left" @click="closeModal()">Cancel</button>
<button type="button" class="btn btn-primary" @click="submitForm()">Submit</button>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { required, email } from "vuelidate/lib/validators";
export default {
props: {
section: {
type: String,
required: true
},
data: {
type: Object,
default: null
}
},
created() {
if(this.data){
this.parameters = this.data;
}
},
data() {
return {
parameters: {
$REQUEST_FIELDS$
},
};
},
validations: {
parameters: {
$VALIDATION$
}
},
methods:{
submitForm(){
this.submit((this.data ? this.route('api.$MODEL_NAME_SNAKE$.update', this.data.id) : this.route('api.$MODEL_NAME_SNAKE$.create')), (this.data ? 'put' : 'post'), this.section+'.form', true, true)
},
successHandler(){
this.crudSuccess();
}
}
}
</script>
@@ -0,0 +1,193 @@
<?php
namespace $NAMESPACE_APP$\Repositories;
use Illuminate\Container\Container as Application;
use Illuminate\Database\Eloquent\Model;
abstract class BaseRepository
{
/**
* @var Model
*/
protected $model;
/**
* @var Application
*/
protected $app;
/**
* @param Application $app
*
* @throws \Exception
*/
public function __construct(Application $app)
{
$this->app = $app;
$this->makeModel();
}
/**
* Get searchable fields array
*
* @return array
*/
abstract public function getFieldsSearchable();
/**
* Configure the Model
*
* @return string
*/
abstract public function model();
/**
* Make Model instance
*
* @throws \Exception
*
* @return Model
*/
public function makeModel()
{
$model = $this->app->make($this->model());
if (!$model instanceof Model) {
throw new \Exception("Class {$this->model()} must be an instance of Illuminate\\Database\\Eloquent\\Model");
}
return $this->model = $model;
}
/**
* Paginate records for scaffold.
*
* @param int $perPage
* @param array $columns
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
*/
public function paginate($perPage, $columns = ['*'])
{
$query = $this->allQuery();
return $query->paginate($perPage, $columns);
}
/**
* Build a query for retrieving all records.
*
* @param array $search
* @param int|null $skip
* @param int|null $limit
* @return \Illuminate\Database\Eloquent\Builder
*/
public function allQuery($search = [], $skip = null, $limit = null)
{
$query = $this->model->newQuery();
if (count($search)) {
foreach($search as $key => $value) {
if (in_array($key, $this->getFieldsSearchable())) {
$query->where($key, $value);
}
}
}
if (!is_null($skip)) {
$query->skip($skip);
}
if (!is_null($limit)) {
$query->limit($limit);
}
return $query;
}
/**
* Retrieve all records with given filter criteria
*
* @param array $search
* @param int|null $skip
* @param int|null $limit
* @param array $columns
*
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection
*/
public function all($search = [], $skip = null, $limit = null, $columns = ['*'])
{
$query = $this->allQuery($search, $skip, $limit);
return $query->get($columns);
}
/**
* Create model record
*
* @param array $input
*
* @return Model
*/
public function create($input)
{
$model = $this->model->newInstance($input);
$model->save();
return $model;
}
/**
* Find model record for given id
*
* @param int $id
* @param array $columns
*
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|Model|null
*/
public function find($id, $columns = ['*'])
{
$query = $this->model->newQuery();
return $query->find($id, $columns);
}
/**
* Update model record for given id
*
* @param array $input
* @param int $id
*
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|Model
*/
public function update($input, $id)
{
$query = $this->model->newQuery();
$model = $query->findOrFail($id);
$model->fill($input);
$model->save();
return $model;
}
/**
* @param int $id
*
* @throws \Exception
*
* @return bool|mixed|null
*/
public function delete($id)
{
$query = $this->model->newQuery();
$model = $query->findOrFail($id);
return $model->delete();
}
}
@@ -0,0 +1,37 @@
<?php
namespace App\Classes\CodeGenerator\Utils;
class FileUtil
{
public static function createFile($path, $fileName, $contents)
{
if (!file_exists($path)) {
mkdir($path, 0755, true);
}
$path = $path.$fileName;
file_put_contents($path, $contents);
}
public static function createDirectoryIfNotExist($path, $replace = false)
{
if (file_exists($path) && $replace) {
rmdir($path);
}
if (!file_exists($path)) {
mkdir($path, 0755, true);
}
}
public static function deleteFile($path, $fileName)
{
if (file_exists($path.$fileName)) {
return unlink($path.$fileName);
}
return false;
}
}
@@ -0,0 +1,105 @@
<?php
namespace App\Classes\CodeGenerator\Utils;
use App\Classes\CodeGenerator\Common\GeneratorField;
class GeneratorFieldsInputUtil
{
public static function validateFieldInput($fieldInputStr)
{
$fieldInputs = explode(' ', $fieldInputStr);
if (count($fieldInputs) < 2) {
return false;
}
return true;
}
/**
* @param string $fieldInput
* @param string $validations
*
* @return GeneratorField
*/
public static function processFieldInput($fieldInput, $validations)
{
/*
* Field Input Format: field_name <space> db_type <space> html_type(optional) <space> options(optional)
* Options are to skip the field from certain criteria like searchable, fillable, not in form, not in index
* Searchable (s), Fillable (f), In Form (if), In Index (ii)
* Sample Field Inputs
*
* title string text
* body text textarea
* name string,20 text
* post_id integer:unsigned:nullable
* post_id integer:unsigned:nullable:foreign,posts,id
* password string text if,ii,s - options will skip field from being added in form, in index and searchable
*/
$fieldInputsArr = explode(' ', $fieldInput);
$field = new GeneratorField();
$field->name = $fieldInputsArr[0];
$field->parseDBType($fieldInputsArr[1]);
if (count($fieldInputsArr) > 2) {
$field->parseHtmlInput($fieldInputsArr[2]);
}
if (count($fieldInputsArr) > 3) {
$field->parseOptions($fieldInputsArr[3]);
}
$field->validations = $validations;
return $field;
}
public static function prepareKeyValueArrayStr($arr)
{
$arrStr = '[';
foreach ($arr as $key => $item) {
$arrStr .= "'$item' => '$key', ";
}
$arrStr = substr($arrStr, 0, strlen($arrStr) - 2);
$arrStr .= ']';
return $arrStr;
}
public static function prepareValuesArrayStr($arr)
{
$arrStr = '[';
foreach ($arr as $item) {
$arrStr .= "'$item', ";
}
$arrStr = substr($arrStr, 0, strlen($arrStr) - 2);
$arrStr .= ']';
return $arrStr;
}
public static function prepareKeyValueArrFromLabelValueStr($values)
{
$arr = [];
foreach ($values as $value) {
$labelValue = explode(':', $value);
if (count($labelValue) > 1) {
$arr[$labelValue[0]] = $labelValue[1];
} else {
$arr[$labelValue[0]] = $labelValue[0];
}
}
return $arr;
}
}
@@ -0,0 +1,85 @@
<?php
namespace App\Classes\CodeGenerator\Utils;
use App\Classes\CodeGenerator\Common\GeneratorField;
use App\Classes\CodeGenerator\Common\GeneratorHelpers;
use Illuminate\Support\Str;
class HTMLFieldGenerator
{
public static function generateHTML(GeneratorField $field)
{
$fieldTemplate = '';
$generatorHelpers = new GeneratorHelpers();
switch ($field->htmlType) {
case 'text':
case 'number':
case 'checkbox':
$fieldTemplate = $generatorHelpers->get_template('Fields.text');
break;
case 'textarea':
case 'date':
case 'file':
case 'email':
case 'password':
$fieldTemplate = $generatorHelpers->get_template('Fields.'.$field->htmlType);
break;
case 'select':
case 'enum':
$fieldTemplate = $generatorHelpers->get_template('Fields.select');
$radioLabels = GeneratorFieldsInputUtil::prepareKeyValueArrFromLabelValueStr($field->htmlValues);
$fieldTemplate = str_replace(
'$INPUT_ARR$',
GeneratorFieldsInputUtil::prepareKeyValueArrayStr($radioLabels),
$fieldTemplate
);
break;
case 'selectTable':
$inputArr = explode(',', $field->htmlValues[1]);
$selectTable = $field->htmlValues[0];
$fieldTemplate = $generatorHelpers->get_template('Fields.selectable');
$fieldTemplate = str_replace('$SELECT_TABLE$', str::singular($selectTable),$fieldTemplate);
$fieldTemplate = str_replace('$SELECT_TABLE_CAMEL$', str::singular(str::camel($selectTable)),$fieldTemplate);
$fieldTemplate = str_replace('$LABEL_COLUMN$',$inputArr[0],$fieldTemplate);
$fieldTemplate = str_replace('$VALUE_COLUMN$',$inputArr[1],$fieldTemplate);
break;
case 'checkbox_2':
$fieldTemplate = $generatorHelpers->get_template('Fields.checkbox');
if (count($field->htmlValues) > 0) {
$checkboxValue = $field->htmlValues[0];
} else {
$checkboxValue = 1;
}
$fieldTemplate = str_replace('$CHECKBOX_VALUE$', $checkboxValue, $fieldTemplate);
break;
case 'radio':
$fieldTemplate = $generatorHelpers->get_template('Fields.radio_group');
$radioTemplate = $generatorHelpers->get_template('Fields.radio');
$radioLabels = GeneratorFieldsInputUtil::prepareKeyValueArrFromLabelValueStr($field->htmlValues);
$radioButtons = [];
foreach ($radioLabels as $label => $value) {
$radioButtonTemplate = str_replace('$LABEL$', $label, $radioTemplate);
$radioButtonTemplate = str_replace('$VALUE$', $value, $radioButtonTemplate);
$radioButtons[] = $radioButtonTemplate;
}
$fieldTemplate = str_replace('$RADIO_BUTTONS$', implode("\n", $radioButtons), $fieldTemplate);
break;
case 'toggle-switch':
$fieldTemplate = $generatorHelpers->get_template('Fields.toggle-switch');
break;
}
return $fieldTemplate;
}
}
@@ -0,0 +1,41 @@
<?php
namespace App\Classes\CodeGenerator\Utils;
class ResponseUtil
{
/**
* @param string $message
* @param mixed $data
*
* @return array
*/
public static function makeResponse($message, $data)
{
return [
'success' => true,
'data' => $data,
'message' => $message,
];
}
/**
* @param string $message
* @param array $data
*
* @return array
*/
public static function makeError($message, array $data = [])
{
$res = [
'success' => false,
'message' => $message,
];
if (!empty($data)) {
$res['data'] = $data;
}
return $res;
}
}
@@ -0,0 +1,42 @@
<?php
namespace App\Classes\CodeGenerator\Utils;
class SchemaUtil
{
public static function createField($field)
{
$fieldName = $field['fieldName'];
$databaseInputStr = $field['databaseInputs'];
$databaseInputs = explode(':', $databaseInputStr);
$fieldTypeParams = explode(',', array_shift($databaseInputs));
$fieldType = array_shift($fieldTypeParams);
$fieldStr = '$table->'.$fieldType."('".$fieldName."'";
if (count($fieldTypeParams) > 0) {
$fieldStr .= ', '.implode(' ,', $fieldTypeParams);
}
if ($fieldType == 'enum') {
$inputsArr = explode(',', $field['htmlTypeInputs']);
$inputArrStr = GeneratorFieldsInputUtil::prepareValuesArrayStr($inputsArr);
$fieldStr .= ', '.$inputArrStr;
}
$fieldStr .= ')';
if (count($databaseInputs) > 0) {
foreach ($databaseInputs as $databaseInput) {
$databaseInput = explode(',', $databaseInput);
$type = array_shift($databaseInput);
$fieldStr .= "->$type(".implode(',', $databaseInput).')';
}
}
$fieldStr .= ';';
return $fieldStr;
}
}
@@ -0,0 +1,541 @@
<?php
namespace App\Classes\CodeGenerator\Utils;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\Schema\Column;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use App\Classes\CodeGenerator\Common\GeneratorField;
use App\Classes\CodeGenerator\Common\GeneratorFieldRelation;
class GeneratorForeignKey
{
/** @var string */
public $name;
public $localField;
public $foreignField;
public $foreignTable;
public $onUpdate;
public $onDelete;
}
class GeneratorTable
{
/** @var string */
public $primaryKey;
/** @var GeneratorForeignKey[] */
public $foreignKeys;
}
class TableFieldsGenerator
{
/** @var string */
public $tableName;
public $primaryKey;
/** @var bool */
public $defaultSearchable;
/** @var array */
public $timestamps;
/** @var AbstractSchemaManager */
private $schemaManager;
/** @var Column[] */
private $columns;
/** @var GeneratorField[] */
public $fields;
/** @var GeneratorFieldRelation[] */
public $relations;
/** @var array */
public $ignoredFields;
public function __construct($tableName, $ignoredFields, $connection = '')
{
$this->tableName = $tableName;
$this->ignoredFields = $ignoredFields;
if (!empty($connection)) {
$this->schemaManager = DB::connection($connection)->getDoctrineSchemaManager();
} else {
$this->schemaManager = DB::getDoctrineSchemaManager();
}
$platform = $this->schemaManager->getDatabasePlatform();
$defaultMappings = [
'enum' => 'string',
'json' => 'text',
'bit' => 'boolean',
];
$mappings = [];
$mappings = array_merge($mappings, $defaultMappings);
foreach ($mappings as $dbType => $doctrineType) {
$platform->registerDoctrineTypeMapping($dbType, $doctrineType);
}
$columns = $this->schemaManager->listTableColumns($tableName);
$this->columns = [];
foreach ($columns as $column) {
if (!in_array($column->getName(), $ignoredFields)) {
$this->columns[] = $column;
}
}
$this->primaryKey = $this->getPrimaryKeyOfTable($tableName);
$this->timestamps = static::getTimestampFieldNames();
$this->defaultSearchable = false;
}
/**
* Prepares array of GeneratorField from table columns.
*/
public function prepareFieldsFromTable()
{
foreach ($this->columns as $column) {
$type = $column->getType()->getName();
switch ($type) {
case 'integer':
$field = $this->generateIntFieldInput($column, 'integer');
break;
case 'smallint':
$field = $this->generateIntFieldInput($column, 'smallInteger');
break;
case 'bigint':
$field = $this->generateIntFieldInput($column, 'bigInteger');
break;
case 'boolean':
$name = Str::title(str_replace('_', ' ', $column->getName()));
$field = $this->generateField($column, 'boolean', 'checkbox,1');
break;
case 'datetime':
$field = $this->generateField($column, 'datetime', 'date');
break;
case 'datetimetz':
$field = $this->generateField($column, 'dateTimeTz', 'date');
break;
case 'date':
$field = $this->generateField($column, 'date', 'date');
break;
case 'time':
$field = $this->generateField($column, 'time', 'text');
break;
case 'decimal':
$field = $this->generateNumberInput($column, 'decimal');
break;
case 'float':
$field = $this->generateNumberInput($column, 'float');
break;
case 'string':
$field = $this->generateField($column, 'string', 'text');
break;
case 'text':
$field = $this->generateField($column, 'text', 'textarea');
break;
default:
$field = $this->generateField($column, 'string', 'text');
break;
}
if (strtolower($field->name) == 'password') {
$field->htmlType = 'password';
} elseif (strtolower($field->name) == 'email') {
$field->htmlType = 'email';
} elseif (in_array($field->name, $this->timestamps)) {
$field->isSearchable = false;
$field->isFillable = false;
$field->inForm = false;
$field->inIndex = false;
$field->inView = false;
}
$field->isNotNull = (bool) $column->getNotNull();
$field->description = $column->getComment(); // get comments from table
$this->fields[] = $field;
}
}
/**
* Get primary key of given table.
*
* @param string $tableName
*
* @return string|null The column name of the (simple) primary key
*/
public function getPrimaryKeyOfTable($tableName)
{
$column = $this->schemaManager->listTableDetails($tableName)->getPrimaryKey();
return $column ? $column->getColumns()[0] : '';
}
/**
* Get timestamp columns from config.
*
* @return array the set of [created_at column name, updated_at column name]
*/
public static function getTimestampFieldNames()
{
$createdAtName = 'created_at';
$updatedAtName = 'updated_at';
$deletedAtName = 'deleted_at';
return [$createdAtName, $updatedAtName, $deletedAtName];
}
/**
* Generates integer text field for database.
*
* @param string $dbType
* @param Column $column
*
* @return GeneratorField
*/
private function generateIntFieldInput($column, $dbType)
{
$field = new GeneratorField();
$field->name = $column->getName();
$field->parseDBType($dbType);
$field->htmlType = 'number';
if ($column->getAutoincrement()) {
$field->dbInput .= ',true';
} else {
$field->dbInput .= ',false';
}
if ($column->getUnsigned()) {
$field->dbInput .= ',true';
}
return $this->checkForPrimary($field);
}
/**
* Check if key is primary key and sets field options.
*
* @param GeneratorField $field
*
* @return GeneratorField
*/
private function checkForPrimary(GeneratorField $field)
{
if ($field->name == $this->primaryKey) {
$field->isPrimary = true;
$field->isFillable = false;
$field->isSearchable = false;
$field->inIndex = false;
$field->inForm = false;
$field->inView = false;
}
return $field;
}
/**
* Generates field.
*
* @param Column $column
* @param $dbType
* @param $htmlType
*
* @return GeneratorField
*/
private function generateField($column, $dbType, $htmlType)
{
$field = new GeneratorField();
$field->name = $column->getName();
$field->parseDBType($dbType, $column);
$field->parseHtmlInput($htmlType);
return $this->checkForPrimary($field);
}
/**
* Generates number field.
*
* @param Column $column
* @param string $dbType
*
* @return GeneratorField
*/
private function generateNumberInput($column, $dbType)
{
$field = new GeneratorField();
$field->name = $column->getName();
$field->parseDBType($dbType.','.$column->getPrecision().','.$column->getScale());
$field->htmlType = 'number';
return $this->checkForPrimary($field);
}
/**
* Prepares relations (GeneratorFieldRelation) array from table foreign keys.
*/
public function prepareRelations()
{
$foreignKeys = $this->prepareForeignKeys();
$this->checkForRelations($foreignKeys);
}
/**
* Prepares foreign keys from table with required details.
*
* @return GeneratorTable[]
*/
public function prepareForeignKeys()
{
$tables = $this->schemaManager->listTables();
$fields = [];
foreach ($tables as $table) {
$primaryKey = $table->getPrimaryKey();
if ($primaryKey) {
$primaryKey = $primaryKey->getColumns()[0];
}
$formattedForeignKeys = [];
$tableForeignKeys = $table->getForeignKeys();
foreach ($tableForeignKeys as $tableForeignKey) {
$generatorForeignKey = new GeneratorForeignKey();
$generatorForeignKey->name = $tableForeignKey->getName();
$generatorForeignKey->localField = $tableForeignKey->getLocalColumns()[0];
$generatorForeignKey->foreignField = $tableForeignKey->getForeignColumns()[0];
$generatorForeignKey->foreignTable = $tableForeignKey->getForeignTableName();
$generatorForeignKey->onUpdate = $tableForeignKey->onUpdate();
$generatorForeignKey->onDelete = $tableForeignKey->onDelete();
$formattedForeignKeys[] = $generatorForeignKey;
}
$generatorTable = new GeneratorTable();
$generatorTable->primaryKey = $primaryKey;
$generatorTable->foreignKeys = $formattedForeignKeys;
$fields[$table->getName()] = $generatorTable;
}
return $fields;
}
/**
* Prepares relations array from table foreign keys.
*
* @param GeneratorTable[] $tables
*/
private function checkForRelations($tables)
{
// get Model table name and table details from tables list
$modelTableName = $this->tableName;
$modelTable = $tables[$modelTableName];
unset($tables[$modelTableName]);
$this->relations = [];
// detects many to one rules for model table
$manyToOneRelations = $this->detectManyToOne($tables, $modelTable);
if (count($manyToOneRelations) > 0) {
$this->relations = array_merge($this->relations, $manyToOneRelations);
}
foreach ($tables as $tableName => $table) {
$foreignKeys = $table->foreignKeys;
$primary = $table->primaryKey;
// if foreign key count is 2 then check if many to many relationship is there
if (count($foreignKeys) == 2) {
$manyToManyRelation = $this->isManyToMany($tables, $tableName, $modelTable, $modelTableName);
if ($manyToManyRelation) {
$this->relations[] = $manyToManyRelation;
continue;
}
}
// iterate each foreign key and check for relationship
foreach ($foreignKeys as $foreignKey) {
// check if foreign key is on the model table for which we are using generator command
if ($foreignKey->foreignTable == $modelTableName) {
// detect if one to one relationship is there
$isOneToOne = $this->isOneToOne($primary, $foreignKey, $modelTable->primaryKey);
if ($isOneToOne) {
$modelName = model_name_from_table_name($tableName);
$this->relations[] = GeneratorFieldRelation::parseRelation('1t1,'.$modelName);
continue;
}
// detect if one to many relationship is there
$isOneToMany = $this->isOneToMany($primary, $foreignKey, $modelTable->primaryKey);
if ($isOneToMany) {
$modelName = model_name_from_table_name($tableName);
$this->relations[] = GeneratorFieldRelation::parseRelation(
'1tm,'.$modelName.','.$foreignKey->localField
);
continue;
}
}
}
}
}
/**
* Detects many to many relationship
* If table has only two foreign keys
* Both foreign keys are primary key in foreign table
* Also one is from model table and one is from diff table.
*
* @param GeneratorTable[] $tables
* @param string $tableName
* @param GeneratorTable $modelTable
* @param string $modelTableName
*
* @return bool|GeneratorFieldRelation
*/
private function isManyToMany($tables, $tableName, $modelTable, $modelTableName)
{
// get table details
$table = $tables[$tableName];
$isAnyKeyOnModelTable = false;
// many to many model table name
$manyToManyTable = '';
$foreignKeys = $table->foreignKeys;
$primary = $table->primaryKey;
// check if any foreign key is there from model table
foreach ($foreignKeys as $foreignKey) {
if ($foreignKey->foreignTable == $modelTableName) {
$isAnyKeyOnModelTable = true;
}
}
// if foreign key is there
if (!$isAnyKeyOnModelTable) {
return false;
}
foreach ($foreignKeys as $foreignKey) {
$foreignField = $foreignKey->foreignField;
$foreignTableName = $foreignKey->foreignTable;
// if foreign table is model table
if ($foreignTableName == $modelTableName) {
$foreignTable = $modelTable;
} else {
$foreignTable = $tables[$foreignTableName];
// get the many to many model table name
$manyToManyTable = $foreignTableName;
}
// if foreign field is not primary key of foreign table
// then it can not be many to many
if ($foreignField != $foreignTable->primaryKey) {
return false;
break;
}
// if foreign field is primary key of this table
// then it can not be many to many
if ($foreignField == $primary) {
return false;
}
}
if (empty($manyToManyTable)) {
return false;
}
$modelName = model_name_from_table_name($manyToManyTable);
return GeneratorFieldRelation::parseRelation('mtm,'.$modelName.','.$tableName);
}
/**
* Detects if one to one relationship is there
* If foreign key of table is primary key of foreign table
* Also foreign key field is primary key of this table.
*
* @param string $primaryKey
* @param GeneratorForeignKey $foreignKey
* @param string $modelTablePrimary
*
* @return bool
*/
private function isOneToOne($primaryKey, $foreignKey, $modelTablePrimary)
{
if ($foreignKey->foreignField == $modelTablePrimary) {
if ($foreignKey->localField == $primaryKey) {
return true;
}
}
return false;
}
/**
* Detects if one to many relationship is there
* If foreign key of table is primary key of foreign table
* Also foreign key field is not primary key of this table.
*
* @param string $primaryKey
* @param GeneratorForeignKey $foreignKey
* @param string $modelTablePrimary
*
* @return bool
*/
private function isOneToMany($primaryKey, $foreignKey, $modelTablePrimary)
{
if ($foreignKey->foreignField == $modelTablePrimary) {
if ($foreignKey->localField != $primaryKey) {
return true;
}
}
return false;
}
/**
* Detect many to one relationship on model table
* If foreign key of model table is primary key of foreign table.
*
* @param GeneratorTable[] $tables
* @param GeneratorTable $modelTable
*
* @return array
*/
private function detectManyToOne($tables, $modelTable)
{
$manyToOneRelations = [];
$foreignKeys = $modelTable->foreignKeys;
foreach ($foreignKeys as $foreignKey) {
$foreignTable = $foreignKey->foreignTable;
$foreignField = $foreignKey->foreignField;
if (!isset($tables[$foreignTable])) {
continue;
}
if ($foreignField == $tables[$foreignTable]->primaryKey) {
$modelName = model_name_from_table_name($foreignTable);
$manyToOneRelations[] = GeneratorFieldRelation::parseRelation(
'mt1,'.$modelName.','.$foreignKey->localField
);
}
}
return $manyToOneRelations;
}
}