Commit f2511980 authored by m-wynn's avatar m-wynn

artisanコマンド名、copyrightをwinasに変更

言語対応(英語、日本語)
parent bbeca1ef
/vendor
/.env
composer.phar
composer.lock
.DS_Store
Thumbs.db
.idea
.phpunit.result.cache
\ No newline at end of file
The MIT License (MIT)
Copyright © 2024 Winas, INC. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
{
"name": "infyomlabs/laravel-generator",
"type": "library",
"description": "InfyOm Laravel Generator",
"keywords": [
"laravel",
"api",
"model",
"request",
"migration",
"model",
"crud",
"repository",
"view",
"test",
"generator",
"swagger"
],
"license": "MIT",
"authors": [{
"name": "Mitul Golakiya",
"email": "me@mitul.me"
}],
"require": {
"php": "^8.1.0",
"illuminate/support": "^10.0",
"illuminate/console": "^10.0",
"laracasts/flash": "^3.2.2",
"laravelcollective/html": "^6.4",
"symfony/var-exporter": "^6.2.5"
},
"require-dev": {
"phpunit/phpunit": "^10.0.7",
"mockery/mockery": "^1.5.1",
"orchestra/testbench": "^8.0.0",
"pestphp/pest": "2.x-dev",
"pestphp/pest-plugin-laravel": "2.x-dev"
},
"autoload": {
"psr-4": {
"InfyOm\\Generator\\": "src/"
},
"files": [
"src/helpers.php"
]
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"extra": {
"laravel": {
"providers": [
"\\InfyOm\\Generator\\InfyOmGeneratorServiceProvider"
]
}
},
"funding": [{
"type": "opencollective",
"url": "https://opencollective.com/infyomlabs"
}],
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
"allow-plugins": {
"pestphp/pest-plugin": true
}
}
}
<?php
return [
/*
|--------------------------------------------------------------------------
| Paths
|--------------------------------------------------------------------------
|
*/
'path' => [
'migration' => database_path('migrations/'),
'model' => app_path('Models/'),
'datatables' => app_path('DataTables/'),
'livewire_tables' => app_path('Http/Livewire/'),
'repository' => app_path('Repositories/'),
'routes' => base_path('routes/web.php'),
'api_routes' => base_path('routes/api.php'),
'request' => app_path('Http/Requests/'),
'api_request' => app_path('Http/Requests/API/'),
'controller' => app_path('Http/Controllers/'),
'api_controller' => app_path('Http/Controllers/API/'),
'api_resource' => app_path('Http/Resources/'),
'schema_files' => resource_path('model_schemas/'),
'seeder' => database_path('seeders/'),
'database_seeder' => database_path('seeders/DatabaseSeeder.php'),
'factory' => database_path('factories/'),
'view_provider' => app_path('Providers/ViewServiceProvider.php'),
'tests' => base_path('tests/'),
'repository_test' => base_path('tests/Repositories/'),
'api_test' => base_path('tests/APIs/'),
'views' => resource_path('views/'),
'menu_file' => resource_path('views/layouts/menu.blade.php'),
],
/*
|--------------------------------------------------------------------------
| Namespaces
|--------------------------------------------------------------------------
|
*/
'namespace' => [
'model' => 'App\Models',
'datatables' => 'App\DataTables',
'livewire_tables' => 'App\Http\Livewire',
'repository' => 'App\Repositories',
'controller' => 'App\Http\Controllers',
'api_controller' => 'App\Http\Controllers\API',
'api_resource' => 'App\Http\Resources',
'request' => 'App\Http\Requests',
'api_request' => 'App\Http\Requests\API',
'seeder' => 'Database\Seeders',
'factory' => 'Database\Factories',
'tests' => 'Tests',
'repository_test' => 'Tests\Repositories',
'api_test' => 'Tests\APIs',
],
/*
|--------------------------------------------------------------------------
| Templates
|--------------------------------------------------------------------------
|
*/
'templates' => 'adminlte-templates',
/*
|--------------------------------------------------------------------------
| Model extend class
|--------------------------------------------------------------------------
|
*/
'model_extend_class' => 'Illuminate\Database\Eloquent\Model',
/*
|--------------------------------------------------------------------------
| API routes prefix & version
|--------------------------------------------------------------------------
|
*/
'api_prefix' => 'api',
/*
|--------------------------------------------------------------------------
| Options
|--------------------------------------------------------------------------
|
*/
'options' => [
'soft_delete' => false,
'save_schema_file' => true,
'localized' => false,
'repository_pattern' => true,
'resources' => false,
'factory' => false,
'seeder' => false,
'swagger' => false, // generate swagger for your APIs
'tests' => false, // generate test cases for your APIs
'excluded_fields' => ['id'], // Array of columns that doesn't required while creating module
],
/*
|--------------------------------------------------------------------------
| Prefixes
|--------------------------------------------------------------------------
|
*/
'prefixes' => [
'route' => '', // e.g. admin or admin.shipping or admin.shipping.logistics
'namespace' => '', // e.g. Admin or Admin\Shipping or Admin\Shipping\Logistics
'view' => '', // e.g. admin or admin/shipping or admin/shipping/logistics
],
/*
|--------------------------------------------------------------------------
| Table Types
|
| Possible Options: blade, datatables, livewire
|--------------------------------------------------------------------------
|
*/
'tables' => 'blade',
/*
|--------------------------------------------------------------------------
| Timestamp Fields
|--------------------------------------------------------------------------
|
*/
'timestamps' => [
'enabled' => true,
'created_at' => 'created_at',
'updated_at' => 'updated_at',
'deleted_at' => 'deleted_at',
],
/*
|--------------------------------------------------------------------------
| Specify custom doctrine mappings as per your need
|--------------------------------------------------------------------------
|
*/
'from_table' => [
'doctrine_mappings' => [],
],
];
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
'failed' => 'These credentials do not match our records.',
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
'full_name' => 'Full Name',
'email' => 'Email',
'password' => 'Password',
'confirm_password' => 'Confirm Password',
'remember_me' => 'Remember Me',
'sign_in' => 'Sign In',
'sign_out' => 'Sign out',
'register' => 'Register',
'login' => [
'title' => 'Sign in to start your session',
'forgot_password' => 'I forgot my password',
],
'registration' => [
'title' => 'Register a new membership',
'i_agree' => 'I agree to',
'terms' => 'the terms',
'have_membership' => 'I already have a membership',
],
'forgot_password' => [
'title' => 'You forgot your password? Here you can easily retrieve a new password.',
'send_pwd_reset' => 'Send Password Reset Link',
],
'reset_password' => [
'title' => 'You are only one step a way from your new password, recover your password now.',
'reset_pwd_btn' => 'Reset Password',
],
'confirm_passwords' => [
'title' => 'Please confirm your password before continuing.',
'forgot_your_password' => 'Forgot Your Password?',
],
'verify_email' => [
'title' => 'Verify Your Email Address',
'success' => 'A fresh verification link has been sent to your email address',
'notice' => 'Before proceeding, please check your email for a verification link.If you did not receive the email,',
'another_req' => 'click here to request another',
],
'emails' => [
'password' => [
'reset_link' => 'Click here to reset your password',
],
],
];
<?php
return [
'add_new' => 'Add New',
'cancel' => 'Cancel',
'create' => 'Create',
'edit' => 'Edit',
'save' => 'Save',
'delete' => 'Delete',
'detail' => 'Detail',
'back' => 'Back',
'search' => 'Search',
'export' => 'Export',
'print' => 'Print',
'reset' => 'Reset',
'reload' => 'Reload',
'action' => 'Action',
'id' => 'Id',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
'deleted_at' => 'Deleted At',
'are_you_sure' => 'Are you sure?',
];
<?php
return [
'retrieved' => ':model retrieved successfully.',
'saved' => ':model saved successfully.',
'updated' => ':model updated successfully.',
'deleted' => ':model deleted successfully.',
'not_found' => ':model not found',
];
<?php
return [
'failed' => 'メールアドレス、もしくはパスワードが違います',
'throttle' => 'ログイン試行回数がしきい値を超えました。 時間をおいてログインしてください。',
'login' => 'ログインしました',
'logout' => 'ログアウトしました',
'notVerified' => 'メールが認証されていません',
'verified' => 'メールの認証に成功しました',
'alreadyVerified' => '既に認証済みのメールアドレスです',
'sendVerifyMail' => '認証メールを再送しました',
'noUser' => '入力されたメールアドレスのユーザーが存在しません',
'email' => 'メールアドレス',
'password' => 'パスワード',
'confirm_password' => 'パスワードを確認',
'sign_in' => 'ログイン',
'admin_sign_in' => '管理者ログイン',
'sign_out' => 'ログアウト',
'register' => 'ユーザー登録',
'full_name' => '氏名',
'login' => [
'forgot_password' => 'パスワードを忘れた時',
],
'forgot_password' => [
'send_pwd_reset' => 'パスワード変更リンクを送る',
],
'reset_password' => [
'title' => 'パスワードを変更',
'enter_email' => 'メールアドレスを入力してください'
],
'registration' => [
'have_membership' => '既にアカウントを持っている方はこちら'
]
];
\ No newline at end of file
<?php
return [
'add_new' => '新規追加',
'cancel' => 'キャンセル',
'create' => '作成',
'edit' => '編集',
'save' => '保存',
'delete' => '削除',
'detail' => '詳細',
'back' => '戻る',
'search' => '検索',
'export' => 'エクスポート',
'print' => '印刷',
'reset' => 'リセット',
'reload' => '再読み込み',
'action' => 'アクション',
'id' => 'ID',
'created_at' => '作成日時',
'updated_at' => '更新日時',
'deleted_at' => '削除日時',
'are_you_sure' => '本当によろしいですか?',
];
<?php
return [
'retrieved' => ':model が正常に取得されました。',
'saved' => ':model が正常に保存されました。',
'updated' => ':model が正常に更新されました。',
'deleted' => ':model が正常に削除されました。',
'not_found' => ':model が見つかりません。',
];
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Package Test Suite">
<directory suffix=".php">./tests/</directory>
</testsuite>
</testsuites>
<php>
<env name="APP_KEY" value="BckfSJCXivnK6r38GVIWUAxmbBSjTsmF"/>
</php>
</phpunit>
\ No newline at end of file
[
{
"name": "id",
"dbType": "id",
"htmlType": null,
"validations": null,
"searchable": false,
"fillable": false,
"primary": true,
"inForm": false,
"inIndex": false,
"inView": false
},
{
"name": "user_id",
"dbType": "foreignId:constrained",
"htmlType": "number",
"relation": "mt1,User,user_id,id",
"validations": "required|min:1",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true,
"inView": true
},
{
"name": "title",
"dbType": "string",
"htmlType": "text",
"validations": "required",
"searchable": true,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true,
"inView": true
},
{
"name": "body",
"dbType": "text",
"htmlType": "textarea",
"validations": "",
"searchable": true,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true,
"inView": true
},
{
"name": "is_featured",
"dbType": "boolean",
"htmlType": "boolean",
"validations": "",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true,
"inView": true
},
{
"name": "is_enabled",
"dbType": "boolean",
"htmlType": "checkbox",
"validations": "",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true,
"inView": true
},
{
"name": "published_at",
"dbType": "date",
"htmlType": "date",
"validations": "",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true,
"inView": true
},
{
"name": "password",
"dbType": "string",
"htmlType": "password",
"validations": "",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true,
"inView": true
},
{
"name": "post_type",
"dbType": "integer",
"htmlType": "radio:Blog:1,Event:2,Guest:3",
"validations": "",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true,
"inView": true
},
{
"name": "status",
"dbType": "integer",
"htmlType": "select:Draft:1,Published:2,Archived:3",
"validations": "",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true,
"inView": true
},
{
"name": "created_by",
"dbType": "unsignedBigInteger:foreign,users,id",
"htmlType": "number",
"relation": "mt1,User,user_id,id",
"validations": "required|min:1",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true,
"inView": true
},
{
"name": "created_at",
"dbType": "timestamp",
"htmlType": null,
"validations": null,
"searchable": false,
"fillable": false,
"primary": false,
"inForm": false,
"inIndex": false,
"inView": true
},
{
"name": "updated_at",
"dbType": "timestamp",
"htmlType": null,
"validations": null,
"searchable": false,
"fillable": false,
"primary": false,
"inForm": false,
"inIndex": false,
"inView": true
}
]
<?php
namespace InfyOm\Generator\Commands\API;
use InfyOm\Generator\Commands\BaseCommand;
use InfyOm\Generator\Generators\API\APIControllerGenerator;
class APIControllerGeneratorCommand extends BaseCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'infyom.api:controller';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create an api controller command';
public function handle()
{
parent::handle();
/** @var APIControllerGenerator $controllerGenerator */
$controllerGenerator = app(APIControllerGenerator::class);
$controllerGenerator->generate();
$this->performPostActions();
}
/**
* 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(), []);
}
}
<?php
namespace InfyOm\Generator\Commands\API;
use InfyOm\Generator\Commands\BaseCommand;
class APIGeneratorCommand extends BaseCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'winas:api';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a full CRUD API for given model';
public function handle()
{
parent::handle();
$this->fireFileCreatingEvent('api');
$this->generateCommonItems();
$this->generateAPIItems();
$this->performPostActionsWithMigration();
$this->fireFileCreatedEvent('api');
}
/**
* 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(), []);
}
}
<?php
namespace InfyOm\Generator\Commands\API;
use InfyOm\Generator\Commands\BaseCommand;
use InfyOm\Generator\Generators\API\APIRequestGenerator;
class APIRequestsGeneratorCommand extends BaseCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'infyom.api:requests';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create an api request command';
public function handle()
{
parent::handle();
/** @var APIRequestGenerator $controllerGenerator */
$controllerGenerator = app(APIRequestGenerator::class);
$controllerGenerator->generate();
$this->performPostActions();
}
/**
* 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(), []);
}
}
<?php
namespace InfyOm\Generator\Commands\API;
use InfyOm\Generator\Commands\BaseCommand;
use InfyOm\Generator\Generators\API\APITestGenerator;
use InfyOm\Generator\Generators\RepositoryTestGenerator;
class TestsGeneratorCommand extends BaseCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'infyom.api:tests';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create tests command';
public function handle()
{
parent::handle();
/** @var RepositoryTestGenerator $repositoryTestGenerator */
$repositoryTestGenerator = app(RepositoryTestGenerator::class);
$repositoryTestGenerator->generate();
/** @var APITestGenerator $apiTestGenerator */
$apiTestGenerator = app(APITestGenerator::class);
$apiTestGenerator->generate();
$this->performPostActions();
}
/**
* 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(), []);
}
}
<?php
namespace InfyOm\Generator\Commands;
class APIScaffoldGeneratorCommand extends BaseCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'winas:api_scaffold';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a full CRUD API and Scaffold for given model';
/**
* Execute the command.
*
* @return void
*/
public function handle()
{
parent::handle();
$this->fireFileCreatingEvent('api_scaffold');
$this->generateCommonItems();
$this->generateAPIItems();
$this->generateScaffoldItems();
$this->performPostActionsWithMigration();
$this->fireFileCreatedEvent('api_scaffold');
}
/**
* 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(), []);
}
}
<?php
namespace InfyOm\Generator\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Composer;
use Illuminate\Support\Str;
use InfyOm\Generator\Common\GeneratorConfig;
use InfyOm\Generator\Common\GeneratorField;
use InfyOm\Generator\Common\GeneratorFieldRelation;
use InfyOm\Generator\Events\GeneratorFileCreated;
use InfyOm\Generator\Events\GeneratorFileCreating;
use InfyOm\Generator\Events\GeneratorFileDeleted;
use InfyOm\Generator\Events\GeneratorFileDeleting;
use InfyOm\Generator\Generators\API\APIControllerGenerator;
use InfyOm\Generator\Generators\API\APIRequestGenerator;
use InfyOm\Generator\Generators\API\APIResourceGenerator;
use InfyOm\Generator\Generators\API\APIRoutesGenerator;
use InfyOm\Generator\Generators\API\APITestGenerator;
use InfyOm\Generator\Generators\FactoryGenerator;
use InfyOm\Generator\Generators\MigrationGenerator;
use InfyOm\Generator\Generators\ModelGenerator;
use InfyOm\Generator\Generators\RepositoryGenerator;
use InfyOm\Generator\Generators\RepositoryTestGenerator;
use InfyOm\Generator\Generators\Scaffold\ControllerGenerator;
use InfyOm\Generator\Generators\Scaffold\MenuGenerator;
use InfyOm\Generator\Generators\Scaffold\RequestGenerator;
use InfyOm\Generator\Generators\Scaffold\RoutesGenerator;
use InfyOm\Generator\Generators\Scaffold\ViewGenerator;
use InfyOm\Generator\Generators\SeederGenerator;
use InfyOm\Generator\Utils\GeneratorFieldsInputUtil;
use InfyOm\Generator\Utils\TableFieldsGenerator;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\VarExporter\VarExporter;
class BaseCommand extends Command
{
public GeneratorConfig $config;
public Composer $composer;
public function __construct()
{
parent::__construct();
$this->composer = app()['composer'];
}
public function handle()
{
$this->config = app(GeneratorConfig::class);
$this->config->setCommand($this);
$this->config->init();
$this->getFields();
}
public function generateCommonItems()
{
if (!$this->option('fromTable') and !$this->isSkip('migration')) {
$migrationGenerator = app(MigrationGenerator::class);
$migrationGenerator->generate();
}
if (!$this->isSkip('model')) {
$modelGenerator = app(ModelGenerator::class);
$modelGenerator->generate();
}
if (!$this->isSkip('repository') && $this->config->options->repositoryPattern) {
$repositoryGenerator = app(RepositoryGenerator::class);
$repositoryGenerator->generate();
}
if ($this->config->options->factory || (!$this->isSkip('tests') and $this->config->options->tests)) {
$factoryGenerator = app(FactoryGenerator::class);
$factoryGenerator->generate();
}
if ($this->config->options->seeder) {
$seederGenerator = app(SeederGenerator::class);
$seederGenerator->generate();
}
}
public function generateAPIItems()
{
if (!$this->isSkip('requests') and !$this->isSkip('api_requests')) {
$requestGenerator = app(APIRequestGenerator::class);
$requestGenerator->generate();
}
if (!$this->isSkip('controllers') and !$this->isSkip('api_controller')) {
$controllerGenerator = app(APIControllerGenerator::class);
$controllerGenerator->generate();
}
if (!$this->isSkip('routes') and !$this->isSkip('api_routes')) {
$routesGenerator = app(APIRoutesGenerator::class);
$routesGenerator->generate();
}
if (!$this->isSkip('tests') and $this->config->options->tests) {
if ($this->config->options->repositoryPattern) {
$repositoryTestGenerator = app(RepositoryTestGenerator::class);
$repositoryTestGenerator->generate();
}
$apiTestGenerator = app(APITestGenerator::class);
$apiTestGenerator->generate();
}
if ($this->config->options->resources) {
$apiResourceGenerator = app(APIResourceGenerator::class);
$apiResourceGenerator->generate();
}
}
public function generateScaffoldItems()
{
if (!$this->isSkip('requests') and !$this->isSkip('scaffold_requests')) {
$requestGenerator = app(RequestGenerator::class);
$requestGenerator->generate();
}
if (!$this->isSkip('controllers') and !$this->isSkip('scaffold_controller')) {
$controllerGenerator = app(ControllerGenerator::class);
$controllerGenerator->generate();
}
if (!$this->isSkip('views')) {
$viewGenerator = app(ViewGenerator::class);
$viewGenerator->generate();
}
if (!$this->isSkip('routes') and !$this->isSkip('scaffold_routes')) {
$routeGenerator = app(RoutesGenerator::class);
$routeGenerator->generate();
}
if (!$this->isSkip('menu')) {
$menuGenerator = app(MenuGenerator::class);
$menuGenerator->generate();
}
}
public function performPostActions($runMigration = false)
{
if ($this->config->options->saveSchemaFile) {
$this->saveSchemaFile();
}
if ($runMigration) {
if ($this->option('forceMigrate')) {
$this->runMigration();
} elseif (!$this->option('fromTable') and !$this->isSkip('migration')) {
$requestFromConsole = (php_sapi_name() == 'cli');
if ($this->option('jsonFromGUI') && $requestFromConsole) {
$this->runMigration();
} elseif ($requestFromConsole && $this->confirm(infy_nl().'Do you want to migrate database? [y|N]', false)) {
$this->runMigration();
}
}
}
if ($this->config->options->localized) {
$this->saveLocaleFile();
}
if (!$this->isSkip('dump-autoload')) {
$this->info('Generating autoload files');
$this->composer->dumpOptimized();
}
}
public function runMigration(): bool
{
$migrationPath = config('laravel_generator.path.migration', 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): bool
{
if ($this->option('skip')) {
return in_array($skip, explode(',', $this->option('skip') ?? ''));
}
return false;
}
public function performPostActionsWithMigration()
{
$this->performPostActions(true);
}
protected function saveSchemaFile()
{
$fileFields = [];
foreach ($this->config->fields as $field) {
$fileFields[] = [
'name' => $field->name,
'dbType' => $field->dbType,
'htmlType' => $field->htmlType,
'validations' => $field->validations,
'searchable' => $field->isSearchable,
'fillable' => $field->isFillable,
'primary' => $field->isPrimary,
'inForm' => $field->inForm,
'inIndex' => $field->inIndex,
'inView' => $field->inView,
];
}
foreach ($this->config->relations as $relation) {
$fileFields[] = [
'type' => 'relation',
'relation' => $relation->type.','.implode(',', $relation->inputs),
];
}
$path = config('laravel_generator.path.schema_files', resource_path('model_schemas/'));
$fileName = $this->config->modelNames->name.'.json';
if (file_exists($path.$fileName) && !$this->confirmOverwrite($fileName)) {
return;
}
g_filesystem()->createFile($path.$fileName, json_encode($fileFields, JSON_PRETTY_PRINT));
$this->comment("\nSchema File saved: ");
$this->info($fileName);
}
protected function saveLocaleFile()
{
$locales = [
'singular' => $this->config->modelNames->name,
'plural' => $this->config->modelNames->plural,
'fields' => [],
];
foreach ($this->config->fields as $field) {
$locales['fields'][$field->name] = Str::title(str_replace('_', ' ', $field->name));
}
$path = lang_path('en/models/');
$fileName = $this->config->modelNames->snakePlural.'.php';
if (file_exists($path.$fileName) && !$this->confirmOverwrite($fileName)) {
return;
}
$locales = VarExporter::export($locales);
$end = ';'.infy_nl();
$content = "<?php\n\nreturn ".$locales.$end;
g_filesystem()->createFile($path.$fileName, $content);
$this->comment("\nModel Locale File saved.");
$this->info($fileName);
}
protected function confirmOverwrite(string $fileName, string $prompt = ''): bool
{
$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'],
['table', 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'],
['primary', null, InputOption::VALUE_REQUIRED, 'Custom primary key'],
['prefix', null, InputOption::VALUE_REQUIRED, 'Prefix for all files'],
['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)'],
['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'],
['forceMigrate', null, InputOption::VALUE_NONE, 'Specify if you want to run migration or not'],
['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'],
];
}
public function getFields()
{
$this->config->fields = [];
if ($this->option('fieldsFile')) {
$this->parseFieldsFromJsonFile();
return;
}
if ($this->option('jsonFromGUI')) {
$this->parseFieldsFromGUI();
return;
}
if ($this->option('fromTable')) {
$this->parseFieldsFromTable();
return;
}
$this->getFieldsFromConsole();
}
protected function getFieldsFromConsole()
{
$this->info('Specify fields for the model (skip id & timestamp fields, we will add it automatically)');
$this->info('Read docs carefully to specify field inputs)');
$this->info('Enter "exit" to finish');
$this->addPrimaryKey();
while (true) {
$fieldInputStr = $this->ask('Field: (name db_type html_type options)', '');
if (empty($fieldInputStr) || $fieldInputStr == false || $fieldInputStr == 'exit') {
break;
}
if (!GeneratorFieldsInputUtil::validateFieldInput($fieldInputStr)) {
$this->error('Invalid Input. Try again');
continue;
}
$validations = $this->ask('Enter validations: ', false);
$validations = ($validations == false) ? '' : $validations;
if ($this->option('relations')) {
$relation = $this->ask('Enter relationship (Leave Blank to skip):', false);
} else {
$relation = '';
}
$this->config->fields[] = GeneratorField::parseFieldFromConsoleInput(
$fieldInputStr,
$validations
);
if (!empty($relation)) {
$this->config->relations[] = GeneratorFieldRelation::parseRelation($relation);
}
}
if (config('laravel_generator.timestamps.enabled', true)) {
$this->addTimestamps();
}
}
private function addPrimaryKey()
{
$primaryKey = new GeneratorField();
if ($this->option('primary')) {
$primaryKey->name = $this->option('primary') ?? 'id';
} else {
$primaryKey->name = 'id';
}
$primaryKey->parseDBType('id');
$primaryKey->parseOptions('s,f,p,if,ii');
$this->config->fields[] = $primaryKey;
}
private function addTimestamps()
{
$createdAt = new GeneratorField();
$createdAt->name = 'created_at';
$createdAt->parseDBType('timestamp');
$createdAt->parseOptions('s,f,if,ii');
$this->config->fields[] = $createdAt;
$updatedAt = new GeneratorField();
$updatedAt->name = 'updated_at';
$updatedAt->parseDBType('timestamp');
$updatedAt->parseOptions('s,f,if,ii');
$this->config->fields[] = $updatedAt;
}
protected function parseFieldsFromJsonFile()
{
$fieldsFileValue = $this->option('fieldsFile');
if (file_exists($fieldsFileValue)) {
$filePath = $fieldsFileValue;
} elseif (file_exists(base_path($fieldsFileValue))) {
$filePath = base_path($fieldsFileValue);
} else {
$schemaFileDirector = config(
'laravel_generator.path.schema_files',
resource_path('model_schemas/')
);
$filePath = $schemaFileDirector.$fieldsFileValue;
}
if (!file_exists($filePath)) {
$this->error('Fields file not found');
exit;
}
$fileContents = g_filesystem()->getFile($filePath);
$jsonData = json_decode($fileContents, true);
$this->config->fields = [];
foreach ($jsonData as $field) {
if (isset($field['relation'])) {
$this->config->relations[] = GeneratorFieldRelation::parseRelation($field['relation']);
continue;
}
$this->config->fields[] = GeneratorField::parseFieldFromFile($field);
}
}
protected function parseFieldsFromGUI()
{
$fileContents = $this->option('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->config->addDynamicVariable('$TABLE_NAME$', $tableName);
$this->config->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->config->relations[] = GeneratorFieldRelation::parseRelation($field['relation']);
} else {
$this->config->fields[] = GeneratorField::parseFieldFromFile($field);
if (isset($field['relation'])) {
$this->config->relations[] = GeneratorFieldRelation::parseRelation($field['relation']);
}
}
}
}
protected function parseFieldsFromTable()
{
$tableName = $this->config->tableName;
$ignoredFields = $this->option('ignoreFields');
if (!empty($ignoredFields)) {
$ignoredFields = explode(',', trim($ignoredFields));
} else {
$ignoredFields = [];
}
$tableFieldsGenerator = new TableFieldsGenerator($tableName, $ignoredFields, $this->config->connection);
$tableFieldsGenerator->prepareFieldsFromTable();
$tableFieldsGenerator->prepareRelations();
$this->config->fields = $tableFieldsGenerator->fields;
$this->config->relations = $tableFieldsGenerator->relations;
}
private function prepareEventsData(): array
{
return [
'modelName' => $this->config->modelNames->name,
'tableName' => $this->config->tableName,
'nsModel' => $this->config->namespaces->model,
];
}
public function fireFileCreatingEvent($commandType)
{
event(new GeneratorFileCreating($commandType, $this->prepareEventsData()));
}
public function fireFileCreatedEvent($commandType)
{
event(new GeneratorFileCreated($commandType, $this->prepareEventsData()));
}
public function fireFileDeletingEvent($commandType)
{
event(new GeneratorFileDeleting($commandType, $this->prepareEventsData()));
}
public function fireFileDeletedEvent($commandType)
{
event(new GeneratorFileDeleted($commandType, $this->prepareEventsData()));
}
}
<?php
namespace InfyOm\Generator\Commands\Common;
use InfyOm\Generator\Commands\BaseCommand;
use InfyOm\Generator\Generators\MigrationGenerator;
class MigrationGeneratorCommand extends BaseCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'winas:migration';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create migration command';
public function handle()
{
parent::handle();
if ($this->option('fromTable')) {
$this->error('fromTable option is not allowed to use with migration generator');
return;
}
/** @var MigrationGenerator $migrationGenerator */
$migrationGenerator = app(MigrationGenerator::class);
$migrationGenerator->generate();
$this->performPostActionsWithMigration();
}
/**
* 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(), []);
}
}
<?php
namespace InfyOm\Generator\Commands\Common;
use InfyOm\Generator\Commands\BaseCommand;
use InfyOm\Generator\Generators\ModelGenerator;
class ModelGeneratorCommand extends BaseCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'winas:model';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create model command';
public function handle()
{
parent::handle();
/** @var ModelGenerator $modelGenerator */
$modelGenerator = app(ModelGenerator::class);
$modelGenerator->generate();
$this->performPostActions();
}
/**
* 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(), []);
}
}
<?php
namespace InfyOm\Generator\Commands\Common;
use InfyOm\Generator\Commands\BaseCommand;
use InfyOm\Generator\Generators\RepositoryGenerator;
class RepositoryGeneratorCommand extends BaseCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'winas:repository';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create repository command';
public function handle()
{
parent::handle();
/** @var RepositoryGenerator $repositoryGenerator */
$repositoryGenerator = app(RepositoryGenerator::class);
$repositoryGenerator->generate();
$this->performPostActions();
}
/**
* 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(), []);
}
}
<?php
namespace InfyOm\Generator\Commands\Publish;
use Symfony\Component\Console\Input\InputOption;
class GeneratorPublishCommand extends PublishBaseCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'winas:publish';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Publishes & init api routes, base controller, base test cases traits.';
public function handle()
{
$this->updateRouteServiceProvider();
$this->publishTestCases();
$this->publishBaseController();
$repositoryPattern = config('laravel_generator.options.repository_pattern', true);
if ($repositoryPattern) {
$this->publishBaseRepository();
}
if ($this->option('localized')) {
$this->publishLocaleFiles();
}
}
private function updateRouteServiceProvider()
{
$routeServiceProviderPath = app_path('Providers'.DIRECTORY_SEPARATOR.'RouteServiceProvider.php');
if (!file_exists($routeServiceProviderPath)) {
$this->error("Route Service provider not found on $routeServiceProviderPath");
return;
}
$fileContent = g_filesystem()->getFile($routeServiceProviderPath);
$search = "Route::middleware('api')".infy_nl().str(' ')->repeat(16)."->prefix('api')";
$beforeContent = str($fileContent)->before($search);
$afterContent = str($fileContent)->after($search);
$finalContent = $beforeContent.$search.infy_nl().str(' ')->repeat(16)."->as('api.')".$afterContent;
g_filesystem()->createFile($routeServiceProviderPath, $finalContent);
}
private function publishTestCases()
{
$testsPath = config('laravel_generator.path.tests', base_path('tests/'));
$testsNameSpace = config('laravel_generator.namespace.tests', 'Tests');
$createdAtField = config('laravel_generator.timestamps.created_at', 'created_at');
$updatedAtField = config('laravel_generator.timestamps.updated_at', 'updated_at');
$templateData = view('laravel-generator::api.test.api_test_trait', [
'timestamps' => "['$createdAtField', '$updatedAtField']",
'namespacesTests' => $testsNameSpace,
])->render();
$fileName = 'ApiTestTrait.php';
if (file_exists($testsPath.$fileName) && !$this->confirmOverwrite($fileName)) {
return;
}
g_filesystem()->createFile($testsPath.$fileName, $templateData);
$this->info('ApiTestTrait created');
$testAPIsPath = config('laravel_generator.path.api_test', base_path('tests/APIs/'));
if (!file_exists($testAPIsPath)) {
g_filesystem()->createDirectoryIfNotExist($testAPIsPath);
$this->info('APIs Tests directory created');
}
$testRepositoriesPath = config('laravel_generator.path.repository_test', base_path('tests/Repositories/'));
if (!file_exists($testRepositoriesPath)) {
g_filesystem()->createDirectoryIfNotExist($testRepositoriesPath);
$this->info('Repositories Tests directory created');
}
}
private function publishBaseController()
{
$controllerPath = app_path('Http/Controllers/');
$fileName = 'AppBaseController.php';
if (file_exists($controllerPath.$fileName) && !$this->confirmOverwrite($fileName)) {
return;
}
$templateData = view('laravel-generator::stubs.app_base_controller', [
'namespaceApp' => $this->getLaravel()->getNamespace(),
'apiPrefix' => config('laravel_generator.api_prefix'),
])->render();
g_filesystem()->createFile($controllerPath.$fileName, $templateData);
$this->info('AppBaseController created');
}
private function publishBaseRepository()
{
$repositoryPath = app_path('Repositories/');
$fileName = 'BaseRepository.php';
if (file_exists($repositoryPath.$fileName) && !$this->confirmOverwrite($fileName)) {
return;
}
g_filesystem()->createDirectoryIfNotExist($repositoryPath);
$templateData = view('laravel-generator::stubs.base_repository', [
'namespaceApp' => $this->getLaravel()->getNamespace(),
])->render();
g_filesystem()->createFile($repositoryPath.$fileName, $templateData);
$this->info('BaseRepository created');
}
private function publishLocaleFiles()
{
$localesDir = __DIR__.'/../../../locale/';
$this->publishDirectory($localesDir, lang_path(), 'lang', true);
$this->comment('Locale files published');
}
/**
* Get the console command options.
*
* @return array
*/
public function getOptions()
{
return [
['localized', null, InputOption::VALUE_NONE, 'Localize files.'],
];
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [];
}
}
<?php
namespace InfyOm\Generator\Commands\Publish;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
class PublishBaseCommand extends Command
{
public function handle()
{
// Do Nothing
}
public function publishFile($sourceFile, $destinationFile, $fileName)
{
if (file_exists($destinationFile) && !$this->confirmOverwrite($destinationFile)) {
return;
}
copy($sourceFile, $destinationFile);
$this->comment($fileName.' published');
$this->info($destinationFile);
}
public function publishDirectory(string $sourceDir, string $destinationDir, string $dirName, bool $force = false): bool
{
if (file_exists($destinationDir) && !$force && !$this->confirmOverwrite($destinationDir)) {
return false;
}
File::makeDirectory($destinationDir, 493, true, true);
File::copyDirectory($sourceDir, $destinationDir);
$this->comment($dirName.' published');
$this->info($destinationDir);
return true;
}
protected function confirmOverwrite(string $fileName, string $prompt = ''): bool
{
$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 [];
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [];
}
}
<?php
namespace InfyOm\Generator\Commands\Publish;
use Exception;
use Illuminate\View\Factory;
use Symfony\Component\Console\Input\InputArgument;
class PublishTablesCommand extends PublishBaseCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'infyom.publish:tables';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Publishes Table files';
public function handle()
{
$tableType = $this->argument('type');
if ($tableType === 'datatable') {
$this->publishDataTableViews();
return;
}
if ($tableType === 'livewire') {
$this->publishLivewireTableViews();
return;
}
throw new Exception('Invalid Table Type');
}
public function publishLivewireTableViews()
{
$viewsPath = config('laravel_generator.path.views', resource_path('views/'));
$templateType = config('laravel_generator.templates', 'adminlte-templates');
$files = [
'templates.scaffold.table.livewire.actions' => 'common/livewire-tables/actions.blade.php',
];
g_filesystem()->createDirectoryIfNotExist($viewsPath.'common/livewire-tables');
/** @var Factory $viewFactory */
$viewFactory = view();
foreach ($files as $templateView => $destinationView) {
$templateViewPath = $viewFactory->getFinder()->find($templateType.'::'.$templateView);
$content = g_filesystem()->getFile($templateViewPath);
$destinationFile = $viewsPath.$destinationView;
g_filesystem()->createFile($destinationFile, $content);
}
}
protected function publishDataTableViews()
{
$viewsPath = config('laravel_generator.path.views', resource_path('views/'));
$files = [
'layouts.datatables_css' => 'layouts/datatables_css.blade.php',
'layouts.datatables_js' => 'layouts/datatables_js.blade.php',
];
foreach ($files as $templateView => $destinationView) {
$content = view('laravel-generator::scaffold.'.$templateView)->render();
$destinationFile = $viewsPath.$destinationView;
g_filesystem()->createFile($destinationFile, $content);
}
}
/**
* Get the console command arguments.
*
* @return array
*/
public function getArguments()
{
return [
['type', InputArgument::REQUIRED, 'Types of Tables (datatable / livewire)'],
];
}
}
<?php
namespace InfyOm\Generator\Commands\Publish;
class PublishUserCommand extends PublishBaseCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'infyom.publish:user';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Publishes Users CRUD file';
public function handle()
{
$this->copyViews();
$this->updateRoutes();
$this->updateMenu();
$this->publishUserController();
if (config('laravel_generator.options.repository_pattern')) {
$this->publishUserRepository();
}
$this->publishCreateUserRequest();
$this->publishUpdateUserRequest();
}
private function copyViews()
{
$viewsPath = config('laravel_generator.path.views', resource_path('views/'));
$templateType = config('laravel_generator.templates', 'adminlte-templates');
$this->createDirectories($viewsPath.'users');
$files = $this->getViews();
foreach ($files as $templateView => $destinationView) {
$content = view($templateType.'::'.$templateView);
$destinationFile = $viewsPath.$destinationView;
g_filesystem()->createFile($destinationFile, $content);
}
}
private function createDirectories($dir)
{
g_filesystem()->createDirectoryIfNotExist($dir);
}
private function getViews(): array
{
return [
'users.create' => 'users/create.blade.php',
'users.edit' => 'users/edit.blade.php',
'users.fields' => 'users/fields.blade.php',
'users.index' => 'users/index.blade.php',
'users.show' => 'users/show.blade.php',
'users.show_fields' => 'users/show_fields.blade.php',
'users.table' => 'users/table.blade.php',
];
}
private function updateRoutes()
{
$path = config('laravel_generator.path.routes', base_path('routes/web.php'));
$routeContents = g_filesystem()->getFile($path);
$controllerNamespace = config('laravel_generator.namespace.controller');
$routeContents .= infy_nls(2)."Route::resource('users', '$controllerNamespace\UserController')->middleware('auth');";
g_filesystem()->createFile($path, $routeContents);
$this->comment("\nUser route added");
}
private function updateMenu()
{
$viewsPath = config('laravel_generator.path.views', resource_path('views/'));
$templateType = config('laravel_generator.templates', 'adminlte-templates');
$path = $viewsPath.'layouts/menu.blade.php';
$menuContents = g_filesystem()->getFile($path);
$usersMenuContent = view($templateType.'::templates.users.menu')->render();
$menuContents .= infy_nl().$usersMenuContent;
g_filesystem()->createFile($path, $menuContents);
$this->comment("\nUser Menu added");
}
private function publishUserController()
{
$name = 'user_controller';
if (!config('laravel_generator.options.repository_pattern')) {
$name = 'user_controller_without_repository';
}
$controllerPath = config('laravel_generator.path.controller', app_path('Http/Controllers/'));
$controllerPath .= 'UserController.php';
$controllerContents = view('laravel-generator::scaffold.user.'.$name)->render();
g_filesystem()->createFile($controllerPath, $controllerContents);
$this->info('UserController created');
}
private function publishUserRepository()
{
$repositoryPath = config('laravel_generator.path.repository', app_path('Repositories/'));
$fileName = 'UserRepository.php';
g_filesystem()->createDirectoryIfNotExist($repositoryPath);
if (file_exists($repositoryPath.$fileName) && !$this->confirmOverwrite($fileName)) {
return;
}
$templateData = view('laravel-generator::scaffold.user.user_repository')->render();
g_filesystem()->createFile($repositoryPath.$fileName, $templateData);
$this->info('UserRepository created');
}
private function publishCreateUserRequest()
{
$requestPath = config('laravel_generator.path.request', app_path('Http/Requests/'));
$fileName = 'CreateUserRequest.php';
g_filesystem()->createDirectoryIfNotExist($requestPath);
if (file_exists($requestPath.$fileName) && !$this->confirmOverwrite($fileName)) {
return;
}
$templateData = view('laravel-generator::scaffold.user.create_user_request')->render();
g_filesystem()->createFile($requestPath.$fileName, $templateData);
$this->info('CreateUserRequest created');
}
private function publishUpdateUserRequest()
{
$requestPath = config('laravel_generator.path.request', app_path('Http/Requests/'));
$fileName = 'UpdateUserRequest.php';
if (file_exists($requestPath.$fileName) && !$this->confirmOverwrite($fileName)) {
return;
}
$templateData = view('laravel-generator::scaffold.user.update_user_request')->render();
g_filesystem()->createFile($requestPath.$fileName, $templateData);
$this->info('UpdateUserRequest created');
}
/**
* Get the console command options.
*
* @return array
*/
public function getOptions()
{
return [];
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [];
}
}
<?php
namespace InfyOm\Generator\Commands;
use InfyOm\Generator\Common\GeneratorConfig;
use InfyOm\Generator\Generators\API\APIControllerGenerator;
use InfyOm\Generator\Generators\API\APIRequestGenerator;
use InfyOm\Generator\Generators\API\APIRoutesGenerator;
use InfyOm\Generator\Generators\API\APITestGenerator;
use InfyOm\Generator\Generators\FactoryGenerator;
use InfyOm\Generator\Generators\MigrationGenerator;
use InfyOm\Generator\Generators\ModelGenerator;
use InfyOm\Generator\Generators\RepositoryGenerator;
use InfyOm\Generator\Generators\RepositoryTestGenerator;
use InfyOm\Generator\Generators\Scaffold\ControllerGenerator;
use InfyOm\Generator\Generators\Scaffold\MenuGenerator;
use InfyOm\Generator\Generators\Scaffold\RequestGenerator;
use InfyOm\Generator\Generators\Scaffold\RoutesGenerator;
use InfyOm\Generator\Generators\Scaffold\ViewGenerator;
use InfyOm\Generator\Generators\SeederGenerator;
use Symfony\Component\Console\Input\InputArgument;
class RollbackGeneratorCommand extends BaseCommand
{
public GeneratorConfig $config;
protected $name = 'winas:rollback';
protected $description = 'Rollback a full CRUD API and Scaffold for given model';
public function handle()
{
$this->config = app(GeneratorConfig::class);
$this->config->setCommand($this);
$this->config->init();
$type = $this->argument('type');
if (!in_array($type, ['api', 'scaffold', 'api_scaffold'])) {
$this->error('Invalid rollback type');
return 1;
}
$this->fireFileDeletingEvent($type);
$views = $this->option('views');
if (!empty($views)) {
$views = explode(',', $views);
$viewGenerator = new ViewGenerator();
$viewGenerator->rollback($views);
$this->info('Generating autoload files');
$this->composer->dumpOptimized();
$this->fireFileDeletedEvent($type);
return 0;
}
$migrationGenerator = app(MigrationGenerator::class);
$migrationGenerator->rollback();
$modelGenerator = app(ModelGenerator::class);
$modelGenerator->rollback();
if ($this->config->options->repositoryPattern) {
$repositoryGenerator = app(RepositoryGenerator::class);
$repositoryGenerator->rollback();
}
if (in_array($type, ['api', 'api_scaffold'])) {
$requestGenerator = app(APIRequestGenerator::class);
$requestGenerator->rollback();
$controllerGenerator = app(APIControllerGenerator::class);
$controllerGenerator->rollback();
$routesGenerator = app(APIRoutesGenerator::class);
$routesGenerator->rollback();
}
if (in_array($type, ['scaffold', 'api_scaffold'])) {
$requestGenerator = app(RequestGenerator::class);
$requestGenerator->rollback();
$controllerGenerator = app(ControllerGenerator::class);
$controllerGenerator->rollback();
$viewGenerator = app(ViewGenerator::class);
$viewGenerator->rollback();
$routeGenerator = app(RoutesGenerator::class);
$routeGenerator->rollback();
$menuGenerator = app(MenuGenerator::class);
$menuGenerator->rollback();
}
if ($this->config->options->tests) {
$repositoryTestGenerator = app(RepositoryTestGenerator::class);
$repositoryTestGenerator->rollback();
$apiTestGenerator = app(APITestGenerator::class);
$apiTestGenerator->rollback();
}
if ($this->config->options->factory or $this->config->options->tests) {
$factoryGenerator = app(FactoryGenerator::class);
$factoryGenerator->rollback();
}
if ($this->config->options->seeder) {
$seederGenerator = app(SeederGenerator::class);
$seederGenerator->rollback();
}
$this->info('Generating autoload files');
$this->composer->dumpOptimized();
$this->fireFileDeletedEvent($type);
return 0;
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['model', InputArgument::REQUIRED, 'Singular Model name'],
['type', InputArgument::REQUIRED, 'Rollback type: (api / scaffold / api_scaffold)'],
];
}
}
<?php
namespace InfyOm\Generator\Commands\Scaffold;
use InfyOm\Generator\Commands\BaseCommand;
use InfyOm\Generator\Generators\Scaffold\ControllerGenerator;
class ControllerGeneratorCommand extends BaseCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'infyom.scaffold:controller';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create controller command';
public function handle()
{
parent::handle();
/** @var ControllerGenerator $controllerGenerator */
$controllerGenerator = app(ControllerGenerator::class);
$controllerGenerator->generate();
$this->performPostActions();
}
/**
* 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(), []);
}
}
<?php
namespace InfyOm\Generator\Commands\Scaffold;
use InfyOm\Generator\Commands\BaseCommand;
use InfyOm\Generator\Generators\Scaffold\RequestGenerator;
class RequestsGeneratorCommand extends BaseCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'infyom.scaffold:requests';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a full CRUD views for given model';
public function handle()
{
parent::handle();
/** @var RequestGenerator $requestGenerator */
$requestGenerator = app(RequestGenerator::class);
$requestGenerator->generate();
$this->performPostActions();
}
/**
* 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(), []);
}
}
<?php
namespace InfyOm\Generator\Commands\Scaffold;
use InfyOm\Generator\Commands\BaseCommand;
class ScaffoldGeneratorCommand extends BaseCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'winas:scaffold';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a full CRUD views for given model';
public function handle()
{
parent::handle();
if ($this->checkIsThereAnyDataToGenerate()) {
$this->fireFileCreatingEvent('scaffold');
$this->generateCommonItems();
$this->generateScaffoldItems();
$this->performPostActionsWithMigration();
$this->fireFileCreatedEvent('scaffold');
} else {
$this->config->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(), []);
}
protected function checkIsThereAnyDataToGenerate(): bool
{
if (count($this->config->fields) > 1) {
return true;
}
return false;
}
}
<?php
namespace InfyOm\Generator\Commands\Scaffold;
use InfyOm\Generator\Commands\BaseCommand;
use InfyOm\Generator\Generators\Scaffold\ViewGenerator;
class ViewsGeneratorCommand extends BaseCommand
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'infyom.scaffold:views';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create views file command';
public function handle()
{
parent::handle();
/** @var ViewGenerator $viewGenerator */
$viewGenerator = app(ViewGenerator::class);
$viewGenerator->generate();
$this->performPostActions();
}
/**
* 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(), []);
}
}
<?php
namespace InfyOm\Generator\Common;
class FileSystem
{
public function getFile(string $path): string
{
if (!file_exists($path)) {
return '';
}
return file_get_contents($path);
}
public function createFile(string $file, string $contents): bool|int
{
$path = dirname($file);
if (!empty($path) && !file_exists($path)) {
mkdir($path, 0755, true);
}
return file_put_contents($file, $contents);
}
public function createDirectoryIfNotExist(string $path, bool $replace = false): bool
{
if (!empty($path) && file_exists($path) && $replace) {
return rmdir($path);
}
if (!empty($path) && !file_exists($path)) {
return mkdir($path, 0755, true);
}
return false;
}
public function deleteFile(string $path, string $fileName): bool
{
if (file_exists($path.$fileName)) {
return unlink($path.$fileName);
}
return false;
}
}
<?php
namespace InfyOm\Generator\Common;
use Illuminate\Console\Command;
use Illuminate\Support\Str;
use InfyOm\Generator\DTOs\GeneratorNamespaces;
use InfyOm\Generator\DTOs\GeneratorOptions;
use InfyOm\Generator\DTOs\GeneratorPaths;
use InfyOm\Generator\DTOs\GeneratorPrefixes;
use InfyOm\Generator\DTOs\ModelNames;
class GeneratorConfig
{
public GeneratorNamespaces $namespaces;
public GeneratorPaths $paths;
public ModelNames $modelNames;
public GeneratorPrefixes $prefixes;
public GeneratorOptions $options;
public Command $command;
/** @var GeneratorField[] */
public array $fields = [];
/** @var GeneratorFieldRelation[] */
public array $relations = [];
protected static $dynamicVars = [];
public $tableName;
public string $tableType;
public string $apiPrefix;
public $primaryName;
public $connection;
public function init()
{
$this->loadModelNames();
$this->loadPrefixes();
$this->loadPaths();
$this->tableType = config('laravel_generator.tables', 'blade');
$this->apiPrefix = config('laravel_generator.api_prefix', 'api');
$this->loadNamespaces();
$this->prepareTable();
$this->prepareOptions();
}
public static function addDynamicVariable(string $name, $value)
{
self::$dynamicVars[$name] = $value;
}
public static function addDynamicVariables(array $vars)
{
foreach ($vars as $key => $value) {
self::addDynamicVariable($key, $value);
}
}
public function getDynamicVariable(string $name)
{
return self::$dynamicVars[$name];
}
public function setCommand(Command &$command)
{
$this->command = &$command;
}
public function loadModelNames()
{
$modelNames = new ModelNames();
$modelNames->name = $this->command->argument('model');
if ($this->getOption('plural')) {
$modelNames->plural = $this->getOption('plural');
} else {
$modelNames->plural = Str::plural($modelNames->name);
}
$modelNames->camel = Str::camel($modelNames->name);
$modelNames->camelPlural = Str::camel($modelNames->plural);
$modelNames->snake = Str::snake($modelNames->name);
$modelNames->snakePlural = Str::snake($modelNames->plural);
$modelNames->dashed = Str::kebab($modelNames->name);
$modelNames->dashedPlural = Str::kebab($modelNames->plural);
$modelNames->human = Str::title(str_replace('_', ' ', $modelNames->snake));
$modelNames->humanPlural = Str::title(str_replace('_', ' ', $modelNames->snakePlural));
$this->modelNames = $modelNames;
}
public function loadPrefixes()
{
$prefixes = new GeneratorPrefixes();
$prefixes->route = config('laravel_generator.prefixes.route', '');
$prefixes->namespace = config('laravel_generator.prefixes.namespace', '');
$prefixes->view = config('laravel_generator.prefixes.view', '');
if ($this->getOption('prefix')) {
$multiplePrefixes = explode('/', $this->getOption('prefix'));
$prefixes->mergeRoutePrefix($multiplePrefixes);
$prefixes->mergeNamespacePrefix($multiplePrefixes);
$prefixes->mergeViewPrefix($multiplePrefixes);
}
$this->prefixes = $prefixes;
}
public function loadPaths()
{
$paths = new GeneratorPaths();
$namespacePrefix = $this->prefixes->namespace;
$viewPrefix = $this->prefixes->view;
if (!empty($namespacePrefix)) {
$namespacePrefix .= '/';
}
if (!empty($viewPrefix)) {
$viewPrefix .= '/';
}
$paths->repository = config(
'laravel_generator.path.repository',
app_path('Repositories/')
).$namespacePrefix;
$paths->model = config('laravel_generator.path.model', app_path('Models/')).$namespacePrefix;
$paths->dataTables = config(
'laravel_generator.path.datatables',
app_path('DataTables/')
).$namespacePrefix;
$paths->livewireTables = config(
'laravel_generator.path.livewire_tables',
app_path('Http/Livewire/')
);
$paths->apiController = config(
'laravel_generator.path.api_controller',
app_path('Http/Controllers/API/')
).$namespacePrefix;
$paths->apiResource = config(
'laravel_generator.path.api_resource',
app_path('Http/Resources/')
).$namespacePrefix;
$paths->apiRequest = config(
'laravel_generator.path.api_request',
app_path('Http/Requests/API/')
).$namespacePrefix;
$paths->apiRoutes = config(
'laravel_generator.path.api_routes',
base_path('routes/api.php')
);
$paths->apiTests = config('laravel_generator.path.api_test', base_path('tests/APIs/'));
$paths->controller = config(
'laravel_generator.path.controller',
app_path('Http/Controllers/')
).$namespacePrefix;
$paths->request = config('laravel_generator.path.request', app_path('Http/Requests/')).$namespacePrefix;
$paths->routes = config('laravel_generator.path.routes', base_path('routes/web.php'));
$paths->factory = config('laravel_generator.path.factory', database_path('factories/'));
$paths->views = config(
'laravel_generator.path.views',
resource_path('views/')
).$viewPrefix.$this->modelNames->snakePlural.'/';
$paths->seeder = config('laravel_generator.path.seeder', database_path('seeders/'));
$paths->databaseSeeder = config('laravel_generator.path.database_seeder', database_path('seeders/DatabaseSeeder.php'));
$paths->viewProvider = config(
'laravel_generator.path.view_provider',
app_path('Providers/ViewServiceProvider.php')
);
$this->paths = $paths;
}
public function loadNamespaces()
{
$prefix = $this->prefixes->namespace;
if (!empty($prefix)) {
$prefix = '\\'.$prefix;
}
$namespaces = new GeneratorNamespaces();
$namespaces->app = app()->getNamespace();
$namespaces->app = substr($namespaces->app, 0, strlen($namespaces->app) - 1);
$namespaces->repository = config('laravel_generator.namespace.repository', 'App\Repositories').$prefix;
$namespaces->model = config('laravel_generator.namespace.model', 'App\Models').$prefix;
$namespaces->seeder = config('laravel_generator.namespace.seeder', 'Database\Seeders').$prefix;
$namespaces->factory = config('laravel_generator.namespace.factory', 'Database\Factories').$prefix;
$namespaces->dataTables = config('laravel_generator.namespace.datatables', 'App\DataTables').$prefix;
$namespaces->livewireTables = config('laravel_generator.namespace.livewire_tables', 'App\Http\Livewire');
$namespaces->modelExtend = config(
'laravel_generator.model_extend_class',
'Illuminate\Database\Eloquent\Model'
);
$namespaces->apiController = config(
'laravel_generator.namespace.api_controller',
'App\Http\Controllers\API'
).$prefix;
$namespaces->apiResource = config(
'laravel_generator.namespace.api_resource',
'App\Http\Resources'
).$prefix;
$namespaces->apiRequest = config(
'laravel_generator.namespace.api_request',
'App\Http\Requests\API'
).$prefix;
$namespaces->request = config(
'laravel_generator.namespace.request',
'App\Http\Requests'
).$prefix;
$namespaces->requestBase = config('laravel_generator.namespace.request', 'App\Http\Requests');
$namespaces->baseController = config('laravel_generator.namespace.controller', 'App\Http\Controllers');
$namespaces->controller = config(
'laravel_generator.namespace.controller',
'App\Http\Controllers'
).$prefix;
$namespaces->apiTests = config('laravel_generator.namespace.api_test', 'Tests\APIs');
$namespaces->repositoryTests = config('laravel_generator.namespace.repository_test', 'Tests\Repositories');
$namespaces->tests = config('laravel_generator.namespace.tests', 'Tests');
$this->namespaces = $namespaces;
}
public function prepareTable()
{
if ($this->getOption('table')) {
$this->tableName = $this->getOption('table');
} else {
$this->tableName = $this->modelNames->snakePlural;
}
if ($this->getOption('primary')) {
$this->primaryName = $this->getOption('primary');
} else {
$this->primaryName = 'id';
}
if ($this->getOption('connection')) {
$this->connection = $this->getOption('connection');
}
}
public function prepareOptions()
{
$options = new GeneratorOptions();
$options->softDelete = config('laravel_generator.options.soft_delete', false);
$options->saveSchemaFile = config('laravel_generator.options.save_schema_file', true);
$options->localized = config('laravel_generator.options.localized', false);
$options->repositoryPattern = config('laravel_generator.options.repository_pattern', true);
$options->resources = config('laravel_generator.options.resources', false);
$options->factory = config('laravel_generator.options.factory', false);
$options->seeder = config('laravel_generator.options.seeder', false);
$options->swagger = config('laravel_generator.options.swagger', false);
$options->tests = config('laravel_generator.options.tests', false);
$options->excludedFields = config('laravel_generator.options.excluded_fields', ['id']);
$this->options = $options;
}
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->loadDynamicVariables();
// }
//
// $addOns = ['swagger', 'tests', 'datatables'];
//
// foreach ($addOns as $addOn) {
// if (isset($jsonData['addOns'][$addOn])) {
// $this->addOns[$addOn] = $jsonData['addOns'][$addOn];
// }
// }
}
public function getOption($option)
{
return $this->command->option($option);
}
public function commandError($error)
{
$this->command->error($error);
}
public function commandComment($message)
{
$this->command->comment($message);
}
public function commandWarn($warning)
{
$this->command->warn($warning);
}
public function commandInfo($message)
{
$this->command->info($message);
}
}
<?php
namespace InfyOm\Generator\Common;
use Illuminate\Support\Str;
class GeneratorField
{
/** @var string */
public string $name;
public string $dbType;
public array $dbTypeParams = [];
public array $dbExtraFunctions = [];
public string $htmlType = '';
public array $htmlValues = [];
public string $description;
public string $validations = '';
public bool $isSearchable = true;
public bool $isFillable = true;
public bool $isPrimary = false;
public bool $inForm = true;
public bool $inIndex = true;
public bool $inView = true;
public bool $isNotNull = false;
public string $migrationText = '';
public string $foreignKeyText = '';
public int $numberDecimalPoints = 2;
/** @var \Doctrine\DBAL\Schema\Column */
public $fieldDetails = null;
public function parseDBType(string $dbInput)
{
$dbInputArr = explode(':', $dbInput);
$dbType = (string) array_shift($dbInputArr);
if (Str::contains($dbType, ',')) {
$dbTypeArr = explode(',', $dbType);
$this->dbType = (string) array_shift($dbTypeArr);
$this->dbTypeParams = $dbTypeArr;
} else {
$this->dbType = $dbType;
}
$this->dbExtraFunctions = $dbInputArr;
// if (!is_null($column)) {
// $this->dbType = ($column->getLength() > 0) ? $this->dbType.','.$column->getLength() : $this->dbType;
// $this->dbType = (!$column->getNotnull()) ? $this->dbType.':nullable' : $this->dbType;
// }
$this->prepareMigrationText();
}
public function parseHtmlInput(string $htmlInput)
{
if (empty($htmlInput)) {
$this->htmlType = 'text';
return;
}
if (!Str::contains($htmlInput, ':')) {
$this->htmlType = $htmlInput;
return;
}
$htmlInputArr = explode(':', $htmlInput);
$this->htmlType = (string) array_shift($htmlInputArr);
$this->htmlValues = explode(',', implode(':', $htmlInputArr));
}
public function parseOptions(string $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;
}
}
protected function prepareMigrationText()
{
$this->migrationText = '$table->';
$this->migrationText .= $this->dbType."('".$this->name."'";
if (!count($this->dbTypeParams) and !count($this->dbExtraFunctions)) {
$this->migrationText .= ');';
return;
}
if (count($this->dbTypeParams)) {
// if ($this->dbType === 'enum') {
// $this->migrationText .= ', [';
// foreach ($fieldTypeParams as $param) {
// $this->migrationText .= "'".$param."',";
// }
// $this->migrationText = substr($this->migrationText, 0, strlen($this->migrationText) - 1);
// $this->migrationText .= ']';
// }
foreach ($this->dbTypeParams as $dbTypeParam) {
$this->migrationText .= ', '.$dbTypeParam;
}
}
$this->migrationText .= ')';
if (!count($this->dbExtraFunctions)) {
$this->migrationText .= ';';
return;
}
$this->foreignKeyText = '';
foreach ($this->dbExtraFunctions as $dbExtraFunction) {
$dbExtraFunctionArr = explode(',', $dbExtraFunction);
$functionName = (string) array_shift($dbExtraFunctionArr);
if ($functionName === 'foreign') {
$foreignTable = array_shift($dbExtraFunctionArr);
$foreignField = array_shift($dbExtraFunctionArr);
$this->foreignKeyText .= "\$table->foreign('".$this->name."')->references('".$foreignField."')->on('".$foreignTable."')";
if (count($dbExtraFunctionArr)) {
$cascade = array_shift($dbExtraFunctionArr);
if ($cascade === 'cascade') {
$this->foreignKeyText .= "->onUpdate('cascade')->onDelete('cascade')";
}
}
$this->foreignKeyText .= ';';
} else {
$this->migrationText .= '->'.$functionName;
$this->migrationText .= '(';
$this->migrationText .= implode(', ', $dbExtraFunctionArr);
$this->migrationText .= ')';
}
}
$this->migrationText .= ';';
}
public static function parseFieldFromConsoleInput(string $fieldInput, string $validations = ''): self
{
/*
* 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 unsignedinteger:nullable:foreign,posts,id
* password string text if,ii,s - options will skip field from being added in form, in index and searchable
*/
$field = new self();
$fieldInputArr = explode(' ', $fieldInput);
$field->name = $fieldInputArr[0];
$field->parseDBType($fieldInputArr[1]);
$field->parseHtmlInput($fieldInputArr[2]);
if (count($fieldInputArr) > 3) {
$field->parseOptions($fieldInputArr[3]);
}
$field->validations = $validations;
if (str_contains($field->validations, 'required')) {
$field->isNotNull = true;
}
return $field;
}
public static function parseFieldFromFile(array $fieldInput): self
{
$field = new self();
$field->name = $fieldInput['name'];
$field->parseDBType($fieldInput['dbType']);
$field->parseHtmlInput($fieldInput['htmlType'] ?? '');
$field->validations = $fieldInput['validations'] ?? '';
$field->isSearchable = $fieldInput['searchable'] ?? false;
$field->isFillable = $fieldInput['fillable'] ?? true;
$field->isPrimary = $fieldInput['primary'] ?? false;
$field->inForm = $fieldInput['inForm'] ?? true;
$field->inIndex = $fieldInput['inIndex'] ?? true;
$field->inView = $fieldInput['inView'] ?? true;
if (str_contains($field->validations, 'required')) {
$field->isNotNull = true;
}
return $field;
}
public function getTitle(): string
{
return Str::title(str_replace('_', ' ', $this->name));
}
public function variables(): array
{
return [
'fieldName' => $this->name,
'fieldTitle' => $this->getTitle(),
];
}
}
<?php
namespace InfyOm\Generator\Common;
use Illuminate\Support\Str;
class GeneratorFieldRelation
{
public $type;
public array $inputs;
public string $relationName;
public static function parseRelation($relationInput): self
{
$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(string $relationText = null): string
{
$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 '';
}
protected function generateRelation($functionName, $relation, $relationClass)
{
$inputs = $this->inputs;
$relatedModelName = array_shift($inputs);
if (count($inputs) > 0) {
$inputFields = implode("', '", $inputs);
$inputFields = ", '".$inputFields."'";
} else {
$inputFields = '';
}
return view('laravel-generator::model.relationship', [
'relationClass' => $relationClass,
'functionName' => $functionName,
'relation' => $relation,
'relatedModel' => $relatedModelName,
'fields' => $inputFields,
])->render();
}
}
<?php
namespace InfyOm\Generator\Criteria;
use Illuminate\Http\Request;
use Prettus\Repository\Contracts\CriteriaInterface;
class LimitOffsetCriteria implements CriteriaInterface
{
/**
* @var \Illuminate\Http\Request
*/
protected $request;
public function __construct(Request $request)
{
$this->request = $request;
}
/**
* Apply criteria in query repository.
*
* @param $model
* @param \Prettus\Repository\Contracts\RepositoryInterface $repository
*
* @return mixed
*/
public function apply($model, \Prettus\Repository\Contracts\RepositoryInterface $repository)
{
$limit = (int) $this->request->get('limit', null);
$offset = (int) $this->request->get('offset', null);
if ($limit) {
$model = $model->limit($limit);
}
if ($offset && $limit) {
$model = $model->skip($offset);
}
return $model;
}
}
<?php
namespace InfyOm\Generator\DTOs;
class GeneratorNamespaces
{
public string $app;
public string $repository;
public string $model;
public string $dataTables;
public string $livewireTables;
public string $modelExtend;
public string $seeder;
public string $factory;
public string $apiController;
public string $apiResource;
public string $apiRequest;
public string $request;
public string $requestBase;
public string $controller;
public string $baseController;
public string $apiTests;
public string $repositoryTests;
public string $testTraits;
public string $tests;
}
<?php
namespace InfyOm\Generator\DTOs;
class GeneratorOptions
{
public bool $softDelete;
public bool $saveSchemaFile;
public bool $localized;
public bool $repositoryPattern;
public bool $resources;
public bool $factory;
public bool $seeder;
public bool $swagger;
public bool $tests;
public array $excludedFields;
}
<?php
namespace InfyOm\Generator\DTOs;
class GeneratorPaths
{
public string $repository;
public string $model;
public string $dataTables;
public string $livewireTables;
public string $factory;
public string $seeder;
public string $databaseSeeder;
public string $viewProvider;
public string $apiController;
public string $apiResource;
public string $apiRequest;
public string $apiRoutes;
public string $apiTests;
public string $controller;
public string $request;
public string $routes;
public string $views;
}
<?php
namespace InfyOm\Generator\DTOs;
use Illuminate\Support\Str;
class GeneratorPrefixes
{
public string $route = '';
public string $view = '';
public string $namespace = '';
public function getRoutePrefixWith($append)
{
if ($this->route) {
return $this->route.$append;
}
return '';
}
public function getViewPrefixWith($append)
{
if ($this->view) {
return $this->view.$append;
}
return '';
}
public function getViewPrefixForInclude()
{
if ($this->view) {
return Str::replace('/', '.', $this->view).'.';
}
return '';
}
public function mergeRoutePrefix(array $prefixes)
{
foreach ($prefixes as $prefix) {
if (empty($prefix)) {
continue;
}
$this->route .= '.'.Str::camel($prefix);
}
$this->route = ltrim($this->route, '.');
}
public function mergeNamespacePrefix(array $prefixes)
{
foreach ($prefixes as $prefix) {
if (empty($prefix)) {
continue;
}
$this->namespace .= '\\'.Str::title($prefix);
}
$this->namespace = ltrim($this->namespace, '\\');
}
public function mergeViewPrefix(array $prefixes)
{
foreach ($prefixes as $prefix) {
if (empty($prefix)) {
continue;
}
$this->view .= '/'.Str::snake($prefix);
}
$this->view = ltrim($this->view, '/');
}
}
<?php
namespace InfyOm\Generator\DTOs;
class ModelNames
{
public string $name;
public string $plural;
public string $camel;
public string $camelPlural;
public string $snake;
public string $snakePlural;
public string $dashed;
public string $dashedPlural;
public string $human;
public string $humanPlural;
}
<?php
namespace InfyOm\Generator\Events;
use Illuminate\Queue\SerializesModels;
class GeneratorFileCreated
{
use SerializesModels;
public string $type;
public array $data;
public function __construct(string $type, array $data)
{
$this->type = $type;
$this->data = $data;
}
}
<?php
namespace InfyOm\Generator\Events;
use Illuminate\Queue\SerializesModels;
class GeneratorFileCreating
{
use SerializesModels;
public string $type;
public array $data;
public function __construct(string $type, array $data)
{
$this->type = $type;
$this->data = $data;
}
}
<?php
namespace InfyOm\Generator\Events;
use Illuminate\Queue\SerializesModels;
class GeneratorFileDeleted
{
use SerializesModels;
public string $type;
public array $data;
public function __construct(string $type, array $data)
{
$this->type = $type;
$this->data = $data;
}
}
<?php
namespace InfyOm\Generator\Events;
use Illuminate\Queue\SerializesModels;
class GeneratorFileDeleting
{
use SerializesModels;
public string $type;
public array $data;
public function __construct(string $type, array $data)
{
$this->type = $type;
$this->data = $data;
}
}
<?php
namespace InfyOm\Generator\Facades;
use Illuminate\Support\Facades\Facade;
use InfyOm\Generator\Common\FileSystem;
use Mockery;
class FileUtils extends Facade
{
protected static function getFacadeAccessor()
{
return FileSystem::class;
}
public static function fake($allowedMethods = [])
{
if (empty($allowedMethods)) {
$allowedMethods = [
'getFile' => '',
'createFile' => true,
'createDirectoryIfNotExist' => true,
'deleteFile' => true,
];
}
static::swap($fake = Mockery::mock()->allows($allowedMethods));
return $fake;
}
}
<?php
namespace InfyOm\Generator\Generators\API;
use Illuminate\Support\Str;
use InfyOm\Generator\Generators\BaseGenerator;
class APIControllerGenerator extends BaseGenerator
{
private string $fileName;
public function __construct()
{
parent::__construct();
$this->path = $this->config->paths->apiController;
$this->fileName = $this->config->modelNames->name.'APIController.php';
}
public function variables(): array
{
return array_merge([], $this->docsVariables());
}
public function getViewName(): string
{
if ($this->config->options->repositoryPattern) {
$templateName = 'repository.controller';
} else {
$templateName = 'model.controller';
}
if ($this->config->options->resources) {
$templateName .= '_resource';
}
return $templateName;
}
public function generate()
{
$viewName = $this->getViewName();
$templateData = view('laravel-generator::api.controller.'.$viewName, $this->variables())->render();
g_filesystem()->createFile($this->path.$this->fileName, $templateData);
$this->config->commandComment(infy_nl().'API Controller created: ');
$this->config->commandInfo($this->fileName);
}
protected function docsVariables(): array
{
$methods = ['controller', 'index', 'store', 'show', 'update', 'destroy'];
if ($this->config->options->swagger) {
$templatePrefix = 'controller';
$templateType = 'swagger-generator';
} else {
$templatePrefix = 'api.docs.controller';
$templateType = 'laravel-generator';
}
$variables = [];
foreach ($methods as $method) {
$variable = 'doc'.Str::title($method);
$variables[$variable] = view($templateType.'::'.$templatePrefix.'.'.$method)->render();
}
return $variables;
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->fileName)) {
$this->config->commandComment('API Controller file deleted: '.$this->fileName);
}
}
}
<?php
namespace InfyOm\Generator\Generators\API;
use InfyOm\Generator\Generators\BaseGenerator;
use InfyOm\Generator\Generators\ModelGenerator;
class APIRequestGenerator extends BaseGenerator
{
private string $createFileName;
private string $updateFileName;
public function __construct()
{
parent::__construct();
$this->path = $this->config->paths->apiRequest;
$this->createFileName = 'Create'.$this->config->modelNames->name.'APIRequest.php';
$this->updateFileName = 'Update'.$this->config->modelNames->name.'APIRequest.php';
}
public function generate()
{
$this->generateCreateRequest();
$this->generateUpdateRequest();
}
protected function generateCreateRequest()
{
$templateData = view('laravel-generator::api.request.create', $this->variables())->render();
g_filesystem()->createFile($this->path.$this->createFileName, $templateData);
$this->config->commandComment(infy_nl().'Create Request created: ');
$this->config->commandInfo($this->createFileName);
}
protected function generateUpdateRequest()
{
$modelGenerator = app(ModelGenerator::class);
$rules = $modelGenerator->generateUniqueRules();
$templateData = view('laravel-generator::api.request.update', [
'uniqueRules' => $rules,
])->render();
g_filesystem()->createFile($this->path.$this->updateFileName, $templateData);
$this->config->commandComment(infy_nl().'Update Request created: ');
$this->config->commandInfo($this->updateFileName);
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->createFileName)) {
$this->config->commandComment('Create API Request file deleted: '.$this->createFileName);
}
if ($this->rollbackFile($this->path, $this->updateFileName)) {
$this->config->commandComment('Update API Request file deleted: '.$this->updateFileName);
}
}
}
<?php
namespace InfyOm\Generator\Generators\API;
use InfyOm\Generator\Generators\BaseGenerator;
class APIResourceGenerator extends BaseGenerator
{
private string $fileName;
public function __construct()
{
parent::__construct();
$this->path = $this->config->paths->apiResource;
$this->fileName = $this->config->modelNames->name.'Resource.php';
}
public function variables(): array
{
return [
'fields' => implode(','.infy_nl_tab(1, 3), $this->generateResourceFields()),
];
}
public function generate()
{
$templateData = view('laravel-generator::api.resource.resource', $this->variables())->render();
g_filesystem()->createFile($this->path.$this->fileName, $templateData);
$this->config->commandComment(infy_nl().'API Resource created: ');
$this->config->commandInfo($this->fileName);
}
protected function generateResourceFields(): array
{
$resourceFields = [];
foreach ($this->config->fields as $field) {
$resourceFields[] = "'".$field->name."' => \$this->".$field->name;
}
return $resourceFields;
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->fileName)) {
$this->config->commandComment('API Resource file deleted: '.$this->fileName);
}
}
}
<?php
namespace InfyOm\Generator\Generators\API;
use Illuminate\Support\Str;
use InfyOm\Generator\Generators\BaseGenerator;
class APIRoutesGenerator extends BaseGenerator
{
public function __construct()
{
parent::__construct();
$this->path = $this->config->paths->apiRoutes;
}
public function generate()
{
$routeContents = g_filesystem()->getFile($this->path);
$routes = view('laravel-generator::api.routes', $this->variables())->render();
if (Str::contains($routeContents, $routes)) {
$this->config->commandInfo(infy_nl().'Menu '.$this->config->modelNames->dashedPlural.' already exists, Skipping Adjustment.');
return;
}
$routeContents .= infy_nls(2).$routes;
g_filesystem()->createFile($this->path, $routeContents);
$this->config->commandComment(infy_nl().$this->config->modelNames->dashedPlural.' api routes added.');
}
public function rollback()
{
$routeContents = g_filesystem()->getFile($this->path);
$routes = view('laravel-generator::api.routes', $this->variables())->render();
if (Str::contains($routeContents, $routes)) {
$routeContents = str_replace($routes, '', $routeContents);
g_filesystem()->createFile($this->path, $routeContents);
$this->config->commandComment('api routes deleted');
}
}
}
<?php
namespace InfyOm\Generator\Generators\API;
use InfyOm\Generator\Generators\BaseGenerator;
class APITestGenerator extends BaseGenerator
{
private string $fileName;
public function __construct()
{
parent::__construct();
$this->path = $this->config->paths->apiTests;
$this->fileName = $this->config->modelNames->name.'ApiTest.php';
}
public function generate()
{
$templateData = view('laravel-generator::api.test.api_test', $this->variables())->render();
g_filesystem()->createFile($this->path.$this->fileName, $templateData);
$this->config->commandComment(infy_nl().'ApiTest created: ');
$this->config->commandInfo($this->fileName);
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->fileName)) {
$this->config->commandComment('API Test file deleted: '.$this->fileName);
}
}
}
<?php
namespace InfyOm\Generator\Generators;
use InfyOm\Generator\Common\GeneratorConfig;
abstract class BaseGenerator
{
public GeneratorConfig $config;
public string $path;
public function __construct()
{
$this->config = app(GeneratorConfig::class);
}
public function rollbackFile($path, $fileName): bool
{
if (file_exists($path.$fileName)) {
return g_filesystem()->deleteFile($path, $fileName);
}
return false;
}
public function variables(): array
{
return [];
}
}
<?php
namespace InfyOm\Generator\Generators;
use Illuminate\Support\Str;
use InfyOm\Generator\Utils\GeneratorFieldsInputUtil;
class FactoryGenerator extends BaseGenerator
{
private string $fileName;
private array $relations = [];
public function __construct()
{
parent::__construct();
$this->path = $this->config->paths->factory;
$this->fileName = $this->config->modelNames->name.'Factory.php';
//setup relations if available
//assumes relation fields are tailed with _id if not supplied
if (property_exists($this->config, 'relations')) {
foreach ($this->config->relations as $r) {
if ($r->type == 'mt1') {
$relation = (isset($r->inputs[0])) ? $r->inputs[0] : null;
if (isset($r->inputs[1])) {
$field = $r->inputs[1];
} else {
$field = Str::snake($relation).'_id';
}
if ($field) {
$rel = $relation;
$this->relations[$field] = [
'relation' => $rel,
'model_class' => $this->config->namespaces->model.'\\'.$relation,
];
}
}
}
}
}
public function variables(): array
{
$relations = $this->getRelationsBootstrap();
return [
'fields' => $this->generateFields(),
'relations' => $relations['text'],
'usedRelations' => $relations['uses'],
];
}
public function generate()
{
$templateData = view('laravel-generator::model.factory', $this->variables())->render();
g_filesystem()->createFile($this->path.$this->fileName, $templateData);
$this->config->commandComment(infy_nl().'Factory created: ');
$this->config->commandInfo($this->fileName);
}
protected function generateFields(): string
{
$fields = [];
//get model validation rules
$class = $this->config->namespaces->model.'\\'.$this->config->modelNames->name;
$rules = [];
if (class_exists($class)) {
$rules = $class::$rules;
}
$relations = array_keys($this->relations);
foreach ($this->config->fields as $field) {
if ($field->isPrimary) {
continue;
}
$fieldData = "'".$field->name."' => ".'$this->faker->';
$rule = null;
if (isset($rules[$field->name])) {
$rule = $rules[$field->name];
}
switch (strtolower($field->dbType)) {
case 'integer':
case 'unsignedinteger':
case 'smallinteger':
case 'biginteger':
case 'unsignedbiginteger':
$fakerData = in_array($field->name, $relations) ? ':relation' : $this->getValidNumber($rule, 999);
break;
case 'long':
case 'double':
case 'float':
case 'decimal':
$fakerData = $this->getValidNumber($rule);
break;
case 'string':
case 'char':
$lower = strtolower($field->name);
$firstChar = substr($lower, 0, 1);
if (str_contains($lower, 'email')) {
$fakerData = 'email';
} elseif ($firstChar == 'f' && str_contains($lower, 'name')) {
$fakerData = 'firstName';
} elseif (($firstChar == 's' || $firstChar == 'l') && str_contains($lower, 'name')) {
$fakerData = 'lastName';
} elseif (str_contains($lower, 'phone')) {
$fakerData = "numerify('0##########')";
} elseif (str_contains($lower, 'password')) {
$fakerData = "lexify('1???@???A???')";
} elseif (strpos($lower, 'address')) {
$fakerData = 'address';
} else {
if (!$rule) {
$rule = 'max:255';
}
$fakerData = $this->getValidText($rule);
}
break;
case 'text':
$fakerData = $rule ? $this->getValidText($rule) : 'text(500)';
break;
case 'boolean':
$fakerData = 'boolean';
break;
case 'date':
$fakerData = "date('Y-m-d')";
break;
case 'datetime':
case 'timestamp':
$fakerData = "date('Y-m-d H:i:s')";
break;
case 'time':
$fakerData = "date('H:i:s')";
break;
case 'enum':
$fakerData = 'randomElement('.
GeneratorFieldsInputUtil::prepareValuesArrayStr($field->htmlValues).
')';
break;
default:
$fakerData = 'word';
}
if ($fakerData == ':relation') {
$fieldData = $this->getValidRelation($field->name);
} else {
$fieldData .= $fakerData;
}
$fields[] = $fieldData;
}
return implode(','.infy_nl_tab(1, 3), $fields);
}
/**
* Generates a valid number based on applicable model rule.
*
* @param string $rule The applicable model rule
* @param int $max The maximum number to generate.
*
* @return string
*/
public function getValidNumber($rule = null, $max = PHP_INT_MAX): string
{
if ($rule) {
$max = $this->extractMinMax($rule, 'max') ?? $max;
$min = $this->extractMinMax($rule, 'min') ?? 0;
return "numberBetween($min, $max)";
} else {
return 'randomDigitNotNull';
}
}
/**
* Generates a valid relation if applicable
* This method assumes the related field primary key is id.
*/
public function getValidRelation(string $fieldName): string
{
$relation = $this->relations[$fieldName]['relation'];
$variable = Str::camel($relation);
return "'".$fieldName."' => ".'$'.$variable.'->id';
}
/**
* Generates a valid text based on applicable model rule.
*
* @param string $rule The applicable model rule.
*/
public function getValidText($rule = null): string
{
if ($rule) {
$max = $this->extractMinMax($rule, 'max') ?? 4096;
$min = $this->extractMinMax($rule) ?? 5;
if ($max < 5) {
//faker text requires at least 5 characters
return "lexify('?????')";
}
if ($min < 5) {
//faker text requires at least 5 characters
$min = 5;
}
return 'text('.'$this->faker->numberBetween('.$min.', '.$max.'))';
} else {
return 'text';
}
}
/**
* Extracts min or max rule for a laravel model.
*/
public function extractMinMax($rule, $t = 'min')
{
$i = strpos($rule, $t);
$e = strpos($rule, '|', $i);
if ($e === false) {
$e = strlen($rule);
}
if ($i !== false) {
$len = $e - ($i + 4);
return substr($rule, $i + 4, $len);
}
return null;
}
/**
* Generate valid model so we can use the id where applicable
* This method assumes the model has a factory.
*/
public function getRelationsBootstrap(): array
{
$text = '';
$uses = '';
foreach ($this->relations as $field => $data) {
$relation = $data['relation'];
$qualifier = $data['model_class'];
$variable = Str::camel($relation);
$model = Str::studly($relation);
if (!empty($text)) {
$text = infy_nl_tab(1, 2);
}
$text .= '$'.$variable.' = '.$model.'::first();'.
infy_nl_tab(1, 2).
'if (!$'.$variable.') {'.
infy_nl_tab(1, 3).
'$'.$variable.' = '.$model.'::factory()->create();'.
infy_nl_tab(1, 2).'}'.infy_nl();
$uses .= infy_nl()."use $qualifier;";
}
return [
'text' => $text,
'uses' => $uses,
];
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->fileName)) {
$this->config->commandComment('Factory file deleted: '.$this->fileName);
}
}
}
<?php
namespace InfyOm\Generator\Generators;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use SplFileInfo;
class MigrationGenerator extends BaseGenerator
{
public function __construct()
{
parent::__construct();
$this->path = config('laravel_generator.path.migration', database_path('migrations/'));
}
public function generate()
{
$templateData = view('laravel-generator::migration', $this->variables())->render();
$fileName = date('Y_m_d_His').'_'.'create_'.strtolower($this->config->tableName).'_table.php';
g_filesystem()->createFile($this->path.$fileName, $templateData);
$this->config->commandComment(infy_nl().'Migration created: ');
$this->config->commandInfo($fileName);
}
public function variables(): array
{
return [
'fields' => $this->generateFields(),
];
}
protected function generateFields(): string
{
$fields = [];
$foreignKeys = [];
$createdAtField = null;
$updatedAtField = null;
if (isset($this->config->fields) && !empty($this->config->fields)) {
foreach ($this->config->fields as $field) {
if ($field->name == 'created_at') {
$createdAtField = $field;
continue;
} else {
if ($field->name == 'updated_at') {
$updatedAtField = $field;
continue;
}
}
$fields[] = $field->migrationText;
if (!empty($field->foreignKeyText)) {
$foreignKeys[] = $field->foreignKeyText;
}
}
}
if ($createdAtField->name ?? '' === 'created_at' and $updatedAtField->name ?? '' === 'updated_at') {
$fields[] = '$table->timestamps();';
} else {
if ($createdAtField) {
$fields[] = $createdAtField->migrationText;
}
if ($updatedAtField) {
$fields[] = $updatedAtField->migrationText;
}
}
if ($this->config->options->softDelete) {
$softDeleteFieldName = config('laravel_generator.timestamps.deleted_at', 'deleted_at');
if ($softDeleteFieldName === 'deleted_at') {
$fields[] = '$table->softDeletes();';
} else {
$fields[] = '$table->softDeletes(\''.$softDeleteFieldName.'\');';
}
}
return implode(infy_nl_tab(1, 3), array_merge($fields, $foreignKeys));
}
public function rollback()
{
$fileName = 'create_'.$this->config->tableName.'_table.php';
/** @var SplFileInfo $allFiles */
$allFiles = File::allFiles($this->path);
$files = [];
if (!empty($allFiles)) {
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->config->commandComment('Migration file deleted: '.$file);
}
break;
}
}
}
}
}
<?php
namespace InfyOm\Generator\Generators;
use Illuminate\Support\Str;
use InfyOm\Generator\Utils\TableFieldsGenerator;
class ModelGenerator extends BaseGenerator
{
/**
* Fields not included in the generator by default.
*/
protected array $excluded_fields = [
'created_at',
'updated_at',
'deleted_at',
];
private string $fileName;
public function __construct()
{
parent::__construct();
$this->path = $this->config->paths->model;
$this->fileName = $this->config->modelNames->name.'.php';
}
public function generate()
{
$templateData = view('laravel-generator::model.model', $this->variables())->render();
g_filesystem()->createFile($this->path.$this->fileName, $templateData);
$this->config->commandComment(infy_nl().'Model created: ');
$this->config->commandInfo($this->fileName);
}
public function variables(): array
{
return [
'fillables' => implode(','.infy_nl_tab(1, 2), $this->generateFillables()),
'casts' => implode(','.infy_nl_tab(1, 2), $this->generateCasts()),
'rules' => implode(','.infy_nl_tab(1, 2), $this->generateRules()),
'swaggerDocs' => $this->fillDocs(),
'customPrimaryKey' => $this->customPrimaryKey(),
'customCreatedAt' => $this->customCreatedAt(),
'customUpdatedAt' => $this->customUpdatedAt(),
'customSoftDelete' => $this->customSoftDelete(),
'relations' => $this->generateRelations(),
'timestamps' => config('laravel_generator.timestamps.enabled', true),
];
}
protected function customPrimaryKey()
{
$primary = $this->config->getOption('primary');
if (!$primary) {
return null;
}
if ($primary === 'id') {
return null;
}
return $primary;
}
protected function customSoftDelete()
{
$deletedAt = config('laravel_generator.timestamps.deleted_at', 'deleted_at');
if ($deletedAt === 'deleted_at') {
return null;
}
return $deletedAt;
}
protected function customCreatedAt()
{
$createdAt = config('laravel_generator.timestamps.created_at', 'created_at');
if ($createdAt === 'created_at') {
return null;
}
return $createdAt;
}
protected function customUpdatedAt()
{
$updatedAt = config('laravel_generator.timestamps.updated_at', 'updated_at');
if ($updatedAt === 'updated_at') {
return null;
}
return $updatedAt;
}
protected function generateFillables(): array
{
$fillables = [];
if (isset($this->config->fields) && !empty($this->config->fields)) {
foreach ($this->config->fields as $field) {
if ($field->isFillable) {
$fillables[] = "'".$field->name."'";
}
}
}
return $fillables;
}
protected function fillDocs(): string
{
if (!$this->config->options->swagger) {
return '';
}
return $this->generateSwagger();
}
public function generateSwagger(): string
{
$requiredFields = $this->generateRequiredFields();
$fieldTypes = SwaggerGenerator::generateTypes($this->config->fields);
$properties = [];
foreach ($fieldTypes as $fieldType) {
$properties[] = view(
'swagger-generator::model.property',
$fieldType
)->render();
}
$requiredFields = '{'.implode(',', $requiredFields).'}';
return view('swagger-generator::model.model', [
'requiredFields' => $requiredFields,
'properties' => implode(','.infy_nl().' ', $properties),
]);
}
protected function generateRequiredFields(): array
{
$requiredFields = [];
if (isset($this->config->fields) && !empty($this->config->fields)) {
foreach ($this->config->fields as $field) {
if (!empty($field->validations)) {
if (Str::contains($field->validations, 'required')) {
$requiredFields[] = '"'.$field->name.'"';
}
}
}
}
return $requiredFields;
}
protected function generateRules(): array
{
$dont_require_fields = config('laravel_generator.options.hidden_fields', [])
+ config('laravel_generator.options.excluded_fields', $this->excluded_fields);
$rules = [];
foreach ($this->config->fields as $field) {
if (!$field->isPrimary && !in_array($field->name, $dont_require_fields)) {
if ($field->isNotNull && empty($field->validations)) {
$field->validations = 'required';
}
/**
* Generate some sane defaults based on the field type if we
* are generating from a database table.
*/
if ($this->config->getOption('fromTable')) {
$rule = empty($field->validations) ? [] : explode('|', $field->validations);
if (!$field->isNotNull) {
$rule[] = 'nullable';
}
switch ($field->dbType) {
case 'integer':
$rule[] = 'integer';
break;
case 'boolean':
$rule[] = 'boolean';
break;
case 'float':
case 'double':
case 'decimal':
$rule[] = 'numeric';
break;
case 'string':
case 'text':
$rule[] = 'string';
// Enforce a maximum string length if possible.
if ((int) $field->fieldDetails->getLength() > 0) {
$rule[] = 'max:'.$field->fieldDetails->getLength();
}
break;
}
$field->validations = implode('|', $rule);
}
}
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(): string
{
$tableNameSingular = Str::singular($this->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(): array
{
$casts = [];
$timestamps = TableFieldsGenerator::getTimestampFieldNames();
foreach ($this->config->fields as $field) {
if (in_array($field->name, $timestamps)) {
continue;
}
$rule = "'".$field->name."' => ";
switch (strtolower($field->dbType)) {
case 'integer':
case 'increments':
case 'smallinteger':
case 'long':
case 'biginteger':
$rule .= "'integer'";
break;
case 'double':
$rule .= "'double'";
break;
case 'decimal':
$rule .= sprintf("'decimal:%d'", $field->numberDecimalPoints);
break;
case 'float':
$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;
}
protected function generateRelations(): string
{
$relations = [];
$count = 1;
$fieldsArr = [];
if (isset($this->config->relations) && !empty($this->config->relations)) {
foreach ($this->config->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 implode(infy_nl_tab(2), $relations);
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->fileName)) {
$this->config->commandComment('Model file deleted: '.$this->fileName);
}
}
}
<?php
namespace InfyOm\Generator\Generators;
class RepositoryGenerator extends BaseGenerator
{
private string $fileName;
public function __construct()
{
parent::__construct();
$this->path = $this->config->paths->repository;
$this->fileName = $this->config->modelNames->name.'Repository.php';
}
public function variables(): array
{
return [
'fieldSearchable' => $this->getSearchableFields(),
];
}
public function generate()
{
$templateData = view('laravel-generator::repository.repository', $this->variables())->render();
g_filesystem()->createFile($this->path.$this->fileName, $templateData);
$this->config->commandComment(infy_nl().'Repository created: ');
$this->config->commandInfo($this->fileName);
}
protected function getSearchableFields()
{
$searchables = [];
foreach ($this->config->fields as $field) {
if ($field->isSearchable) {
$searchables[] = "'".$field->name."'";
}
}
return implode(','.infy_nl_tab(1, 2), $searchables);
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->fileName)) {
$this->config->commandComment('Repository file deleted: '.$this->fileName);
}
}
}
<?php
namespace InfyOm\Generator\Generators;
class RepositoryTestGenerator extends BaseGenerator
{
private string $fileName;
public function __construct()
{
parent::__construct();
$this->path = config('laravel_generator.path.repository_test', base_path('tests/Repositories/'));
$this->fileName = $this->config->modelNames->name.'RepositoryTest.php';
}
public function generate()
{
$templateData = view('laravel-generator::repository.repository_test', $this->variables())->render();
g_filesystem()->createFile($this->path.$this->fileName, $templateData);
$this->config->commandComment(infy_nl().'RepositoryTest created: ');
$this->config->commandInfo($this->fileName);
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->fileName)) {
$this->config->commandComment('Repository Test file deleted: '.$this->fileName);
}
}
}
<?php
namespace InfyOm\Generator\Generators\Scaffold;
use Exception;
use InfyOm\Generator\Generators\BaseGenerator;
class ControllerGenerator extends BaseGenerator
{
private string $templateType;
private string $fileName;
public function __construct()
{
parent::__construct();
$this->path = $this->config->paths->controller;
$this->templateType = config('laravel_generator.templates', 'adminlte-templates');
$this->fileName = $this->config->modelNames->name.'Controller.php';
}
public function generate()
{
$variables = [];
switch ($this->config->tableType) {
case 'blade':
if ($this->config->options->repositoryPattern) {
$indexMethodView = 'index_method_repository';
} else {
$indexMethodView = 'index_method';
}
$variables['renderType'] = 'paginate(10)';
break;
case 'datatables':
$indexMethodView = 'index_method_datatable';
$this->generateDataTable();
break;
case 'livewire':
$indexMethodView = 'index_method_livewire';
$this->generateLivewireTable();
break;
default:
throw new Exception('Invalid Table Type');
}
if ($this->config->options->repositoryPattern) {
$viewName = 'controller_repository';
} else {
$viewName = 'controller';
}
$variables['indexMethod'] = view('laravel-generator::scaffold.controller.'.$indexMethodView, $variables)
->render();
$templateData = view('laravel-generator::scaffold.controller.'.$viewName, $variables)->render();
g_filesystem()->createFile($this->path.$this->fileName, $templateData);
$this->config->commandComment(infy_nl().'Controller created: ');
$this->config->commandInfo($this->fileName);
}
protected function generateDataTable()
{
$templateData = view('laravel-generator::scaffold.table.datatable', [
'columns' => implode(','.infy_nl_tab(1, 3), $this->generateDataTableColumns()),
])->render();
$path = $this->config->paths->dataTables;
$fileName = $this->config->modelNames->name.'DataTable.php';
g_filesystem()->createFile($path.$fileName, $templateData);
$this->config->commandComment(infy_nl().'DataTable created: ');
$this->config->commandInfo($fileName);
}
protected function generateLivewireTable()
{
$templateData = view('laravel-generator::scaffold.table.livewire', [
'columns' => implode(','.infy_nl_tab(1, 3), $this->generateLivewireTableColumns()),
])->render();
$path = $this->config->paths->livewireTables;
$fileName = $this->config->modelNames->plural.'Table.php';
g_filesystem()->createFile($path.$fileName, $templateData);
$this->config->commandComment(infy_nl().'LivewireTable created: ');
$this->config->commandInfo($fileName);
}
protected function generateDataTableColumns(): array
{
$dataTableColumns = [];
foreach ($this->config->fields as $field) {
if (!$field->inIndex) {
continue;
}
$dataTableColumns[] = trim(view(
$this->templateType.'::templates.scaffold.table.datatable.column',
$field->variables()
)->render());
}
return $dataTableColumns;
}
protected function generateLivewireTableColumns(): array
{
$livewireTableColumns = [];
foreach ($this->config->fields as $field) {
if (!$field->inIndex) {
continue;
}
$fieldTemplate = 'Column::make("'.$field->getTitle().'", "'.$field->name.'")'.infy_nl();
$fieldTemplate .= infy_tabs(4).'->sortable()';
if ($field->isSearchable) {
$fieldTemplate .= infy_nl().infy_tabs(4).'->searchable()';
}
$livewireTableColumns[] = $fieldTemplate;
}
return $livewireTableColumns;
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->fileName)) {
$this->config->commandComment('Controller file deleted: '.$this->fileName);
}
if ($this->config->tableType === 'datatables') {
if ($this->rollbackFile(
$this->config->paths->dataTables,
$this->config->modelNames->name.'DataTable.php'
)) {
$this->config->commandComment('DataTable file deleted: '.$this->fileName);
}
}
if ($this->config->tableType === 'livewire') {
if ($this->rollbackFile(
$this->config->paths->livewireTables,
$this->config->modelNames->plural.'Table.php'
)) {
$this->config->commandComment('Livewire Table file deleted: '.$this->fileName);
}
}
}
}
<?php
namespace InfyOm\Generator\Generators\Scaffold;
use Illuminate\Support\Str;
use InfyOm\Generator\Generators\BaseGenerator;
class MenuGenerator extends BaseGenerator
{
private string $templateType;
public function __construct()
{
parent::__construct();
$this->path = config('laravel_generator.path.menu_file', resource_path('views/layouts/menu.blade.php'));
$this->templateType = config('laravel_generator.templates', 'adminlte-templates');
}
public function generate()
{
$menuContents = g_filesystem()->getFile($this->path);
$menu = view($this->templateType.'::templates.layouts.menu_template')->render();
if (Str::contains($menuContents, $menu)) {
$this->config->commandInfo(infy_nl().'Menu '.$this->config->modelNames->humanPlural.' already exists, Skipping Adjustment.');
return;
}
$menuContents .= infy_nl().$menu;
g_filesystem()->createFile($this->path, $menuContents);
$this->config->commandComment(infy_nl().$this->config->modelNames->dashedPlural.' menu added.');
}
public function rollback()
{
$menuContents = g_filesystem()->getFile($this->path);
$menu = view($this->templateType.'::templates.layouts.menu_template')->render();
if (Str::contains($menuContents, $menu)) {
g_filesystem()->createFile($this->path, str_replace($menu, '', $menuContents));
$this->config->commandComment('menu deleted');
}
}
}
<?php
namespace InfyOm\Generator\Generators\Scaffold;
use InfyOm\Generator\Generators\BaseGenerator;
use InfyOm\Generator\Generators\ModelGenerator;
class RequestGenerator extends BaseGenerator
{
private string $createFileName;
private string $updateFileName;
public function __construct()
{
parent::__construct();
$this->path = $this->config->paths->request;
$this->createFileName = 'Create'.$this->config->modelNames->name.'Request.php';
$this->updateFileName = 'Update'.$this->config->modelNames->name.'Request.php';
}
public function generate()
{
$this->generateCreateRequest();
$this->generateUpdateRequest();
}
protected function generateCreateRequest()
{
$templateData = view('laravel-generator::scaffold.request.create', $this->variables())->render();
g_filesystem()->createFile($this->path.$this->createFileName, $templateData);
$this->config->commandComment(infy_nl().'Create Request created: ');
$this->config->commandInfo($this->createFileName);
}
protected function generateUpdateRequest()
{
$modelGenerator = new ModelGenerator();
$rules = $modelGenerator->generateUniqueRules();
$templateData = view('laravel-generator::scaffold.request.update', [
'uniqueRules' => $rules,
])->render();
g_filesystem()->createFile($this->path.$this->updateFileName, $templateData);
$this->config->commandComment(infy_nl().'Update Request created: ');
$this->config->commandInfo($this->updateFileName);
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->createFileName)) {
$this->config->commandComment('Create Request file deleted: '.$this->createFileName);
}
if ($this->rollbackFile($this->path, $this->updateFileName)) {
$this->config->commandComment('Update Request file deleted: '.$this->updateFileName);
}
}
}
<?php
namespace InfyOm\Generator\Generators\Scaffold;
use Illuminate\Support\Str;
use InfyOm\Generator\Generators\BaseGenerator;
class RoutesGenerator extends BaseGenerator
{
public function __construct()
{
parent::__construct();
$this->path = $this->config->paths->routes;
}
public function generate()
{
$routeContents = g_filesystem()->getFile($this->path);
$routes = view('laravel-generator::scaffold.routes')->render();
if (Str::contains($routeContents, $routes)) {
$this->config->commandInfo(infy_nl().'Route '.$this->config->modelNames->dashedPlural.' already exists, Skipping Adjustment.');
return;
}
$routeContents .= infy_nl().$routes;
g_filesystem()->createFile($this->path, $routeContents);
$this->config->commandComment(infy_nl().$this->config->modelNames->dashedPlural.' routes added.');
}
public function rollback()
{
$routeContents = g_filesystem()->getFile($this->path);
$routes = view('laravel-generator::scaffold.routes')->render();
if (Str::contains($routeContents, $routes)) {
$routeContents = str_replace($routes, '', $routeContents);
g_filesystem()->createFile($this->path, $routeContents);
$this->config->commandComment('scaffold routes deleted');
}
}
}
<?php
namespace InfyOm\Generator\Generators\Scaffold;
use Exception;
use Illuminate\Support\Str;
use InfyOm\Generator\Generators\BaseGenerator;
use InfyOm\Generator\Generators\ViewServiceProviderGenerator;
use InfyOm\Generator\Utils\HTMLFieldGenerator;
class ViewGenerator extends BaseGenerator
{
private string $templateType;
private string $templateViewPath;
public function __construct()
{
parent::__construct();
$this->path = $this->config->paths->views;
$this->templateType = config('laravel_generator.templates', 'adminlte-templates');
$this->templateViewPath = $this->templateType.'::templates';
}
public function generate()
{
if (!file_exists($this->path)) {
mkdir($this->path, 0755, true);
}
// $htmlInputs = Arr::pluck($this->config->fields, 'htmlInput');
//TODO: Manage files
// if (in_array('file', $htmlInputs)) {
// $this->config->addDynamicVariable('$FILES$', ", 'files' => true");
// }
$this->config->commandComment(infy_nl().'Generating Views...');
if ($this->config->getOption('views')) {
$viewsToBeGenerated = explode(',', $this->config->getOption('views'));
if (in_array('index', $viewsToBeGenerated)) {
$this->generateTable();
$this->generateIndex();
}
if (count(array_intersect(['create', 'update'], $viewsToBeGenerated)) > 0) {
$this->generateFields();
}
if (in_array('create', $viewsToBeGenerated)) {
$this->generateCreate();
}
if (in_array('edit', $viewsToBeGenerated)) {
$this->generateUpdate();
}
if (in_array('show', $viewsToBeGenerated)) {
$this->generateShowFields();
$this->generateShow();
}
} else {
$this->generateTable();
$this->generateIndex();
$this->generateFields();
$this->generateCreate();
$this->generateUpdate();
$this->generateShowFields();
$this->generateShow();
}
$this->config->commandComment('Views created: ');
}
protected function generateTable()
{
if ($this->config->tableType === 'livewire') {
return;
}
switch ($this->config->tableType) {
case 'blade':
$templateData = $this->generateBladeTableBody();
break;
case 'datatables':
$templateData = $this->generateDataTableBody();
$this->generateDataTableActions();
break;
default:
throw new Exception('Invalid Table Type');
}
g_filesystem()->createFile($this->path.'table.blade.php', $templateData);
$this->config->commandInfo('table.blade.php created');
}
protected function generateDataTableBody(): string
{
return view($this->templateViewPath.'.scaffold.table.datatable.body')->render();
}
protected function generateDataTableActions()
{
$templateData = view($this->templateViewPath.'.scaffold.table.datatable.actions')->render();
g_filesystem()->createFile($this->path.'datatables_actions.blade.php', $templateData);
$this->config->commandInfo('datatables_actions.blade.php created');
}
protected function generateBladeTableBody(): string
{
$tableBodyFields = [];
foreach ($this->config->fields as $field) {
if (!$field->inIndex) {
continue;
}
$tableBodyFields[] = view($this->templateViewPath.'.scaffold.table.blade.cell', [
'modelVariable' => $this->config->modelNames->camel,
'fieldName' => $field->name,
])->render();
}
$tableBodyFields = implode(infy_nl_tab(1, 5), $tableBodyFields);
$paginate = view($this->templateViewPath.'.scaffold.paginate')->render();
return view($this->templateViewPath.'.scaffold.table.blade.body', [
'fieldHeaders' => $this->generateTableHeaderFields(),
'fieldBody' => $tableBodyFields,
'paginate' => $paginate,
])->render();
}
protected function generateTableHeaderFields(): string
{
$headerFields = [];
foreach ($this->config->fields as $field) {
if (!$field->inIndex) {
continue;
}
$headerFields[] = view(
$this->templateType.'::templates.scaffold.table.blade.header',
$field->variables()
)->render();
}
return implode(infy_nl_tab(1, 4), $headerFields);
}
protected function generateIndex()
{
switch ($this->config->tableType) {
case 'datatables':
case 'blade':
$tableReplaceString = "@include('".$this->config->prefixes->getViewPrefixForInclude().$this->config->modelNames->snakePlural.".table')";
break;
case 'livewire':
$tableReplaceString = view($this->templateViewPath.'.scaffold.table.livewire.body')->render();
break;
default:
throw new Exception('Invalid table type');
}
$templateData = view($this->templateViewPath.'.scaffold.index', ['table' => $tableReplaceString])
->render();
g_filesystem()->createFile($this->path.'index.blade.php', $templateData);
$this->config->commandInfo('index.blade.php created');
}
protected function generateFields()
{
$htmlFields = [];
foreach ($this->config->fields as $field) {
if (!$field->inForm) {
continue;
}
$htmlFields[] = HTMLFieldGenerator::generateHTML(
$field,
$this->templateViewPath
);
// TODO
// if ($field->htmlType == 'selectTable') {
// $inputArr = explode(',', $field->htmlValues[1]);
// $columns = '';
// foreach ($inputArr as $item) {
// $columns .= "'$item'" . ','; //e.g 'email,id,'
// }
// $columns = substr_replace($columns, '', -1); // remove last ,
//
// $htmlValues = explode(',', $field->htmlValues[0]);
// $selectTable = $htmlValues[0];
// $modalName = null;
// if (count($htmlValues) == 2) {
// $modalName = $htmlValues[1];
// }
//
// $tableName = $this->config->tableName;
// $viewPath = $this->config->prefixes->view;
// if (!empty($viewPath)) {
// $tableName = $viewPath . '.' . $tableName;
// }
//
// $variableName = Str::singular($selectTable) . 'Items'; // e.g $userItems
//
// $fieldTemplate = $this->generateViewComposer($tableName, $variableName, $columns, $selectTable, $modalName);
// }
}
g_filesystem()->createFile($this->path.'fields.blade.php', implode(infy_nls(2), $htmlFields));
$this->config->commandInfo('field.blade.php created');
}
private function generateViewComposer($tableName, $variableName, $columns, $selectTable, $modelName = null): string
{
$templateName = 'scaffold.fields.select';
if ($this->config->isLocalizedTemplates()) {
$templateName .= '_locale';
}
$fieldTemplate = get_template($templateName, $this->templateType);
$viewServiceProvider = new ViewServiceProviderGenerator();
$viewServiceProvider->generate();
$viewServiceProvider->addViewVariables($tableName.'.fields', $variableName, $columns, $selectTable, $modelName);
return str_replace(
'$INPUT_ARR$',
'$'.$variableName,
$fieldTemplate
);
}
protected function generateCreate()
{
$templateData = view($this->templateViewPath.'.scaffold.create')->render();
g_filesystem()->createFile($this->path.'create.blade.php', $templateData);
$this->config->commandInfo('create.blade.php created');
}
protected function generateUpdate()
{
$templateData = view($this->templateViewPath.'.scaffold.edit')->render();
g_filesystem()->createFile($this->path.'edit.blade.php', $templateData);
$this->config->commandInfo('edit.blade.php created');
}
protected function generateShowFields()
{
$fieldsStr = '';
foreach ($this->config->fields as $field) {
if (!$field->inView) {
continue;
}
$fieldsStr .= view($this->templateViewPath.'.scaffold.show_field', $field->variables());
$fieldsStr .= infy_nls(2);
}
g_filesystem()->createFile($this->path.'show_fields.blade.php', $fieldsStr);
$this->config->commandInfo('show_fields.blade.php created');
}
protected function generateShow()
{
$templateData = view($this->templateViewPath.'.scaffold.show')->render();
g_filesystem()->createFile($this->path.'show.blade.php', $templateData);
$this->config->commandInfo('show.blade.php created');
}
public function rollback($views = [])
{
$files = [
'table.blade.php',
'index.blade.php',
'fields.blade.php',
'create.blade.php',
'edit.blade.php',
'show.blade.php',
'show_fields.blade.php',
];
if (!empty($views)) {
$files = [];
foreach ($views as $view) {
$files[] = $view.'.blade.php';
}
}
if ($this->config->tableType === 'datatables') {
$files[] = 'datatables_actions.blade.php';
}
foreach ($files as $file) {
if ($this->rollbackFile($this->path, $file)) {
$this->config->commandComment($file.' file deleted');
}
}
}
}
<?php
namespace InfyOm\Generator\Generators;
class SeederGenerator extends BaseGenerator
{
private string $fileName;
public function __construct()
{
parent::__construct();
$this->path = $this->config->paths->seeder;
$this->fileName = $this->config->modelNames->plural.'TableSeeder.php';
}
public function generate()
{
$templateData = view('laravel-generator::model.seeder', $this->variables())->render();
g_filesystem()->createFile($this->path.$this->fileName, $templateData);
$this->config->commandComment(infy_nl().'Seeder created: ');
$this->config->commandInfo($this->fileName);
}
public function rollback()
{
if ($this->rollbackFile($this->path, $this->fileName)) {
$this->config->commandComment('Seeder file deleted: '.$this->fileName);
}
}
}
<?php
namespace InfyOm\Generator\Generators;
use InfyOm\Generator\Common\GeneratorField;
class SwaggerGenerator
{
public static function generateTypes(array $inputFields): array
{
$fieldTypes = [];
/** @var GeneratorField $field */
foreach ($inputFields as $field) {
$fieldData = self::getFieldType($field->dbType);
if (empty($fieldData['fieldType'])) {
continue;
}
$fieldTypes[] = [
'fieldName' => $field->name,
'type' => $fieldData['fieldType'],
'format' => $fieldData['fieldFormat'],
'nullable' => !$field->isNotNull ? 'true' : 'false',
'readOnly' => !$field->isFillable ? 'true' : 'false',
'description' => (!empty($field->description)) ? $field->description : '',
];
}
return $fieldTypes;
}
public static function getFieldType($type): array
{
$fieldType = null;
$fieldFormat = null;
switch (strtolower($type)) {
case 'increments':
case 'integer':
case 'unsignedinteger':
case 'smallinteger':
case 'long':
case 'biginteger':
case 'unsignedbiginteger':
$fieldType = 'integer';
$fieldFormat = 'int32';
break;
case 'double':
case 'float':
case 'real':
case 'decimal':
$fieldType = 'number';
$fieldFormat = 'number';
break;
case 'boolean':
$fieldType = 'boolean';
break;
case 'string':
case 'char':
case 'text':
case 'mediumtext':
case 'longtext':
case 'enum':
$fieldType = 'string';
break;
case 'byte':
$fieldType = 'string';
$fieldFormat = 'byte';
break;
case 'binary':
$fieldType = 'string';
$fieldFormat = 'binary';
break;
case 'password':
$fieldType = 'string';
$fieldFormat = 'password';
break;
case 'date':
$fieldType = 'string';
$fieldFormat = 'date';
break;
case 'datetime':
case 'timestamp':
$fieldType = 'string';
$fieldFormat = 'date-time';
break;
}
return ['fieldType' => $fieldType, 'fieldFormat' => $fieldFormat];
}
}
<?php
namespace InfyOm\Generator\Generators;
use Illuminate\Support\Facades\File;
class ViewServiceProviderGenerator extends BaseGenerator
{
/**
* Generate ViewServiceProvider.
*/
public function generate()
{
$templateData = get_template_file_path('view_service_provider', 'laravel-generator');
$destination = $this->config->paths->viewProvider;
$fileName = basename($destination);
if (File::exists($destination)) {
return;
}
File::copy($templateData, $destination);
$this->config->commandComment($fileName.' published');
$this->config->commandInfo($fileName);
}
/**
* @param string $views
* @param string $variableName
* @param string $columns
* @param string $tableName
* @param string|null $modelName
*/
public function addViewVariables($views, $variableName, $columns, $tableName, $modelName = null)
{
if (!empty($modelName)) {
$model = $modelName;
} else {
$model = model_name_from_table_name($tableName);
}
$this->config->addDynamicVariable('$COMPOSER_VIEWS$', $views);
$this->config->addDynamicVariable('$COMPOSER_VIEW_VARIABLE$', $variableName);
$this->config->addDynamicVariable(
'$COMPOSER_VIEW_VARIABLE_VALUES$',
$model."::pluck($columns)->toArray()"
);
$mainViewContent = $this->addViewComposer();
$mainViewContent = $this->addNamespace($model, $mainViewContent);
$this->addCustomProvider();
g_filesystem()->createFile($this->config->paths->viewProvider, $mainViewContent);
$this->config->commandComment('View service provider file updated.');
}
public function addViewComposer(): string
{
$mainViewContent = g_filesystem()->getFile($this->config->paths->viewProvider);
$newViewStatement = get_template('scaffold.view_composer', 'laravel-generator');
$newViewStatement = fill_template($this->config->dynamicVars, $newViewStatement);
$newViewStatement = infy_nl().$newViewStatement;
preg_match_all('/public function boot(.*)/', $mainViewContent, $matches);
$totalMatches = count($matches[0]);
$lastSeederStatement = $matches[0][$totalMatches - 1];
$replacePosition = strpos($mainViewContent, $lastSeederStatement);
return substr_replace(
$mainViewContent,
$newViewStatement,
$replacePosition + strlen($lastSeederStatement) + 6,
0
);
}
public function addCustomProvider()
{
$configFile = base_path().'/config/app.php';
$file = g_filesystem()->getFile($configFile);
$searchFor = 'Illuminate\View\ViewServiceProvider::class,';
$customProviders = strpos($file, $searchFor);
$isExist = strpos($file, "App\Providers\ViewServiceProvider::class");
if ($customProviders && !$isExist) {
$newChanges = substr_replace(
$file,
infy_nl().infy_tab(8).'\App\Providers\ViewServiceProvider::class,',
$customProviders + strlen($searchFor),
0
);
g_filesystem()->createFile($configFile, $newChanges);
}
}
public function addNamespace($model, $mainViewContent)
{
$newModelStatement = 'use '.$this->config->namespaces->model.'\\'.$model.';';
$isNameSpaceExist = strpos($mainViewContent, $newModelStatement);
$newModelStatement = infy_nl().$newModelStatement;
if (!$isNameSpaceExist) {
preg_match_all('/namespace(.*)/', $mainViewContent, $matches);
$totalMatches = count($matches[0]);
$nameSpaceStatement = $matches[0][$totalMatches - 1];
$replacePosition = strpos($mainViewContent, $nameSpaceStatement);
$mainViewContent = substr_replace(
$mainViewContent,
$newModelStatement,
$replacePosition + strlen($nameSpaceStatement),
0
);
}
return $mainViewContent;
}
}
<?php
namespace InfyOm\Generator;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
use InfyOm\Generator\Commands\API\APIControllerGeneratorCommand;
use InfyOm\Generator\Commands\API\APIGeneratorCommand;
use InfyOm\Generator\Commands\API\APIRequestsGeneratorCommand;
use InfyOm\Generator\Commands\API\TestsGeneratorCommand;
use InfyOm\Generator\Commands\APIScaffoldGeneratorCommand;
use InfyOm\Generator\Commands\Common\MigrationGeneratorCommand;
use InfyOm\Generator\Commands\Common\ModelGeneratorCommand;
use InfyOm\Generator\Commands\Common\RepositoryGeneratorCommand;
use InfyOm\Generator\Commands\Publish\GeneratorPublishCommand;
use InfyOm\Generator\Commands\Publish\PublishTablesCommand;
use InfyOm\Generator\Commands\Publish\PublishUserCommand;
use InfyOm\Generator\Commands\RollbackGeneratorCommand;
use InfyOm\Generator\Commands\Scaffold\ControllerGeneratorCommand;
use InfyOm\Generator\Commands\Scaffold\RequestsGeneratorCommand;
use InfyOm\Generator\Commands\Scaffold\ScaffoldGeneratorCommand;
use InfyOm\Generator\Commands\Scaffold\ViewsGeneratorCommand;
use InfyOm\Generator\Common\FileSystem;
use InfyOm\Generator\Common\GeneratorConfig;
use InfyOm\Generator\Generators\API\APIControllerGenerator;
use InfyOm\Generator\Generators\API\APIRequestGenerator;
use InfyOm\Generator\Generators\API\APIRoutesGenerator;
use InfyOm\Generator\Generators\API\APITestGenerator;
use InfyOm\Generator\Generators\FactoryGenerator;
use InfyOm\Generator\Generators\MigrationGenerator;
use InfyOm\Generator\Generators\ModelGenerator;
use InfyOm\Generator\Generators\RepositoryGenerator;
use InfyOm\Generator\Generators\RepositoryTestGenerator;
use InfyOm\Generator\Generators\Scaffold\ControllerGenerator;
use InfyOm\Generator\Generators\Scaffold\MenuGenerator;
use InfyOm\Generator\Generators\Scaffold\RequestGenerator;
use InfyOm\Generator\Generators\Scaffold\RoutesGenerator;
use InfyOm\Generator\Generators\Scaffold\ViewGenerator;
use InfyOm\Generator\Generators\SeederGenerator;
class InfyOmGeneratorServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
if ($this->app->runningInConsole()) {
$configPath = __DIR__.'/../config/laravel_generator.php';
$this->publishes([
$configPath => config_path('laravel_generator.php'),
], 'laravel-generator-config');
$this->publishes([
__DIR__.'/../views' => resource_path('views/vendor/laravel-generator'),
], 'laravel-generator-templates');
}
$this->registerCommands();
$this->loadViewsFrom(__DIR__.'/../views', 'laravel-generator');
View::composer('*', function ($view) {
$view->with(['config' => app(GeneratorConfig::class)]);
});
Blade::directive('tab', function () {
return '<?php echo infy_tab() ?>';
});
Blade::directive('tabs', function ($count) {
return "<?php echo infy_tabs($count) ?>";
});
Blade::directive('nl', function () {
return '<?php echo infy_nl() ?>';
});
Blade::directive('nls', function ($count) {
return "<?php echo infy_nls($count) ?>";
});
}
private function registerCommands()
{
if (!$this->app->runningInConsole()) {
return;
}
$this->commands([
APIScaffoldGeneratorCommand::class,
APIGeneratorCommand::class,
APIControllerGeneratorCommand::class,
APIRequestsGeneratorCommand::class,
TestsGeneratorCommand::class,
MigrationGeneratorCommand::class,
ModelGeneratorCommand::class,
RepositoryGeneratorCommand::class,
GeneratorPublishCommand::class,
PublishTablesCommand::class,
PublishUserCommand::class,
ControllerGeneratorCommand::class,
RequestsGeneratorCommand::class,
ScaffoldGeneratorCommand::class,
ViewsGeneratorCommand::class,
RollbackGeneratorCommand::class,
]);
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
$this->mergeConfigFrom(__DIR__.'/../config/laravel_generator.php', 'laravel_generator');
$this->app->singleton(GeneratorConfig::class, function () {
return new GeneratorConfig();
});
$this->app->singleton(FileSystem::class, function () {
return new FileSystem();
});
$this->app->singleton(MigrationGenerator::class);
$this->app->singleton(ModelGenerator::class);
$this->app->singleton(RepositoryGenerator::class);
$this->app->singleton(APIRequestGenerator::class);
$this->app->singleton(APIControllerGenerator::class);
$this->app->singleton(APIRoutesGenerator::class);
$this->app->singleton(RequestGenerator::class);
$this->app->singleton(ControllerGenerator::class);
$this->app->singleton(ViewGenerator::class);
$this->app->singleton(RoutesGenerator::class);
$this->app->singleton(MenuGenerator::class);
$this->app->singleton(RepositoryTestGenerator::class);
$this->app->singleton(APITestGenerator::class);
$this->app->singleton(FactoryGenerator::class);
$this->app->singleton(SeederGenerator::class);
}
}
<?php
namespace InfyOm\Generator\Request;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Response;
use Illuminate\Support\Arr;
use InfyOm\Generator\Utils\ResponseUtil;
class APIRequest extends FormRequest
{
/**
* Get the proper failed validation response for the request.
*
* @param array $errors
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function response(array $errors)
{
$messages = implode(' ', Arr::flatten($errors));
return response()->json(ResponseUtil::makeError($messages), Response::HTTP_BAD_REQUEST);
}
}
<?php
namespace InfyOm\Generator\Utils;
class GeneratorFieldsInputUtil
{
public static function validateFieldInput($fieldInputStr): bool
{
$fieldInputs = explode(' ', $fieldInputStr);
if (count($fieldInputs) < 2) {
return false;
}
return true;
}
/**
* Prepare string of associative array.
*/
public static function prepareKeyValueArrayStr(array $arr): string
{
$arrStr = '[';
if (count($arr) > 0) {
foreach ($arr as $key => $item) {
$arrStr .= "'$item' => '$key', ";
}
$arrStr = substr($arrStr, 0, strlen($arrStr) - 2);
}
$arrStr .= ']';
return $arrStr;
}
/**
* Prepare string of array.
*/
public static function prepareValuesArrayStr(array $arr): string
{
$arrStr = '[';
if (count($arr) > 0) {
foreach ($arr as $item) {
$arrStr .= "'$item', ";
}
$arrStr = substr($arrStr, 0, strlen($arrStr) - 2);
}
$arrStr .= ']';
return $arrStr;
}
public static function prepareKeyValueArrFromLabelValueStr($values): array
{
$arr = [];
if (count($values) > 0) {
foreach ($values as $value) {
$labelValue = explode(':', $value);
if (count($labelValue) > 1) {
$arr[$labelValue[0]] = $labelValue[1];
} else {
$arr[$labelValue[0]] = $labelValue[0];
}
}
}
return $arr;
}
}
<?php
namespace InfyOm\Generator\Utils;
use Illuminate\Support\Str;
use InfyOm\Generator\Common\GeneratorField;
class HTMLFieldGenerator
{
public static function generateHTML(GeneratorField $field, $templateType): string
{
$viewName = $field->htmlType;
$variables = [];
if (!empty($validations = self::generateValidations($field))) {
$variables['options'] = ', '.implode(', ', $validations);
}
switch ($field->htmlType) {
case 'select':
case 'enum':
$viewName = 'select';
$keyValues = GeneratorFieldsInputUtil::prepareKeyValueArrFromLabelValueStr($field->htmlValues);
$variables = [
'selectValues' => GeneratorFieldsInputUtil::prepareKeyValueArrayStr($keyValues),
];
break;
case 'checkbox':
if (count($field->htmlValues) > 0) {
$checkboxValue = $field->htmlValues[0];
} else {
$checkboxValue = 1;
}
$variables['checkboxVal'] = $checkboxValue;
break;
case 'radio':
$keyValues = GeneratorFieldsInputUtil::prepareKeyValueArrFromLabelValueStr($field->htmlValues);
$radioButtons = [];
foreach ($keyValues as $label => $value) {
$radioButtons[] = view($templateType.'.fields.radio', [
'label' => $label,
'value' => $value,
'fieldName' => $field->name,
]);
}
return view($templateType.'.fields.radio_group', array_merge(
['radioButtons' => implode(infy_nl_tab(), $radioButtons)],
array_merge(
$field->variables(),
$variables
)
))->render();
}
return view(
$templateType.'.fields.'.$viewName,
array_merge(
$field->variables(),
$variables
)
)->render();
}
public static function generateValidations(GeneratorField $field)
{
$validations = explode('|', $field->validations);
$validationRules = [];
foreach ($validations as $validation) {
if ($validation === 'required') {
$validationRules[] = "'required'";
continue;
}
if (!Str::contains($validation, ['max:', 'min:'])) {
continue;
}
$validationText = substr($validation, 0, 3);
$sizeInNumber = substr($validation, 4);
$sizeText = ($validationText == 'min') ? 'minlength' : 'maxlength';
if ($field->htmlType == 'number') {
$sizeText = $validationText;
}
$size = "'$sizeText' => $sizeInNumber";
$validationRules[] = $size;
}
return $validationRules;
}
}
<?php
namespace InfyOm\Generator\Utils;
class ResponseUtil
{
public static function makeResponse(string $message, mixed $data): array
{
return [
'success' => true,
'data' => $data,
'message' => $message,
];
}
public static function makeError(string $message, array $data = []): array
{
$res = [
'success' => false,
'message' => $message,
];
if (!empty($data)) {
$res['data'] = $data;
}
return $res;
}
}
<?php
namespace InfyOm\Generator\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;
}
}
<?php
namespace InfyOm\Generator\Utils;
use DB;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\Schema\Column;
use Illuminate\Support\Str;
use InfyOm\Generator\Common\GeneratorField;
use InfyOm\Generator\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;
/** @var \Doctrine\DBAL\Schema\Table */
public $tableDetails;
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',
];
// $this->tableDetails = $this->schemaManager->listTableDetails($this->tableName);
$mappings = config('laravel_generator.from_table.doctrine_mappings', []);
$mappings = array_merge($mappings, $defaultMappings);
foreach ($mappings as $dbType => $doctrineType) {
$platform->registerDoctrineTypeMapping($dbType, $doctrineType);
}
// Added
$this->tableDetails = $this->schemaManager->listTableDetails($this->tableName);
$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 = config('laravel_generator.options.tables_searchable_default', 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');
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 '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 = $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()
{
if (!config('laravel_generator.timestamps.enabled', true)) {
return [];
}
$createdAtName = config('laravel_generator.timestamps.created_at', 'created_at');
$updatedAtName = config('laravel_generator.timestamps.updated_at', 'updated_at');
$deletedAtName = config('laravel_generator.timestamps.deleted_at', '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->dbType .= ',true';
} else {
$field->dbType .= ',false';
}
if ($column->getUnsigned()) {
$field->dbType .= ',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->fieldDetails = $this->tableDetails->getColumn($field->name);
$field->parseDBType($dbType); //, $column); TODO: handle column param
$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';
if ($dbType === 'decimal') {
$field->numberDecimalPoints = $column->getScale();
}
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;
}
}
<?php
use Illuminate\Support\Str;
use InfyOm\Generator\Common\FileSystem;
if (!function_exists('g_filesystem')) {
/**
* @return FileSystem
*/
function g_filesystem()
{
return app(FileSystem::class);
}
}
if (!function_exists('infy_tab')) {
function infy_tab(int $spaces = 4): string
{
return str_repeat(' ', $spaces);
}
}
if (!function_exists('infy_tabs')) {
function infy_tabs(int $tabs, int $spaces = 4): string
{
return str_repeat(infy_tab($spaces), $tabs);
}
}
if (!function_exists('infy_nl')) {
function infy_nl(int $count = 1): string
{
return str_repeat(PHP_EOL, $count);
}
}
if (!function_exists('infy_nls')) {
function infy_nls(int $count, int $nls = 1): string
{
return str_repeat(infy_nl($nls), $count);
}
}
if (!function_exists('infy_nl_tab')) {
function infy_nl_tab(int $lns = 1, int $tabs = 1): string
{
return infy_nls($lns).infy_tabs($tabs);
}
}
if (!function_exists('model_name_from_table_name')) {
function model_name_from_table_name(string $tableName): string
{
return Str::ucfirst(Str::camel(Str::singular($tableName)));
}
}
if (!function_exists('create_resource_route_names')) {
function create_resource_route_names($name, $isScaffold = false): array
{
$result = [
"'index' => '$name.index'",
"'store' => '$name.store'",
"'show' => '$name.show'",
"'update' => '$name.update'",
"'destroy' => '$name.destroy'",
];
if ($isScaffold) {
$result[] = "'create' => '$name.create'";
$result[] = "'edit' => '$name.edit'";
}
return $result;
}
}
<?php
use InfyOm\Generator\Commands\API\APIGeneratorCommand;
use InfyOm\Generator\Facades\FileUtils;
use InfyOm\Generator\Generators\API\APIControllerGenerator;
use InfyOm\Generator\Generators\API\APIRequestGenerator;
use InfyOm\Generator\Generators\API\APIRoutesGenerator;
use InfyOm\Generator\Generators\API\APITestGenerator;
use InfyOm\Generator\Generators\FactoryGenerator;
use InfyOm\Generator\Generators\MigrationGenerator;
use InfyOm\Generator\Generators\ModelGenerator;
use InfyOm\Generator\Generators\RepositoryGenerator;
use InfyOm\Generator\Generators\RepositoryTestGenerator;
use InfyOm\Generator\Generators\Scaffold\ControllerGenerator;
use InfyOm\Generator\Generators\Scaffold\MenuGenerator;
use InfyOm\Generator\Generators\Scaffold\RequestGenerator;
use InfyOm\Generator\Generators\Scaffold\RoutesGenerator;
use InfyOm\Generator\Generators\Scaffold\ViewGenerator;
use InfyOm\Generator\Generators\SeederGenerator;
use Mockery as m;
use function Pest\Laravel\artisan;
afterEach(function () {
m::close();
});
it('generates all files for api from console', function () {
FileUtils::fake();
$shouldHaveCalledGenerators = [
MigrationGenerator::class,
ModelGenerator::class,
APIRequestGenerator::class,
APIControllerGenerator::class,
APIRoutesGenerator::class,
SeederGenerator::class,
];
mockShouldHaveCalledGenerateMethod($shouldHaveCalledGenerators);
$shouldNotHaveCalledGenerator = [
RepositoryGenerator::class,
RequestGenerator::class,
ControllerGenerator::class,
ViewGenerator::class,
RoutesGenerator::class,
MenuGenerator::class,
RepositoryTestGenerator::class,
APITestGenerator::class,
FactoryGenerator::class,
];
mockShouldNotHaveCalledGenerateMethod($shouldNotHaveCalledGenerator);
config()->set('laravel_generator.options.seeder', true);
config()->set('laravel_generator.options.repository_pattern', false);
artisan(APIGeneratorCommand::class, ['model' => 'Post'])
->expectsQuestion('Field: (name db_type html_type options)', 'title body text')
->expectsQuestion('Enter validations: ', 'required')
->expectsQuestion('Field: (name db_type html_type options)', 'exit')
->expectsQuestion(PHP_EOL.'Do you want to migrate database? [y|N]', false)
->assertSuccessful();
});
it('generates all files for api from fields file', function () {
$fileUtils = FileUtils::fake([
'createFile' => true,
'createDirectoryIfNotExist' => true,
'deleteFile' => true,
]);
$shouldHaveCalledGenerators = [
MigrationGenerator::class,
ModelGenerator::class,
RepositoryGenerator::class,
APIRequestGenerator::class,
APIControllerGenerator::class,
APIRoutesGenerator::class,
];
mockShouldHaveCalledGenerateMethod($shouldHaveCalledGenerators);
$shouldNotHaveCalledGenerator = [
RequestGenerator::class,
ControllerGenerator::class,
ViewGenerator::class,
RoutesGenerator::class,
MenuGenerator::class,
RepositoryTestGenerator::class,
APITestGenerator::class,
FactoryGenerator::class,
SeederGenerator::class,
];
mockShouldNotHaveCalledGenerateMethod($shouldNotHaveCalledGenerator);
$modelSchemaFile = __DIR__.'/../fixtures/model_schema/Post.json';
$fileUtils->shouldReceive('getFile')
->withArgs([$modelSchemaFile])
->andReturn(file_get_contents($modelSchemaFile));
$fileUtils->shouldReceive('getFile')
->andReturn('');
artisan(APIGeneratorCommand::class, ['model' => 'Post', '--fieldsFile' => $modelSchemaFile])
->expectsQuestion(PHP_EOL.'Do you want to migrate database? [y|N]', false)
->assertSuccessful();
});
<?php
use InfyOm\Generator\Commands\APIScaffoldGeneratorCommand;
use InfyOm\Generator\Facades\FileUtils;
use InfyOm\Generator\Generators\API\APIControllerGenerator;
use InfyOm\Generator\Generators\API\APIRequestGenerator;
use InfyOm\Generator\Generators\API\APIRoutesGenerator;
use InfyOm\Generator\Generators\API\APITestGenerator;
use InfyOm\Generator\Generators\FactoryGenerator;
use InfyOm\Generator\Generators\MigrationGenerator;
use InfyOm\Generator\Generators\ModelGenerator;
use InfyOm\Generator\Generators\RepositoryGenerator;
use InfyOm\Generator\Generators\RepositoryTestGenerator;
use InfyOm\Generator\Generators\Scaffold\ControllerGenerator;
use InfyOm\Generator\Generators\Scaffold\MenuGenerator;
use InfyOm\Generator\Generators\Scaffold\RequestGenerator;
use InfyOm\Generator\Generators\Scaffold\RoutesGenerator;
use InfyOm\Generator\Generators\Scaffold\ViewGenerator;
use InfyOm\Generator\Generators\SeederGenerator;
use Mockery as m;
use function Pest\Laravel\artisan;
afterEach(function () {
m::close();
});
it('generates all files for api_scaffold from console', function () {
FileUtils::fake();
$shouldHaveCalledGenerators = [
MigrationGenerator::class,
ModelGenerator::class,
RepositoryGenerator::class,
APIRequestGenerator::class,
APIControllerGenerator::class,
APIRoutesGenerator::class,
RequestGenerator::class,
ControllerGenerator::class,
ViewGenerator::class,
RoutesGenerator::class,
MenuGenerator::class,
SeederGenerator::class,
];
mockShouldHaveCalledGenerateMethod($shouldHaveCalledGenerators);
$shouldNotHaveCalledGenerator = [
RepositoryTestGenerator::class,
APITestGenerator::class,
FactoryGenerator::class,
];
mockShouldNotHaveCalledGenerateMethod($shouldNotHaveCalledGenerator);
config()->set('laravel_generator.options.seeder', true);
artisan(APIScaffoldGeneratorCommand::class, ['model' => 'Post'])
->expectsQuestion('Field: (name db_type html_type options)', 'title body text')
->expectsQuestion('Enter validations: ', 'required')
->expectsQuestion('Field: (name db_type html_type options)', 'exit')
->expectsQuestion(PHP_EOL.'Do you want to migrate database? [y|N]', false)
->assertSuccessful();
});
it('generates all files for api_scaffold from fields file', function () {
$fileUtils = FileUtils::fake([
'createFile' => true,
'createDirectoryIfNotExist' => true,
'deleteFile' => true,
]);
$shouldHaveCalledGenerators = [
MigrationGenerator::class,
ModelGenerator::class,
RepositoryGenerator::class,
APIRequestGenerator::class,
APIControllerGenerator::class,
APIRoutesGenerator::class,
RequestGenerator::class,
ControllerGenerator::class,
ViewGenerator::class,
RoutesGenerator::class,
MenuGenerator::class,
RepositoryTestGenerator::class,
APITestGenerator::class,
FactoryGenerator::class,
];
mockShouldHaveCalledGenerateMethod($shouldHaveCalledGenerators);
$shouldNotHaveCalledGenerator = [
SeederGenerator::class,
];
mockShouldNotHaveCalledGenerateMethod($shouldNotHaveCalledGenerator);
config()->set('laravel_generator.options.tests', true);
$modelSchemaFile = __DIR__.'/../fixtures/model_schema/Post.json';
$fileUtils->shouldReceive('getFile')
->withArgs([$modelSchemaFile])
->andReturn(file_get_contents($modelSchemaFile));
$fileUtils->shouldReceive('getFile')
->andReturn('');
artisan(APIScaffoldGeneratorCommand::class, ['model' => 'Post', '--fieldsFile' => $modelSchemaFile])
->expectsQuestion(PHP_EOL.'Do you want to migrate database? [y|N]', false)
->assertSuccessful();
});
<?php
use InfyOm\Generator\Commands\Publish\PublishTablesCommand;
use function Pest\Laravel\artisan;
it('thrown exceptions with invalid type passed', function () {
artisan(PublishTablesCommand::class, ['type' => 'invalid']);
})->throws(Exception::class, 'Invalid Table Type');
<?php
use InfyOm\Generator\Commands\RollbackGeneratorCommand;
use InfyOm\Generator\Generators\API\APIControllerGenerator;
use InfyOm\Generator\Generators\API\APIRequestGenerator;
use InfyOm\Generator\Generators\API\APIRoutesGenerator;
use InfyOm\Generator\Generators\API\APITestGenerator;
use InfyOm\Generator\Generators\FactoryGenerator;
use InfyOm\Generator\Generators\MigrationGenerator;
use InfyOm\Generator\Generators\ModelGenerator;
use InfyOm\Generator\Generators\RepositoryGenerator;
use InfyOm\Generator\Generators\RepositoryTestGenerator;
use InfyOm\Generator\Generators\Scaffold\ControllerGenerator;
use InfyOm\Generator\Generators\Scaffold\MenuGenerator;
use InfyOm\Generator\Generators\Scaffold\RequestGenerator;
use InfyOm\Generator\Generators\Scaffold\RoutesGenerator;
use InfyOm\Generator\Generators\Scaffold\ViewGenerator;
use InfyOm\Generator\Generators\SeederGenerator;
use Mockery as m;
use function Pest\Laravel\artisan;
afterEach(function () {
m::close();
});
it('fails with invalid rollback type', function () {
artisan(RollbackGeneratorCommand::class, ['model' => 'User', 'type' => 'random'])
->assertExitCode(1);
});
function mockShouldHaveCalledRollbackGenerator(array $shouldHaveCalledGenerators): array
{
$mockedObjects = [];
foreach ($shouldHaveCalledGenerators as $generator) {
$mock = m::mock($generator);
$mock->shouldReceive('rollback')
->once()
->andReturn(true);
app()->singleton($generator, function () use ($mock) {
return $mock;
});
$mockedObjects[] = $mock;
}
return $mockedObjects;
}
function mockShouldNotHaveCalledRollbackGenerators(array $shouldNotHaveCalledGenerator): array
{
$mockedObjects = [];
foreach ($shouldNotHaveCalledGenerator as $generator) {
$mock = m::mock($generator);
$mock->shouldNotReceive('rollback');
app()->singleton($generator, function () use ($mock) {
return $mock;
});
$mockedObjects[] = $mock;
}
return $mockedObjects;
}
it('validates that all files are rolled back for api_scaffold', function () {
$shouldHaveCalledGenerators = [
MigrationGenerator::class,
ModelGenerator::class,
RepositoryGenerator::class,
APIRequestGenerator::class,
APIControllerGenerator::class,
APIRoutesGenerator::class,
RequestGenerator::class,
ControllerGenerator::class,
ViewGenerator::class,
RoutesGenerator::class,
MenuGenerator::class,
FactoryGenerator::class,
RepositoryTestGenerator::class,
APITestGenerator::class,
];
mockShouldHaveCalledRollbackGenerator($shouldHaveCalledGenerators);
$shouldNotHaveCalledGenerator = [
SeederGenerator::class,
];
mockShouldNotHaveCalledRollbackGenerators($shouldNotHaveCalledGenerator);
config()->set('laravel_generator.options.tests', true);
artisan(RollbackGeneratorCommand::class, ['model' => 'User', 'type' => 'api_scaffold']);
});
it('validates that all files are rolled back for api', function () {
$shouldHaveCalledGenerators = [
MigrationGenerator::class,
ModelGenerator::class,
APIRequestGenerator::class,
APIControllerGenerator::class,
APIRoutesGenerator::class,
FactoryGenerator::class,
SeederGenerator::class,
];
mockShouldHaveCalledRollbackGenerator($shouldHaveCalledGenerators);
$shouldNotHaveCalledGenerator = [
RepositoryGenerator::class,
RequestGenerator::class,
ControllerGenerator::class,
ViewGenerator::class,
RoutesGenerator::class,
MenuGenerator::class,
];
mockShouldNotHaveCalledRollbackGenerators($shouldNotHaveCalledGenerator);
config()->set('laravel_generator.options.repository_pattern', false);
config()->set('laravel_generator.options.factory', true);
config()->set('laravel_generator.options.seeder', true);
artisan(RollbackGeneratorCommand::class, ['model' => 'User', 'type' => 'api']);
});
it('validates that all files are rolled back for scaffold', function () {
$shouldHaveCalledGenerators = [
MigrationGenerator::class,
ModelGenerator::class,
RepositoryGenerator::class,
RequestGenerator::class,
ControllerGenerator::class,
ViewGenerator::class,
RoutesGenerator::class,
MenuGenerator::class,
];
mockShouldHaveCalledRollbackGenerator($shouldHaveCalledGenerators);
$shouldNotHaveCalledGenerator = [
APIRequestGenerator::class,
APIControllerGenerator::class,
APIRoutesGenerator::class,
];
mockShouldNotHaveCalledRollbackGenerators($shouldNotHaveCalledGenerator);
config()->set('laravel_generator.options.tests', true);
artisan(RollbackGeneratorCommand::class, ['model' => 'User', 'type' => 'scaffold']);
});
<?php
use InfyOm\Generator\Commands\Scaffold\ScaffoldGeneratorCommand;
use InfyOm\Generator\Facades\FileUtils;
use InfyOm\Generator\Generators\API\APIControllerGenerator;
use InfyOm\Generator\Generators\API\APIRequestGenerator;
use InfyOm\Generator\Generators\API\APIRoutesGenerator;
use InfyOm\Generator\Generators\API\APITestGenerator;
use InfyOm\Generator\Generators\FactoryGenerator;
use InfyOm\Generator\Generators\MigrationGenerator;
use InfyOm\Generator\Generators\ModelGenerator;
use InfyOm\Generator\Generators\RepositoryGenerator;
use InfyOm\Generator\Generators\RepositoryTestGenerator;
use InfyOm\Generator\Generators\Scaffold\ControllerGenerator;
use InfyOm\Generator\Generators\Scaffold\MenuGenerator;
use InfyOm\Generator\Generators\Scaffold\RequestGenerator;
use InfyOm\Generator\Generators\Scaffold\RoutesGenerator;
use InfyOm\Generator\Generators\Scaffold\ViewGenerator;
use InfyOm\Generator\Generators\SeederGenerator;
use Mockery as m;
use function Pest\Laravel\artisan;
afterEach(function () {
m::close();
});
it('generates all files for scaffold from console', function () {
FileUtils::fake();
$shouldHaveCalledGenerators = [
MigrationGenerator::class,
ModelGenerator::class,
RepositoryGenerator::class,
RequestGenerator::class,
ControllerGenerator::class,
ViewGenerator::class,
RoutesGenerator::class,
MenuGenerator::class,
];
mockShouldHaveCalledGenerateMethod($shouldHaveCalledGenerators);
$shouldNotHaveCalledGenerator = [
SeederGenerator::class,
APIRequestGenerator::class,
APIControllerGenerator::class,
APIRoutesGenerator::class,
RepositoryTestGenerator::class,
APITestGenerator::class,
FactoryGenerator::class,
];
mockShouldNotHaveCalledGenerateMethod($shouldNotHaveCalledGenerator);
artisan(ScaffoldGeneratorCommand::class, ['model' => 'Post'])
->expectsQuestion('Field: (name db_type html_type options)', 'title body text')
->expectsQuestion('Enter validations: ', 'required')
->expectsQuestion('Field: (name db_type html_type options)', 'exit')
->expectsQuestion(PHP_EOL.'Do you want to migrate database? [y|N]', false)
->assertSuccessful();
});
it('generates all files for scaffold from fields file', function () {
$fileUtils = FileUtils::fake([
'createFile' => true,
'createDirectoryIfNotExist' => true,
'deleteFile' => true,
]);
$shouldHaveCalledGenerators = [
MigrationGenerator::class,
ModelGenerator::class,
RepositoryGenerator::class,
RequestGenerator::class,
ControllerGenerator::class,
ViewGenerator::class,
RoutesGenerator::class,
MenuGenerator::class,
FactoryGenerator::class,
];
mockShouldHaveCalledGenerateMethod($shouldHaveCalledGenerators);
$shouldNotHaveCalledGenerator = [
RepositoryTestGenerator::class,
APITestGenerator::class,
APIRequestGenerator::class,
APIControllerGenerator::class,
APIRoutesGenerator::class,
SeederGenerator::class,
];
mockShouldNotHaveCalledGenerateMethod($shouldNotHaveCalledGenerator);
config()->set('laravel_generator.options.factory', true);
$modelSchemaFile = __DIR__.'/../fixtures/model_schema/Post.json';
$fileUtils->shouldReceive('getFile')
->withArgs([$modelSchemaFile])
->andReturn(file_get_contents($modelSchemaFile));
$fileUtils->shouldReceive('getFile')
->andReturn('');
artisan(ScaffoldGeneratorCommand::class, ['model' => 'Post', '--fieldsFile' => $modelSchemaFile])
->expectsQuestion(PHP_EOL.'Do you want to migrate database? [y|N]', false)
->assertSuccessful();
});
<?php
use InfyOm\Generator\Facades\FileUtils;
use InfyOm\Generator\Generators\API\APIControllerGenerator;
use Mockery as m;
beforeEach(function () {
FileUtils::fake();
});
afterEach(function () {
m::close();
});
test('uses repository controller template', function () {
fakeGeneratorConfig();
/** @var APIControllerGenerator $generator */
$generator = app(APIControllerGenerator::class);
$viewName = $generator->getViewName();
expect($viewName)->toBe('repository.controller');
});
test('uses model controller template', function () {
config()->set('laravel_generator.options.repository_pattern', false);
fakeGeneratorConfig();
/** @var APIControllerGenerator $generator */
$generator = app(APIControllerGenerator::class);
$viewName = $generator->getViewName();
expect($viewName)->toBe('model.controller');
});
test('used resource repository controller template', function () {
config()->set('laravel_generator.options.resources', true);
fakeGeneratorConfig();
/** @var APIControllerGenerator $generator */
$generator = app(APIControllerGenerator::class);
$viewName = $generator->getViewName();
expect($viewName)->toBe('repository.controller_resource');
});
<?php
namespace Tests\Helpers;
it('verifies model name from table names', function () {
$tableNames = ['posts', 'person_addresses', 'personEmails'];
$modelNames = ['Post', 'PersonAddress', 'PersonEmail'];
$i = 0;
foreach ($tableNames as $tableName) {
$result = model_name_from_table_name($tableName);
expect($result)->toBe($modelNames[$i]);
$i++;
}
});
<?php
/*
|--------------------------------------------------------------------------
| Test Case
|--------------------------------------------------------------------------
|
| The closure you provide to your test functions is always bound to a specific PHPUnit test
| case class. By default, that class is "PHPUnit\Framework\TestCase". Of course, you may
| need to change it using the "uses()" function to bind a different classes or traits.
|
*/
uses(Tests\TestCase::class)->in(__DIR__);
/*
|--------------------------------------------------------------------------
| Expectations
|--------------------------------------------------------------------------
|
| When you're writing tests, you often need to check that values meet certain conditions. The
| "expect()" function gives you access to a set of "expectations" methods that you can use
| to assert different things. Of course, you may extend the Expectation API at any time.
|
*/
expect()->extend('toBeOne', function () {
return $this->toBe(1);
});
/*
|--------------------------------------------------------------------------
| Functions
|--------------------------------------------------------------------------
|
| While Pest is very powerful out-of-the-box, you may have some testing code specific to your
| project that you don't want to repeat in every file. Here you can also expose helpers as
| global functions to help you to reduce the number of lines of code in your test files.
|
*/
include_once 'TestHelpers.php';
<?php
namespace Tests;
use InfyOm\Generator\InfyOmGeneratorServiceProvider;
use Orchestra\Testbench\TestCase as Orchestra;
class TestCase extends Orchestra
{
protected function getPackageProviders($app)
{
return [
InfyOmGeneratorServiceProvider::class,
];
}
}
<?php
use Illuminate\Console\Command;
use InfyOm\Generator\Common\GeneratorConfig;
use Mockery as m;
function mockShouldHaveCalledGenerateMethod(array $shouldHaveCalledGenerators): array
{
$mockedObjects = [];
foreach ($shouldHaveCalledGenerators as $generator) {
$mock = m::mock($generator);
$mock->shouldReceive('generate')
->once()
->andReturn(true);
app()->singleton($generator, function () use ($mock) {
return $mock;
});
$mockedObjects[] = $mock;
}
return $mockedObjects;
}
function mockShouldNotHaveCalledGenerateMethod(array $shouldNotHaveCalledGenerator): array
{
$mockedObjects = [];
foreach ($shouldNotHaveCalledGenerator as $generator) {
$mock = m::mock($generator);
$mock->shouldNotReceive('generate');
app()->singleton($generator, function () use ($mock) {
return $mock;
});
$mockedObjects[] = $mock;
}
return $mockedObjects;
}
function fakeGeneratorConfig()
{
$fakeConfig = new GeneratorConfig();
$command = fakeGeneratorCommand();
$fakeConfig->setCommand($command);
$fakeConfig->init();
app()->singleton(GeneratorConfig::class, function () use ($fakeConfig) {
return $fakeConfig;
});
return $fakeConfig;
}
function fakeGeneratorCommand($options = [])
{
$mock = m::mock(Command::class);
$mock->shouldReceive('argument')->withArgs(['model'])->andReturn('FakeModel');
if (empty($options)) {
$mock->shouldReceive('option')->withAnyArgs()->andReturn('');
} else {
foreach ($options as $option => $value) {
$mock->shouldReceive('option')->withArgs([$option])->andReturn($value);
}
}
return $mock;
}
[
{
"name": "id",
"dbType": "id",
"htmlType": null,
"validations": null,
"searchable": false,
"fillable": false,
"primary": true,
"inForm": false,
"inIndex": false,
"inView": false
},
{
"name": "user_id",
"dbType": "unsignedBigInteger:foreign,users,id",
"htmlType": "text",
"relation": "mt1,User,user_id,id",
"validations": "required",
"searchable": false,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true,
"inView": true
},
{
"name": "title",
"dbType": "string",
"htmlType": "text",
"validations": "required",
"searchable": true,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true,
"inView": true
},
{
"name": "body",
"dbType": "text",
"htmlType": "textarea",
"validations": "",
"searchable": true,
"fillable": true,
"primary": false,
"inForm": true,
"inIndex": true,
"inView": true
},
{
"name": "created_at",
"dbType": "timestamp",
"htmlType": null,
"validations": null,
"searchable": false,
"fillable": false,
"primary": false,
"inForm": false,
"inIndex": false,
"inView": true
},
{
"name": "updated_at",
"dbType": "timestamp",
"htmlType": null,
"validations": null,
"searchable": false,
"fillable": false,
"primary": false,
"inForm": false,
"inIndex": false,
"inView": true
}
]
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->apiController }};
use {{ $config->namespaces->apiRequest }}\Create{{ $config->modelNames->name }}APIRequest;
use {{ $config->namespaces->apiRequest }}\Update{{ $config->modelNames->name }}APIRequest;
use {{ $config->namespaces->model }}\{{ $config->modelNames->name }};
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use {{ $config->namespaces->app }}\Http\Controllers\AppBaseController;
{!! $docController !!}
class {{ $config->modelNames->name }}APIController extends AppBaseController
{
{!! $docIndex !!}
public function index(Request $request): JsonResponse
{
$query = {{ $config->modelNames->name }}::query();
if ($request->get('skip')) {
$query->skip($request->get('skip'));
}
if ($request->get('limit')) {
$query->limit($request->get('limit'));
}
${{ $config->modelNames->camelPlural }} = $query->get();
@if($config->options->localized)
return $this->sendResponse(
${{ $config->modelNames->camelPlural }}->toArray(),
__('messages.retrieved', ['model' => __('models/{{ $config->modelNames->camelPlural }}.plural')])
);
@else
return $this->sendResponse(${{ $config->modelNames->camelPlural }}->toArray(), '{{ $config->modelNames->humanPlural }} retrieved successfully');
@endif
}
{!! $docStore !!}
public function store(Create{{ $config->modelNames->name }}APIRequest $request): JsonResponse
{
$input = $request->all();
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::create($input);
@if($config->options->localized)
return $this->sendResponse(
${{ $config->modelNames->camel }}->toArray(),
__('messages.saved', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendResponse(${{ $config->modelNames->camel }}->toArray(), '{{ $config->modelNames->human }} saved successfully');
@endif
}
{!! $docShow !!}
public function show($id): JsonResponse
{
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::find($id);
if (empty(${{ $config->modelNames->camel }})) {
@if($config->options->localized)
return $this->sendError(
__('messages.not_found', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendError('{{ $config->modelNames->human }} not found');
@endif
}
@if($config->options->localized)
return $this->sendResponse(
${{ $config->modelNames->camel }}->toArray(),
__('messages.retrieved', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendResponse(${{ $config->modelNames->camel }}->toArray(), '{{ $config->modelNames->human }} retrieved successfully');
@endif
}
{!! $docUpdate !!}
public function update($id, Update{{ $config->modelNames->name }}APIRequest $request): JsonResponse
{
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::find($id);
if (empty(${{ $config->modelNames->camel }})) {
@if($config->options->localized)
return $this->sendError(
__('messages.not_found', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendError('{{ $config->modelNames->human }} not found');
@endif
}
${{ $config->modelNames->camel }}->fill($request->all());
${{ $config->modelNames->camel }}->save();
@if($config->options->localized)
return $this->sendResponse(
${{ $config->modelNames->camel }}->toArray(),
__('messages.updated', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendResponse(${{ $config->modelNames->camel }}->toArray(), '{{ $config->modelNames->name }} updated successfully');
@endif
}
{!! $docDestroy !!}
public function destroy($id): JsonResponse
{
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::find($id);
if (empty(${{ $config->modelNames->camel }})) {
@if($config->options->localized)
return $this->sendError(
__('messages.not_found', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendError('{{ $config->modelNames->human }} not found');
@endif
}
${{ $config->modelNames->camel }}->delete();
@if($config->options->localized)
return $this->sendResponse(
$id,
__('messages.deleted', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendSuccess('{{ $config->modelNames->human }} deleted successfully');
@endif
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->apiController }};
use {{ $config->namespaces->apiRequest }}\Create{{ $config->modelNames->name }}APIRequest;
use {{ $config->namespaces->apiRequest }}\Update{{ $config->modelNames->name }}APIRequest;
use {{ $config->namespaces->model }}\{{ $config->modelNames->name }};
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use {{ $config->namespaces->app }}\Http\Controllers\AppBaseController;
use {{ $config->namespaces->apiResource }}\{{ $config->modelNames->name }}Resource;
{!! $docController !!}
class {{ $config->modelNames->name }}APIController extends AppBaseController
{
{!! $docIndex !!}
public function index(Request $request): JsonResponse
{
$query = {{ $config->modelNames->name }}::query();
if ($request->get('skip')) {
$query->skip($request->get('skip'));
}
if ($request->get('limit')) {
$query->limit($request->get('limit'));
}
${{ $config->modelNames->camelPlural }} = $query->get();
@if($config->options->localized)
return $this->sendResponse(
{{ $config->modelNames->name }}Resource::collection(${{ $config->modelNames->camelPlural }}),
__('messages.retrieved', ['model' => __('models/{{ $config->modelNames->camelPlural }}.plural')])
);
@else
return $this->sendResponse({{ $config->modelNames->name }}Resource::collection(${{ $config->modelNames->camelPlural }}), '{{ $config->modelNames->humanPlural }} retrieved successfully');
@endif
}
{!! $docStore !!}
public function store(Create{{ $config->modelNames->name }}APIRequest $request): JsonResponse
{
$input = $request->all();
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::create($input);
@if($config->options->localized)
return $this->sendResponse(
new {{ $config->modelNames->name }}Resource(${{ $config->modelNames->camel }}),
__('messages.saved', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendResponse(new {{ $config->modelNames->name }}Resource(${{ $config->modelNames->camel }}), '{{ $config->modelNames->human }} saved successfully');
@endif
}
{!! $docShow !!}
public function show($id): JsonResponse
{
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::find($id);
if (empty(${{ $config->modelNames->camel }})) {
@if($config->options->localized)
return $this->sendError(
__('messages.not_found', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendError('{{ $config->modelNames->human }} not found');
@endif
}
@if($config->options->localized)
return $this->sendResponse(
new {{ $config->modelNames->name }}Resource(${{ $config->modelNames->camel }}),
__('messages.retrieved', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendResponse(new {{ $config->modelNames->name }}Resource(${{ $config->modelNames->camel }}), '{{ $config->modelNames->human }} retrieved successfully');
@endif
}
{!! $docUpdate !!}
public function update($id, Update{{ $config->modelNames->name }}APIRequest $request): JsonResponse
{
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::find($id);
if (empty(${{ $config->modelNames->camel }})) {
@if($config->options->localized)
return $this->sendError(
__('messages.not_found', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendError('{{ $config->modelNames->human }} not found');
@endif
}
${{ $config->modelNames->camel }}->fill($request->all());
${{ $config->modelNames->camel }}->save();
@if($config->options->localized)
return $this->sendResponse(
new {{ $config->modelNames->name }}Resource(${{ $config->modelNames->camel }}),
__('messages.updated', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendResponse(new {{ $config->modelNames->name }}Resource(${{ $config->modelNames->camel }}), '{{ $config->modelNames->name }} updated successfully');
@endif
}
{!! $docDestroy !!}
public function destroy($id): JsonResponse
{
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::find($id);
if (empty(${{ $config->modelNames->camel }})) {
@if($config->options->localized)
return $this->sendError(
__('messages.not_found', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendError('{{ $config->modelNames->human }} not found');
@endif
}
${{ $config->modelNames->camel }}->delete();
@if($config->options->localized)
return $this->sendResponse(
$id,
__('messages.deleted', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendSuccess('{{ $config->modelNames->human }} deleted successfully');
@endif
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->apiController }};
use {{ $config->namespaces->apiRequest }}\Create{{ $config->modelNames->name }}APIRequest;
use {{ $config->namespaces->apiRequest }}\Update{{ $config->modelNames->name }}APIRequest;
use {{ $config->namespaces->model }}\{{ $config->modelNames->name }};
use {{ $config->namespaces->repository }}\{{ $config->modelNames->name }}Repository;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use {{ $config->namespaces->app }}\Http\Controllers\AppBaseController;
{!! $docController !!}
class {{ $config->modelNames->name }}APIController extends AppBaseController
{
private {{ $config->modelNames->name }}Repository ${{ $config->modelNames->camel }}Repository;
public function __construct({{ $config->modelNames->name }}Repository ${{ $config->modelNames->camel }}Repo)
{
$this->{{ $config->modelNames->camel }}Repository = ${{ $config->modelNames->camel }}Repo;
}
{!! $docIndex !!}
public function index(Request $request): JsonResponse
{
${{ $config->modelNames->camelPlural }} = $this->{{ $config->modelNames->camel }}Repository->all(
$request->except(['skip', 'limit']),
$request->get('skip'),
$request->get('limit')
);
@if($config->options->localized)
return $this->sendResponse(
${{ $config->modelNames->camelPlural }}->toArray(),
__('messages.retrieved', ['model' => __('models/{{ $config->modelNames->camelPlural }}.plural')])
);
@else
return $this->sendResponse(${{ $config->modelNames->camelPlural }}->toArray(), '{{ $config->modelNames->humanPlural }} retrieved successfully');
@endif
}
{!! $docStore !!}
public function store(Create{{ $config->modelNames->name }}APIRequest $request): JsonResponse
{
$input = $request->all();
${{ $config->modelNames->camel }} = $this->{{ $config->modelNames->camel }}Repository->create($input);
@if($config->options->localized)
return $this->sendResponse(
${{ $config->modelNames->camel }}->toArray(),
__('messages.saved', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendResponse(${{ $config->modelNames->camel }}->toArray(), '{{ $config->modelNames->human }} saved successfully');
@endif
}
{!! $docShow !!}
public function show($id): JsonResponse
{
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = $this->{{ $config->modelNames->camel }}Repository->find($id);
if (empty(${{ $config->modelNames->camel }})) {
@if($config->options->localized)
return $this->sendError(
__('messages.not_found', ['model' => __('models/$MODEL_NAME_PLURAL_CAMEL$.singular')])
);
@else
return $this->sendError('{{ $config->modelNames->human }} not found');
@endif
}
@if($config->options->localized)
return $this->sendResponse(
${{ $config->modelNames->camel }}->toArray(),
__('messages.retrieved', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendResponse(${{ $config->modelNames->camel }}->toArray(), '{{ $config->modelNames->human }} retrieved successfully');
@endif
}
{!! $docUpdate !!}
public function update($id, Update{{ $config->modelNames->name }}APIRequest $request): JsonResponse
{
$input = $request->all();
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = $this->{{ $config->modelNames->camel }}Repository->find($id);
if (empty(${{ $config->modelNames->camel }})) {
@if($config->options->localized)
return $this->sendError(
__('messages.not_found', ['model' => __('models/$MODEL_NAME_PLURAL_CAMEL$.singular')])
);
@else
return $this->sendError('{{ $config->modelNames->human }} not found');
@endif
}
${{ $config->modelNames->camel }} = $this->{{ $config->modelNames->camel }}Repository->update($input, $id);
@if($config->options->localized)
return $this->sendResponse(
${{ $config->modelNames->camel }}->toArray(),
__('messages.updated', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendResponse(${{ $config->modelNames->camel }}->toArray(), '{{ $config->modelNames->name }} updated successfully');
@endif
}
{!! $docDestroy !!}
public function destroy($id): JsonResponse
{
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = $this->{{ $config->modelNames->camel }}Repository->find($id);
if (empty(${{ $config->modelNames->camel }})) {
@if($config->options->localized)
return $this->sendError(
__('messages.not_found', ['model' => __('models/$MODEL_NAME_PLURAL_CAMEL$.singular')])
);
@else
return $this->sendError('{{ $config->modelNames->human }} not found');
@endif
}
${{ $config->modelNames->camel }}->delete();
@if($config->options->localized)
return $this->sendError(
$id,
__('messages.deleted', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendSuccess('{{ $config->modelNames->human }} deleted successfully');
@endif
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->apiController }};
use {{ $config->namespaces->apiRequest }}\Create{{ $config->modelNames->name }}APIRequest;
use {{ $config->namespaces->apiRequest }}\Update{{ $config->modelNames->name }}APIRequest;
use {{ $config->namespaces->model }}\{{ $config->modelNames->name }};
use {{ $config->namespaces->repository }}\{{ $config->modelNames->name }}Repository;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use {{ $config->namespaces->app }}\Http\Controllers\AppBaseController;
use {{ $config->namespaces->apiResource }}\{{ $config->modelNames->name }}Resource;
{!! $docController !!}
class {{ $config->modelNames->name }}APIController extends AppBaseController
{
/** @var {{ $config->modelNames->name }}Repository */
private ${{ $config->modelNames->camel }}Repository;
public function __construct({{ $config->modelNames->name }}Repository ${{ $config->modelNames->camel }}Repo)
{
$this->{{ $config->modelNames->camel }}Repository = ${{ $config->modelNames->camel }}Repo;
}
{!! $docIndex !!}
public function index(Request $request): JsonResponse
{
${{ $config->modelNames->camelPlural }} = $this->{{ $config->modelNames->camel }}Repository->all(
$request->except(['skip', 'limit']),
$request->get('skip'),
$request->get('limit')
);
@if($config->options->localized)
return $this->sendResponse(
{{ $config->modelNames->name }}Resource::collection(${{ $config->modelNames->camelPlural }}),
__('messages.retrieved', ['model' => __('models/{{ $config->modelNames->camelPlural }}.plural')])
);
@else
return $this->sendResponse({{ $config->modelNames->name }}Resource::collection(${{ $config->modelNames->camelPlural }}), '{{ $config->modelNames->humanPlural }} retrieved successfully');
@endif
}
{!! $docStore !!}
public function store(Create{{ $config->modelNames->name }}APIRequest $request): JsonResponse
{
$input = $request->all();
${{ $config->modelNames->camel }} = $this->{{ $config->modelNames->camel }}Repository->create($input);
@if($config->options->localized)
return $this->sendResponse(
new {{ $config->modelNames->name }}Resource(${{ $config->modelNames->camel }}),
__('messages.saved', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendResponse(new {{ $config->modelNames->name }}Resource(${{ $config->modelNames->camel }}), '{{ $config->modelNames->human }} saved successfully');
@endif
}
{!! $docShow !!}
public function show($id): JsonResponse
{
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = $this->{{ $config->modelNames->camel }}Repository->find($id);
if (empty(${{ $config->modelNames->camel }})) {
@if($config->options->localized)
return $this->sendError(
__('messages.not_found', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendError('{{ $config->modelNames->human }} not found');
@endif
}
@if($config->options->localized)
return $this->sendResponse(
new {{ $config->modelNames->name }}Resource(${{ $config->modelNames->camel }}),
__('messages.retrieved', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendResponse(new {{ $config->modelNames->name }}Resource(${{ $config->modelNames->camel }}), '{{ $config->modelNames->human }} retrieved successfully');
@endif
}
{!! $docUpdate !!}
public function update($id, Update{{ $config->modelNames->name }}APIRequest $request): JsonResponse
{
$input = $request->all();
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = $this->{{ $config->modelNames->camel }}Repository->find($id);
if (empty(${{ $config->modelNames->camel }})) {
@if($config->options->localized)
return $this->sendError(
__('messages.not_found', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendError('{{ $config->modelNames->human }} not found');
@endif
}
${{ $config->modelNames->camel }} = $this->{{ $config->modelNames->camel }}Repository->update($input, $id);
@if($config->options->localized)
return $this->sendResponse(
new {{ $config->modelNames->name }}Resource(${{ $config->modelNames->camel }}),
__('messages.updated', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendResponse(new {{ $config->modelNames->name }}Resource(${{ $config->modelNames->camel }}), '{{ $config->modelNames->name }} updated successfully');
@endif
}
{!! $docDestroy !!}
public function destroy($id): JsonResponse
{
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = $this->{{ $config->modelNames->camel }}Repository->find($id);
if (empty(${{ $config->modelNames->camel }})) {
@if($config->options->localized)
return $this->sendError(
__('messages.not_found', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendError('{{ $config->modelNames->human }} not found');
@endif
}
${{ $config->modelNames->camel }}->delete();
@if($config->options->localized)
return $this->sendResponse(
$id,
__('messages.deleted', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')])
);
@else
return $this->sendSuccess('{{ $config->modelNames->human }} deleted successfully');
@endif
}
}
/**
* Class {{ $config->modelNames->name }}APIController
*/
\ No newline at end of file
/**
* Remove the specified {{ $config->modelNames->name }} from storage.
* DELETE /{{ $config->modelNames->dashedPlural }}/{id}
*
* @throws \Exception
*/
\ No newline at end of file
/**
* Display a listing of the {{ $config->modelNames->plural }}.
* GET|HEAD /{{ $config->modelNames->dashedPlural }}
*/
\ No newline at end of file
/**
* Display the specified {{ $config->modelNames->name }}.
* GET|HEAD /{{ $config->modelNames->dashedPlural }}/{id}
*/
\ No newline at end of file
/**
* Store a newly created {{ $config->modelNames->name }} in storage.
* POST /{{ $config->modelNames->dashedPlural }}
*/
\ No newline at end of file
/**
* Update the specified {{ $config->modelNames->name }} in storage.
* PUT/PATCH /{{ $config->modelNames->dashedPlural }}/{id}
*/
\ No newline at end of file
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->apiRequest }};
use {{ $config->namespaces->model }}\{{ $config->modelNames->name }};
use InfyOm\Generator\Request\APIRequest;
class Create{{ $config->modelNames->name }}APIRequest extends APIRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return {{ $config->modelNames->name }}::$rules;
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->apiRequest }};
use {{ $config->namespaces->model }}\{{ $config->modelNames->name }};
use InfyOm\Generator\Request\APIRequest;
class Update{{ $config->modelNames->name }}APIRequest extends APIRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$rules = {{ $config->modelNames->name }}::$rules;
{!! $uniqueRules !!}
return $rules;
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->apiResource }};
use Illuminate\Http\Resources\Json\JsonResource;
class {{ $config->modelNames->name }}Resource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
{!! $fields !!}
];
}
}
Route::resource('{{ $config->prefixes->getRoutePrefixWith('/') }}{{ $config->modelNames->dashedPlural }}', {{ $config->namespaces->apiController }}\{{ $config->modelNames->name }}APIController::class){!! infy_nl_tab() !!}->except(['create', 'edit'])@if(!$config->prefixes->route);@endif
@if($config->prefixes->route){!! infy_nl_tab().'->names(['.infy_nl_tab(1,2).implode(','.infy_nl_tab(1, 2), create_resource_route_names($config->prefixes->getRoutePrefixWith('.').$config->modelNames->camelPlural)).infy_nl_tab().']);' !!}@endif
\ No newline at end of file
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->apiTests }};
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use {{ $config->namespaces->tests }}\TestCase;
use {{ $config->namespaces->tests }}\ApiTestTrait;
use {{ $config->namespaces->model }}\{{ $config->modelNames->name }};
class {{ $config->modelNames->name }}ApiTest extends TestCase
{
use ApiTestTrait, WithoutMiddleware, DatabaseTransactions;
/**
* @test
*/
public function test_create_{{ $config->modelNames->snake }}()
{
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::factory()->make()->toArray();
$this->response = $this->json(
'POST',
'/{{ $config->apiPrefix }}/{{ $config->modelNames->dashedPlural }}', ${{ $config->modelNames->camel }}
);
$this->assertApiResponse(${{ $config->modelNames->camel }});
}
/**
* @test
*/
public function test_read_{{ $config->modelNames->snake }}()
{
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::factory()->create();
$this->response = $this->json(
'GET',
'/{{ $config->apiPrefix }}/{{ $config->modelNames->dashedPlural }}/'.${{ $config->modelNames->camel }}->{{ $config->primaryName }}
);
$this->assertApiResponse(${{ $config->modelNames->camel }}->toArray());
}
/**
* @test
*/
public function test_update_{{ $config->modelNames->snake }}()
{
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::factory()->create();
$edited{{ $config->modelNames->name }} = {{ $config->modelNames->name }}::factory()->make()->toArray();
$this->response = $this->json(
'PUT',
'/{{ $config->apiPrefix }}/{{ $config->modelNames->dashedPlural }}/'.${{ $config->modelNames->camel }}->{{ $config->primaryName }},
$edited{{ $config->modelNames->name }}
);
$this->assertApiResponse($edited{{ $config->modelNames->name }});
}
/**
* @test
*/
public function test_delete_{{ $config->modelNames->snake }}()
{
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::factory()->create();
$this->response = $this->json(
'DELETE',
'/{{ $config->apiPrefix }}/{{ $config->modelNames->dashedPlural }}/'.${{ $config->modelNames->camel }}->{{ $config->primaryName }}
);
$this->assertApiSuccess();
$this->response = $this->json(
'GET',
'/{{ $config->apiPrefix }}/{{ $config->modelNames->dashedPlural }}/'.${{ $config->modelNames->camel }}->{{ $config->primaryName }}
);
$this->response->assertStatus(404);
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $namespacesTests }};
trait ApiTestTrait
{
private $response;
public function assertApiResponse(Array $actualData)
{
$this->assertApiSuccess();
$response = json_decode($this->response->getContent(), true);
$responseData = $response['data'];
$this->assertNotEmpty($responseData['id']);
$this->assertModelData($actualData, $responseData);
}
public function assertApiSuccess()
{
$this->response->assertStatus(200);
$this->response->assertJson(['success' => true]);
}
public function assertModelData(Array $actualData, Array $expectedData)
{
foreach ($actualData as $key => $value) {
if (in_array($key, {!! $timestamps !!})) {
continue;
}
$this->assertEquals($actualData[$key], $expectedData[$key]);
}
}
}
@php
echo "<?php".PHP_EOL;
@endphp
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('{{ $config->tableName }}', function (Blueprint $table) {
{!! $fields !!}
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('{{ $config->tableName }}');
}
};
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->factory }};
use {{ $config->namespaces->model }}\{{ $config->modelNames->name }};
use Illuminate\Database\Eloquent\Factories\Factory;
{!! $usedRelations !!}
class {{ $config->modelNames->name }}Factory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = {{ $config->modelNames->name }}::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
{!! $relations !!}
return [
{!! $fields !!}
];
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->model }};
use Illuminate\Database\Eloquent\Model;
@if($config->options->softDelete) {{ 'use Illuminate\Database\Eloquent\SoftDeletes;' }}@endif
@if($config->options->tests or $config->options->factory) {{ 'use Illuminate\Database\Eloquent\Factories\HasFactory;' }}@endif
@if(isset($swaggerDocs)){!! $swaggerDocs !!}@endif
class {{ $config->modelNames->name }} extends Model
{
@if($config->options->softDelete) {{ infy_tab().'use SoftDeletes;' }}@endif
@if($config->options->tests or $config->options->factory){{ infy_tab().'use HasFactory;' }}@endif
public $table = '{{ $config->tableName }}';
@if($customPrimaryKey)@tab()protected $primaryKey = '{{ $customPrimaryKey }}';@nls(2)@endif
@if($config->connection)@tab()protected $connection = '{{ $config->connection }}';@nls(2)@endif
@if(!$timestamps)@tab()public $timestamps = false;@nls(2)@endif
@if($customSoftDelete)@tab()protected $dates = ['{{ $customSoftDelete }}'];@nls(2)@endif
@if($customCreatedAt)@tab()const CREATED_AT = '{{ $customCreatedAt }}';@nls(2)@endif
@if($customUpdatedAt)@tab()const UPDATED_AT = '{{ $customUpdatedAt }}';@nls(2)@endif
public $fillable = [
{!! $fillables !!}
];
protected $casts = [
{!! $casts !!}
];
public static array $rules = [
{!! $rules !!}
];
{!! $relations !!}
}
public function {{ $functionName }}(): \Illuminate\Database\Eloquent\Relations\{{ $relationClass }}
{
return $this->{{ $relation }}(\{{ $config->namespaces->model }}\{{ $relatedModel }}::class{!! $fields !!});
}
\ No newline at end of file
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->seeder }};
use Illuminate\Database\Seeder;
class {{ $config->modelNames->plural }}TableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->repository }};
use {{ $config->namespaces->model }}\{{ $config->modelNames->name }};
use {{ $config->namespaces->app }}\Repositories\BaseRepository;
class {{ $config->modelNames->name }}Repository extends BaseRepository
{
protected $fieldSearchable = [
{!! $fieldSearchable !!}
];
public function getFieldsSearchable(): array
{
return $this->fieldSearchable;
}
public function model(): string
{
return {{ $config->modelNames->name }}::class;
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->repositoryTests }};
use {{ $config->namespaces->model }}\{{ $config->modelNames->name }};
use {{ $config->namespaces->repository }}\{{ $config->modelNames->name }}Repository;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use {{ $config->namespaces->tests }}\TestCase;
use {{ $config->namespaces->tests }}\ApiTestTrait;
class {{ $config->modelNames->name }}RepositoryTest extends TestCase
{
use ApiTestTrait, DatabaseTransactions;
protected {{ $config->modelNames->name }}Repository ${{ $config->modelNames->camel }}Repo;
public function setUp() : void
{
parent::setUp();
$this->{{ $config->modelNames->camel }}Repo = app({{ $config->modelNames->name }}Repository::class);
}
/**
* @test create
*/
public function test_create_{{ $config->modelNames->snake }}()
{
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::factory()->make()->toArray();
$created{{ $config->modelNames->name }} = $this->{{ $config->modelNames->camel }}Repo->create(${{ $config->modelNames->camel }});
$created{{ $config->modelNames->name }} = $created{{ $config->modelNames->name }}->toArray();
$this->assertArrayHasKey('id', $created{{ $config->modelNames->name }});
$this->assertNotNull($created{{ $config->modelNames->name }}['id'], 'Created {{ $config->modelNames->name }} must have id specified');
$this->assertNotNull({{ $config->modelNames->name }}::find($created{{ $config->modelNames->name }}['id']), '{{ $config->modelNames->name }} with given id must be in DB');
$this->assertModelData(${{ $config->modelNames->camel }}, $created{{ $config->modelNames->name }});
}
/**
* @test read
*/
public function test_read_{{ $config->modelNames->snake }}()
{
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::factory()->create();
$db{{ $config->modelNames->name }} = $this->{{ $config->modelNames->camel }}Repo->find(${{ $config->modelNames->camel }}->{{ $config->primaryName }});
$db{{ $config->modelNames->name }} = $db{{ $config->modelNames->name }}->toArray();
$this->assertModelData(${{ $config->modelNames->camel }}->toArray(), $db{{ $config->modelNames->name }});
}
/**
* @test update
*/
public function test_update_{{ $config->modelNames->snake }}()
{
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::factory()->create();
$fake{{ $config->modelNames->name }} = {{ $config->modelNames->name }}::factory()->make()->toArray();
$updated{{ $config->modelNames->name }} = $this->{{ $config->modelNames->camel }}Repo->update($fake{{ $config->modelNames->name }}, ${{ $config->modelNames->camel }}->{{ $config->primaryName }});
$this->assertModelData($fake{{ $config->modelNames->name }}, $updated{{ $config->modelNames->name }}->toArray());
$db{{ $config->modelNames->name }} = $this->{{ $config->modelNames->camel }}Repo->find(${{ $config->modelNames->camel }}->{{ $config->primaryName }});
$this->assertModelData($fake{{ $config->modelNames->name }}, $db{{ $config->modelNames->name }}->toArray());
}
/**
* @test delete
*/
public function test_delete_{{ $config->modelNames->snake }}()
{
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::factory()->create();
$resp = $this->{{ $config->modelNames->camel }}Repo->delete(${{ $config->modelNames->camel }}->{{ $config->primaryName }});
$this->assertTrue($resp);
$this->assertNull({{ $config->modelNames->name }}::find(${{ $config->modelNames->camel }}->{{ $config->primaryName }}), '{{ $config->modelNames->name }} should not exist in DB');
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->controller }};
@if(config('laravel_generator.tables') == 'datatables')
use {{ $config->namespaces->dataTables }}\{{ $config->modelNames->name }}DataTable;
@endif
use {{ $config->namespaces->request }}\Create{{ $config->modelNames->name }}Request;
use {{ $config->namespaces->request }}\Update{{ $config->modelNames->name }}Request;
use {{ $config->namespaces->app }}\Http\Controllers\AppBaseController;
use {{ $config->namespaces->model }}\{{ $config->modelNames->name }};
use Illuminate\Http\Request;
use Flash;
class {{ $config->modelNames->name }}Controller extends AppBaseController
{
/**
* Display a listing of the {{ $config->modelNames->name }}.
*/
{!! $indexMethod !!}
/**
* Show the form for creating a new {{ $config->modelNames->name }}.
*/
public function create()
{
return view('{{ $config->prefixes->getViewPrefixForInclude() }}{{ $config->modelNames->snakePlural }}.create');
}
/**
* Store a newly created {{ $config->modelNames->name }} in storage.
*/
public function store(Create{{ $config->modelNames->name }}Request $request)
{
$input = $request->all();
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::create($input);
@include('laravel-generator::scaffold.controller.messages.save_success')
return redirect(route('{{ $config->prefixes->getRoutePrefixWith('.') }}{{ $config->modelNames->camelPlural }}.index'));
}
/**
* Display the specified {{ $config->modelNames->name }}.
*/
public function show($id)
{
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::find($id);
@include('laravel-generator::scaffold.controller.messages.not_found')
return view('{{ $config->prefixes->getViewPrefixForInclude() }}{{ $config->modelNames->snakePlural }}.show')->with('{{ $config->modelNames->camel }}', ${{ $config->modelNames->camel }});
}
/**
* Show the form for editing the specified {{ $config->modelNames->name }}.
*/
public function edit($id)
{
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::find($id);
@include('laravel-generator::scaffold.controller.messages.not_found')
return view('{{ $config->prefixes->getViewPrefixForInclude() }}{{ $config->modelNames->snakePlural }}.edit')->with('{{ $config->modelNames->camel }}', ${{ $config->modelNames->camel }});
}
/**
* Update the specified {{ $config->modelNames->name }} in storage.
*/
public function update($id, Update{{ $config->modelNames->name }}Request $request)
{
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::find($id);
@include('laravel-generator::scaffold.controller.messages.not_found')
${{ $config->modelNames->camel }}->fill($request->all());
${{ $config->modelNames->camel }}->save();
@include('laravel-generator::scaffold.controller.messages.update_success')
return redirect(route('{{ $config->prefixes->getRoutePrefixWith('.') }}{{ $config->modelNames->camelPlural }}.index'));
}
/**
* Remove the specified {{ $config->modelNames->name }} from storage.
*
* @throws \Exception
*/
public function destroy($id)
{
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camel }} */
${{ $config->modelNames->camel }} = {{ $config->modelNames->name }}::find($id);
@include('laravel-generator::scaffold.controller.messages.not_found')
${{ $config->modelNames->camel }}->delete();
@include('laravel-generator::scaffold.controller.messages.delete_success')
return redirect(route('{{ $config->prefixes->getRoutePrefixWith('.') }}{{ $config->modelNames->camelPlural }}.index'));
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->controller }};
@if(config('laravel_generator.tables') === 'datatables')
use {{ $config->namespaces->dataTables }}\{{ $config->modelNames->name }}DataTable;
@endif
use {{ $config->namespaces->request }}\Create{{ $config->modelNames->name }}Request;
use {{ $config->namespaces->request }}\Update{{ $config->modelNames->name }}Request;
use {{ $config->namespaces->app }}\Http\Controllers\AppBaseController;
use {{ $config->namespaces->repository }}\{{ $config->modelNames->name }}Repository;
use Illuminate\Http\Request;
use Flash;
class {{ $config->modelNames->name }}Controller extends AppBaseController
{
/** @var {{ $config->modelNames->name }}Repository ${{ $config->modelNames->camel }}Repository*/
private ${{ $config->modelNames->camel }}Repository;
public function __construct({{ $config->modelNames->name }}Repository ${{ $config->modelNames->camel }}Repo)
{
$this->{{ $config->modelNames->camel }}Repository = ${{ $config->modelNames->camel }}Repo;
}
/**
* Display a listing of the {{ $config->modelNames->name }}.
*/
{!! $indexMethod !!}
/**
* Show the form for creating a new {{ $config->modelNames->name }}.
*/
public function create()
{
return view('{{ $config->prefixes->getViewPrefixForInclude() }}{{ $config->modelNames->snakePlural }}.create');
}
/**
* Store a newly created {{ $config->modelNames->name }} in storage.
*/
public function store(Create{{ $config->modelNames->name }}Request $request)
{
$input = $request->all();
${{ $config->modelNames->camel }} = $this->{{ $config->modelNames->camel }}Repository->create($input);
@include('laravel-generator::scaffold.controller.messages.save_success')
return redirect(route('{{ $config->prefixes->getRoutePrefixWith('.') }}{{ $config->modelNames->camelPlural }}.index'));
}
/**
* Display the specified {{ $config->modelNames->name }}.
*/
public function show($id)
{
${{ $config->modelNames->camel }} = $this->{{ $config->modelNames->camel }}Repository->find($id);
@include('laravel-generator::scaffold.controller.messages.not_found')
return view('{{ $config->prefixes->getViewPrefixForInclude() }}{{ $config->modelNames->snakePlural }}.show')->with('{{ $config->modelNames->camel }}', ${{ $config->modelNames->camel }});
}
/**
* Show the form for editing the specified {{ $config->modelNames->name }}.
*/
public function edit($id)
{
${{ $config->modelNames->camel }} = $this->{{ $config->modelNames->camel }}Repository->find($id);
@include('laravel-generator::scaffold.controller.messages.not_found')
return view('{{ $config->prefixes->getViewPrefixForInclude() }}{{ $config->modelNames->snakePlural }}.edit')->with('{{ $config->modelNames->camel }}', ${{ $config->modelNames->camel }});
}
/**
* Update the specified {{ $config->modelNames->name }} in storage.
*/
public function update($id, Update{{ $config->modelNames->name }}Request $request)
{
${{ $config->modelNames->camel }} = $this->{{ $config->modelNames->camel }}Repository->find($id);
@include('laravel-generator::scaffold.controller.messages.not_found')
${{ $config->modelNames->camel }} = $this->{{ $config->modelNames->camel }}Repository->update($request->all(), $id);
@include('laravel-generator::scaffold.controller.messages.update_success')
return redirect(route('{{ $config->prefixes->getRoutePrefixWith('.') }}{{ $config->modelNames->camelPlural }}.index'));
}
/**
* Remove the specified {{ $config->modelNames->name }} from storage.
*
* @throws \Exception
*/
public function destroy($id)
{
${{ $config->modelNames->camel }} = $this->{{ $config->modelNames->camel }}Repository->find($id);
@include('laravel-generator::scaffold.controller.messages.not_found')
$this->{{ $config->modelNames->camel }}Repository->delete($id);
@include('laravel-generator::scaffold.controller.messages.delete_success')
return redirect(route('{{ $config->prefixes->getRoutePrefixWith('.') }}{{ $config->modelNames->camelPlural }}.index'));
}
}
public function index(Request $request)
{
/** @var {{ $config->modelNames->name }} ${{ $config->modelNames->camelPlural }} */
${{ $config->modelNames->camelPlural }} = {{ $config->modelNames->name }}::{!! $renderType !!};
return view('{{ $config->prefixes->getViewPrefixForInclude() }}{{ $config->modelNames->snakePlural }}.index')
->with('{{ $config->modelNames->camelPlural }}', ${{ $config->modelNames->camelPlural }});
}
public function index({{ $config->modelNames->name }}DataTable ${{ $config->modelNames->camel }}DataTable)
{
return ${{ $config->modelNames->camel }}DataTable->render('{{ $config->modelNames->snakePlural }}.index');
}
public function index(Request $request)
{
return view('{{ $config->modelNames->snakePlural }}.index');
}
\ No newline at end of file
public function index(Request $request)
{
${{ $config->modelNames->camelPlural }} = $this->{{ $config->modelNames->camel }}Repository->{!! $renderType !!};
return view('{{ $config->prefixes->getViewPrefixForInclude() }}{{ $config->modelNames->snakePlural }}.index')
->with('{{ $config->modelNames->camelPlural }}', ${{ $config->modelNames->camelPlural }});
}
\ No newline at end of file
@if($config->options->localized)
Flash::success(__('messages.deleted', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')]));
@else
Flash::success('{{ $config->modelNames->human }} deleted successfully.');
@endif
\ No newline at end of file
if (empty(${{ $config->modelNames->camel }})) {
@if($config->options->localized)
Flash::error(__('models/{{ $config->modelNames->camelPlural }}.singular').' '.__('messages.not_found'));
@else
Flash::error('{{ $config->modelNames->human }} not found');
@endif
return redirect(route('{{ $config->prefixes->getRoutePrefixWith('.') }}{{ $config->modelNames->camelPlural }}.index'));
}
@if($config->options->localized)
Flash::success(__('messages.saved', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')]));
@else
Flash::success('{{ $config->modelNames->human }} saved successfully.');
@endif
@if($config->options->localized)
Flash::success(__('messages.updated', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')]));
@else
Flash::success('{{ $config->modelNames->human }} updated successfully.');
@endif
\ No newline at end of file
if (empty(${{ $config->modelNames->camel }})) {
@if($config->options->localized)
Flash::error(__('models/{{ $config->modelNames->camelPlural }}.singular').' '.__('messages.not_found'));
@else
Flash::error('{{ $config->modelNames->human }} not found');
@endif
return redirect(route('{{ $config->prefixes->getRoutePrefixWith('.') }}{{ $config->modelNames->camelPlural }}.index'));
}
<!-- DataTable Bootstrap -->
<link href="https://cdn.datatables.net/1.10.25/css/dataTables.bootstrap4.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.datatables.net/buttons/1.6.2/css/buttons.bootstrap4.min.css">
\ No newline at end of file
<!-- Datatables -->
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/dataTables.bootstrap4.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/buttons.bootstrap4.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/buttons.colVis.min.js"></script>
<script src="{{ asset('vendor/datatables/buttons.server-side.js') }}"></script>
\ No newline at end of file
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->request }};
use {{ $config->namespaces->model }}\{{ $config->modelNames->name }};
use Illuminate\Foundation\Http\FormRequest;
class Create{{ $config->modelNames->name }}Request extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return {{ $config->modelNames->name }}::$rules;
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->request }};
use {{ $config->namespaces->model }}\{{ $config->modelNames->name }};
use Illuminate\Foundation\Http\FormRequest;
class Update{{ $config->modelNames->name }}Request extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$rules = {{ $config->modelNames->name }}::$rules;
{!! $uniqueRules !!}
return $rules;
}
}
Route::resource('{{ $config->prefixes->getRoutePrefixWith('/') }}{{ $config->modelNames->dashedPlural }}', {{ $config->namespaces->controller }}\{{ $config->modelNames->name }}Controller::class)@if(!$config->prefixes->route);@endif
@if($config->prefixes->route){!! infy_nl_tab().'->names(['.infy_nl_tab(1, 2).implode(','.infy_nl_tab(1, 2), create_resource_route_names($config->prefixes->getRoutePrefixWith('.').$config->modelNames->dashedPlural, true)).infy_nl_tab().']);' !!}@endif
\ No newline at end of file
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->dataTables }};
use {{ $config->namespaces->model }}\{{ $config->modelNames->name }};
@if($config->options->localized)
use Yajra\DataTables\Html\Column;
@endif
use Yajra\DataTables\Services\DataTable;
use Yajra\DataTables\EloquentDataTable;
class {{ $config->modelNames->name }}DataTable extends DataTable
{
/**
* Build DataTable class.
*
* @param mixed $query Results from query() method.
* @return \Yajra\DataTables\DataTableAbstract
*/
public function dataTable($query)
{
$dataTable = new EloquentDataTable($query);
return $dataTable->addColumn('action', '{{ $config->modelNames->snakePlural }}.datatables_actions');
}
/**
* Get query source of dataTable.
*
* @param \App\Models\{{ $config->modelNames->name }} $model
* @return \Illuminate\Database\Eloquent\Builder
*/
public function query({{ $config->modelNames->name }} $model)
{
return $model->newQuery();
}
/**
* Optional method if you want to use html builder.
*
* @return \Yajra\DataTables\Html\Builder
*/
public function html()
{
return $this->builder()
->columns($this->getColumns())
->minifiedAjax()
->addAction(['width' => '120px', 'printable' => false])
->parameters([
'dom' => 'Bfrtip',
'stateSave' => true,
'order' => [[0, 'desc']],
'buttons' => [
// Enable Buttons as per your need
// ['extend' => 'create', 'className' => 'btn btn-default btn-sm no-corner',],
// ['extend' => 'export', 'className' => 'btn btn-default btn-sm no-corner',],
// ['extend' => 'print', 'className' => 'btn btn-default btn-sm no-corner',],
// ['extend' => 'reset', 'className' => 'btn btn-default btn-sm no-corner',],
// ['extend' => 'reload', 'className' => 'btn btn-default btn-sm no-corner',],
],
@if($config->options->localized)
'language' => [
'url' => url('//cdn.datatables.net/plug-ins/1.10.12/i18n/English.json'),
],
@endif
]);
}
/**
* Get columns.
*
* @return array
*/
protected function getColumns()
{
return [
{!! $columns !!}
];
}
/**
* Get filename for export.
*
* @return string
*/
protected function filename(): string
{
return '{{ $config->modelNames->snakePlural }}_datatable_' . time();
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $config->namespaces->livewireTables }};
use Laracasts\Flash\Flash;
use Rappasoft\LaravelLivewireTables\DataTableComponent;
use Rappasoft\LaravelLivewireTables\Views\Column;
use {{ $config->namespaces->model }}\{{ $config->modelNames->name }};
class {{ $config->modelNames->plural }}Table extends DataTableComponent
{
protected $model = {{ $config->modelNames->name }}::class;
protected $listeners = ['deleteRecord' => 'deleteRecord'];
public function deleteRecord($id)
{
{{ $config->modelNames->name }}::find($id)->delete();
@if($config->options->localized)
Flash::success(__('messages.deleted', ['model' => __('models/{{ $config->modelNames->camelPlural }}.singular')]));
@else
Flash::success('{{ $config->modelNames->human }} deleted successfully.');
@endif
$this->emit('refreshDatatable');
}
public function configure(): void
{
$this->setPrimaryKey('{{ $config->primaryName }}');
}
public function columns(): array
{
return [
{!! $columns !!},
Column::make("Actions", '{{ $config->primaryName }}')
->format(
fn($value, $row, Column $column) => view('common.livewire-tables.actions', [
'showUrl' => route('{{ $config->modelNames->dashedPlural }}.show', $row->{{ $config->primaryName }}),
'editUrl' => route('{{ $config->modelNames->dashedPlural }}.edit', $row->{{ $config->primaryName }}),
'recordId' => $row->{{ $config->primaryName }},
])
)
];
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ config('laravel_generator.namespace.request') }};
use Illuminate\Foundation\Http\FormRequest;
class CreateUserRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$rules = [
'name' => 'required',
'email' => 'required|email|unique:users,email',
'password' => 'required|confirmed'
];
return $rules;
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ config('laravel_generator.namespace.request') }};
use Illuminate\Foundation\Http\FormRequest;
class UpdateUserRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$id = $this->route('user');
$rules = [
'name' => 'required',
'email' => 'required|email|unique:users,email,'.$id,
'password' => 'confirmed'
];
return $rules;
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ config('laravel_generator.namespace.controller') }};
use {{ config('laravel_generator.namespace.request') }}\CreateUserRequest;
use {{ config('laravel_generator.namespace.request') }}\UpdateUserRequest;
use {{ config('laravel_generator.namespace.repository') }}\UserRepository;
use {{ config('laravel_generator.namespace.controller') }}\AppBaseController;
use Illuminate\Http\Request;
use Flash;
use Hash;
class UserController extends AppBaseController
{
/** @var $userRepository UserRepository */
private $userRepository;
public function __construct(UserRepository $userRepo)
{
$this->userRepository = $userRepo;
}
/**
* Display a listing of the User.
*
* @param Request $request
*/
public function index(Request $request)
{
$users = $this->userRepository->paginate(10);
return view('users.index')->with('users', $users);
}
/**
* Show the form for creating a new User.
*/
public function create()
{
return view('users.create');
}
/**
* Store a newly created User in storage.
*
* @param CreateUserRequest $request
*/
public function store(CreateUserRequest $request)
{
$input = $request->all();
$input['password'] = Hash::make($input['password']);
$user = $this->userRepository->create($input);
Flash::success('User saved successfully.');
return redirect(route('users.index'));
}
/**
* Display the specified User.
*
* @param int $id
*/
public function show($id)
{
$user = $this->userRepository->find($id);
if (empty($user)) {
Flash::error('User not found');
return redirect(route('users.index'));
}
return view('users.show')->with('user', $user);
}
/**
* Show the form for editing the specified User.
*
* @param int $id
*/
public function edit($id)
{
$user = $this->userRepository->find($id);
if (empty($user)) {
Flash::error('User not found');
return redirect(route('users.index'));
}
return view('users.edit')->with('user', $user);
}
/**
* Update the specified User in storage.
*
* @param int $id
* @param UpdateUserRequest $request
*/
public function update($id, UpdateUserRequest $request)
{
$user = $this->userRepository->find($id);
if (empty($user)) {
Flash::error('User not found');
return redirect(route('users.index'));
}
$input = $request->all();
if (!empty($input['password'])) {
$input['password'] = Hash::make($input['password']);
} else {
unset($input['password']);
}
$user = $this->userRepository->update($input, $id);
Flash::success('User updated successfully.');
return redirect(route('users.index'));
}
/**
* Remove the specified User from storage.
*
* @param int $id
*
* @throws \Exception
*/
public function destroy($id)
{
$user = $this->userRepository->find($id);
if (empty($user)) {
Flash::error('User not found');
return redirect(route('users.index'));
}
$this->userRepository->delete($id);
Flash::success('User deleted successfully.');
return redirect(route('users.index'));
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ config('laravel_generator.namespace.controller') }};
use {{ config('laravel_generator.namespace.request') }}\CreateUserRequest;
use {{ config('laravel_generator.namespace.request') }}\UpdateUserRequest;
use {{ config('laravel_generator.namespace.repository') }}\UserRepository;
use {{ config('laravel_generator.namespace.controller') }}\AppBaseController;
use Illuminate\Http\Request;
use Flash;
use Hash;
class UserController extends AppBaseController
{
/**
* Display a listing of the User.
*
* @param Request $request
*/
public function index(Request $request)
{
/** @var User $users */
$users = User::all();
return view('users.index')
->with('users', $users);
}
/**
* Show the form for creating a new User.
*/
public function create()
{
return view('users.create');
}
/**
* Store a newly created User in storage.
*
* @param CreateUserRequest $request
*/
public function store(CreateUserRequest $request)
{
$input = $request->all();
$input['password'] = Hash::make($input['password']);
/** @var User $user */
$user = User::create($input);
Flash::success('User saved successfully.');
return redirect(route('users.index'));
}
/**
* Display the specified User.
*
* @param int $id
*/
public function show($id)
{
/** @var User $user */
$user = User::find($id);
if (empty($user)) {
Flash::error('User not found');
return redirect(route('users.index'));
}
return view('users.show')->with('user', $user);
}
/**
* Show the form for editing the specified User.
*
* @param int $id
*/
public function edit($id)
{
/** @var User $user */
$user = User::find($id);
if (empty($user)) {
Flash::error('User not found');
return redirect(route('users.index'));
}
return view('users.edit')->with('user', $user);
}
/**
* Update the specified User in storage.
*
* @param int $id
* @param UpdateUserRequest $request
*/
public function update($id, UpdateUserRequest $request)
{
/** @var User $user */
$user = User::find($id);
if (empty($user)) {
Flash::error('User not found');
return redirect(route('users.index'));
}
$input = $request->all();
if (!empty($input['password'])) {
$input['password'] = Hash::make($input['password']);
} else {
unset($input['password']);
}
$user->fill($input);
$user->save();
Flash::success('User updated successfully.');
return redirect(route('users.index'));
}
/**
* Remove the specified User from storage.
*
* @param int $id
*
* @throws \Exception
*/
public function destroy($id)
{
/** @var User $user */
$user = User::find($id);
if (empty($user)) {
Flash::error('User not found');
return redirect(route('users.index'));
}
$user->delete();
Flash::success('User deleted successfully.');
return redirect(route('users.index'));
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ config('laravel_generator.namespace.repository') }};
use {{ config('laravel_generator.namespace.repository') }}\BaseRepository;
use {{ config('laravel_generator.namespace.model') }}\User;
/**
* Class UserRepository
* @package {{ config('laravel_generator.namespace.repository') }}
*/
class UserRepository extends BaseRepository
{
/**
* @var array
*/
protected $fieldSearchable = [
'name',
'email',
'password'
];
/**
* Return searchable fields
*
* @return array
*/
public function getFieldsSearchable(): array
{
return $this->fieldSearchable;
}
/**
* Configure the Model
**/
public function model(): string
{
return User::class;
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $namespaceApp }}Http\Controllers;
use InfyOm\Generator\Utils\ResponseUtil;
/**
* @OA\Server(url="/{{ $apiPrefix }}")
* @OA\Info(
* title="InfyOm Laravel Generator APIs",
* version="1.0.0"
* )
* This class should be parent class for other API controllers
* Class AppBaseController
*/
class AppBaseController extends Controller
{
public function sendResponse($result, $message)
{
return response()->json(ResponseUtil::makeResponse($message, $result));
}
public function sendError($error, $code = 404)
{
return response()->json(ResponseUtil::makeError($error), $code);
}
public function sendSuccess($message)
{
return response()->json([
'success' => true,
'message' => $message
], 200);
}
}
@php
echo "<?php".PHP_EOL;
@endphp
namespace {{ $namespaceApp }}Repositories;
use Illuminate\Container\Container as Application;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
abstract class BaseRepository
{
/**
* @var Model
*/
protected $model;
/**
* @throws \Exception
*/
public function __construct()
{
$this->makeModel();
}
/**
* Get searchable fields array
*/
abstract public function getFieldsSearchable(): array;
/**
* Configure the Model
*/
abstract public function model(): string;
/**
* Make Model instance
*
* @throws \Exception
*
* @return Model
*/
public function makeModel()
{
$model = app($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.
*/
public function paginate(int $perPage, array $columns = ['*']): LengthAwarePaginator
{
$query = $this->allQuery();
return $query->paginate($perPage, $columns);
}
/**
* Build a query for retrieving all records.
*/
public function allQuery(array $search = [], int $skip = null, int $limit = null): Builder
{
$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
*/
public function all(array $search = [], int $skip = null, int $limit = null, array $columns = ['*']): Collection
{
$query = $this->allQuery($search, $skip, $limit);
return $query->get($columns);
}
/**
* Create model record
*/
public function create(array $input): Model
{
$model = $this->model->newInstance($input);
$model->save();
return $model;
}
/**
* Find model record for given id
*
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|Model|null
*/
public function find(int $id, array $columns = ['*'])
{
$query = $this->model->newQuery();
return $query->find($id, $columns);
}
/**
* Update model record for given id
*
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|Model
*/
public function update(array $input, int $id)
{
$query = $this->model->newQuery();
$model = $query->findOrFail($id);
$model->fill($input);
$model->save();
return $model;
}
/**
* @throws \Exception
*
* @return bool|mixed|null
*/
public function delete(int $id)
{
$query = $this->model->newQuery();
$model = $query->findOrFail($id);
return $model->delete();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment