Browse Source

Create new command make:crud-api

Generate Api Controller
tags/1.1.0
Nafies Luthfi 8 years ago
parent
commit
108596431a
  1. 113
      src/CrudApiMake.php
  2. 19
      src/Generators/ControllerGenerator.php
  3. 1
      src/ServiceProvider.php
  4. 88
      src/stubs/controller.api.stub
  5. 156
      tests/CrudApiMakeCommandTest.php
  6. 106
      tests/Generators/Api/ApiControllerGeneratorTest.php

113
src/CrudApiMake.php

@ -0,0 +1,113 @@
<?php
namespace Luthfi\CrudGenerator;
class CrudApiMake extends GeneratorCommand
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'make:crud-api {name} {--p|parent=} {--t|tests-only}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create simple Laravel API CRUD files of given model name.';
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
$this->getModelName();
if ($this->modelExists()) {
$this->error("{$this->modelNames['model_name']} model already exists.");
return;
}
// Warn if it has no default layout view based on
// simple-crud.default_layout_view config
if ($this->defaultLayoutNotExists()) {
$this->warn(config('simple-crud.default_layout_view').' view does not exists.');
}
if ($this->option('tests-only')) {
$this->generateTestFiles();
$this->info('Test files generated successfully!');
return;
}
$this->generateRoutes();
$this->generateModel();
$this->generateController();
$this->generateResources();
$this->generateTestFiles();
$this->info('CRUD files generated successfully!');
}
/**
* Generate test files
*
* @return void
*/
public function generateTestFiles()
{
app('Luthfi\CrudGenerator\Generators\ModelTestGenerator', ['command' => $this])->generate();
app('Luthfi\CrudGenerator\Generators\FeatureTestGenerator', ['command' => $this])->generate('simple');
app('Luthfi\CrudGenerator\Generators\ModelPolicyTestGenerator', ['command' => $this])->generate();
}
/**
* Generate Controller
*
* @return void
*/
public function generateController()
{
app('Luthfi\CrudGenerator\Generators\ControllerGenerator', ['command' => $this])->generate('api');
}
/**
* Generate Model
*
* @return void
*/
public function generateModel()
{
app('Luthfi\CrudGenerator\Generators\ModelGenerator', ['command' => $this])->generate();
app('Luthfi\CrudGenerator\Generators\MigrationGenerator', ['command' => $this])->generate();
app('Luthfi\CrudGenerator\Generators\ModelPolicyGenerator', ['command' => $this])->generate();
app('Luthfi\CrudGenerator\Generators\ModelFactoryGenerator', ['command' => $this])->generate();
}
/**
* Generate Route Route
*
* @return void
*/
public function generateRoutes()
{
app('Luthfi\CrudGenerator\Generators\WebRouteGenerator', ['command' => $this])->generate();
}
/**
* Generate Resources
*
* @return void
*/
public function generateResources()
{
app('Luthfi\CrudGenerator\Generators\LangFileGenerator', ['command' => $this])->generate();
app('Luthfi\CrudGenerator\Generators\FormViewGenerator', ['command' => $this])->generate('simple');
app('Luthfi\CrudGenerator\Generators\IndexViewGenerator', ['command' => $this])->generate('simple');
}
}

19
src/Generators/ControllerGenerator.php

@ -12,16 +12,26 @@ class ControllerGenerator extends BaseGenerator
*/
public function generate(string $type = 'full')
{
$pluralModelName = $this->modelNames['plural_model_name'];
$parentControllerDirectory = '';
if (!is_null($this->command->option('parent'))) {
$parentControllerDirectory = '/'.$this->command->option('parent');
}
if ($this->isForApi()) {
$parentControllerDirectory = '/Api'.$parentControllerDirectory;
}
$controllerPath = $this->makeDirectory(app_path('Http/Controllers'.$parentControllerDirectory));
$controllerPath = $controllerPath.'/'.$pluralModelName.'Controller.php';
$controllerPath = $controllerPath.'/'.$this->modelNames['plural_model_name'].'Controller.php';
$this->generateFile($controllerPath, $this->getContent('controller.'.$type));
$this->command->info($this->modelNames['plural_model_name'].'Controller generated.');
if ($this->isForApi()) {
$pluralModelName = 'Api/'.$pluralModelName;
}
$this->command->info($pluralModelName.'Controller generated.');
}
/**
@ -61,4 +71,9 @@ class ControllerGenerator extends BaseGenerator
return $controllerFileContent;
}
private function isForApi()
{
return $this->command->getName() == 'make:crud-api';
}
}

1
src/ServiceProvider.php

@ -15,6 +15,7 @@ class ServiceProvider extends BaseServiceProvider
$this->commands([
CrudMake::class,
CrudSimpleMake::class,
CrudApiMake::class,
]);
}

88
src/stubs/controller.api.stub

@ -0,0 +1,88 @@
<?php
namespace App\Http\Controllers\Api;
use fullMstr;
use Illuminate\Http\Request;
class MastersController extends Controller
{
/**
* Display a listing of the singleMstr.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$mstrCollections = Master::where(function ($query) {
$query->where('name', 'like', '%'.request('q').'%');
})->paginate(25);
return $mstrCollections;
}
/**
* Store a newly created singleMstr in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$this->authorize('create', new Master);
$this->validate($request, [
'name' => 'required|max:60',
'description' => 'nullable|max:255',
]);
$newMaster = $request->only('name', 'description');
$newMaster['creator_id'] = auth()->id();
$singleMstr = Master::create($newMaster);
return $singleMstr;
}
/**
* Update the specified singleMstr in storage.
*
* @param \Illuminate\Http\Request $request
* @param \fullMstr $singleMstr
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Master $singleMstr)
{
$this->authorize('update', $singleMstr);
$this->validate($request, [
'name' => 'required|max:60',
'description' => 'nullable|max:255',
]);
$singleMstr->update($request->only('name', 'description'));
return $singleMstr;
}
/**
* Remove the specified singleMstr from storage.
*
* @param \fullMstr $singleMstr
* @return \Illuminate\Http\Response
*/
public function destroy(Master $singleMstr)
{
$this->authorize('delete', $singleMstr);
$this->validate(request(), [
'master_id' => 'required',
]);
if (request('master_id') == $singleMstr->id && $singleMstr->delete()) {
return response()->json('master deleted.', 204);
}
return response()->json('Unprocessable Entity.', 422);
}
}

156
tests/CrudApiMakeCommandTest.php

@ -0,0 +1,156 @@
<?php
namespace Tests;
use Illuminate\Contracts\Console\Kernel;
class CrudApiMakeCommandTest extends TestCase
{
/** @test */
public function it_can_generate_api_crud_files()
{
$this->artisan('make:crud-api', ['name' => $this->model_name, '--no-interaction' => true]);
$this->assertNotContains("{$this->model_name} model already exists.", app(Kernel::class)->output());
$this->assertFileExists(app_path($this->model_name.'.php'));
$this->assertFileExists(app_path("Http/Controllers/Api/{$this->plural_model_name}Controller.php"));
$migrationFilePath = database_path('migrations/'.date('Y_m_d_His').'_create_'.$this->table_name.'_table.php');
$this->assertFileExists($migrationFilePath);
$this->assertFileExists(resource_path("views/{$this->table_name}/index.blade.php"));
$this->assertFileExists(resource_path("views/{$this->table_name}/forms.blade.php"));
$localeConfig = config('app.locale');
$this->assertFileExists(resource_path("lang/{$localeConfig}/{$this->lang_name}.php"));
$this->assertFileExists(base_path("routes/web.php"));
$this->assertFileExists(app_path("Policies/{$this->model_name}Policy.php"));
$this->assertFileExists(database_path("factories/{$this->model_name}Factory.php"));
$this->assertFileExists(base_path("tests/Unit/Models/{$this->model_name}Test.php"));
$this->assertFileExists(base_path("tests/Feature/Manage{$this->plural_model_name}Test.php"));
}
/** @test */
public function it_cannot_generate_crud_files_if_model_exists()
{
$this->artisan('make:model', ['name' => $this->model_name, '--no-interaction' => true]);
$this->artisan('make:crud', ['name' => $this->model_name, '--no-interaction' => true]);
$this->assertContains("{$this->model_name} model already exists.", app(Kernel::class)->output());
$this->assertFileExists(app_path($this->model_name.'.php'));
$this->assertFileNotExists(app_path("Http/Controllers/Api/{$this->plural_model_name}Controller.php"));
$migrationFilePath = database_path('migrations/'.date('Y_m_d_His').'_create_'.$this->table_name.'_table.php');
$this->assertFileNotExists($migrationFilePath);
$this->assertFileNotExists(resource_path("views/{$this->table_name}/index.blade.php"));
$this->assertFileNotExists(resource_path("views/{$this->table_name}/forms.blade.php"));
$localeConfig = config('app.locale');
$this->assertFileNotExists(resource_path("lang/{$localeConfig}/{$this->lang_name}.php"));
$this->assertFileNotExists(base_path("routes/web.php"));
$this->assertFileNotExists(app_path("Policies/{$this->model_name}Policy.php"));
$this->assertFileNotExists(database_path("factories/{$this->model_name}Factory.php"));
$this->assertFileNotExists(base_path("tests/Unit/Models/{$this->model_name}Test.php"));
$this->assertFileNotExists(base_path("tests/Feature/Manage{$this->plural_model_name}Test.php"));
}
/** @test */
public function it_cannot_generate_crud_files_if_namespaced_model_exists()
{
$this->artisan('make:model', ['name' => 'Entities/Projects/Problem', '--no-interaction' => true]);
$this->artisan('make:crud-api', ['name' => 'Entities/Projects/Problem', '--no-interaction' => true]);
$this->assertContains("Problem model already exists.", app(Kernel::class)->output());
$this->assertFileExists(app_path('Entities/Projects/Problem.php'));
$this->assertFileNotExists(app_path("Http/Controllers/Api/ProblemsController.php"));
$migrationFilePath = database_path('migrations/'.date('Y_m_d_His').'_create_problems_table.php');
$this->assertFileNotExists($migrationFilePath);
$this->assertFileNotExists(resource_path("views/problems/index.blade.php"));
$this->assertFileNotExists(resource_path("views/problems/forms.blade.php"));
$localeConfig = config('app.locale');
$this->assertFileNotExists(resource_path("lang/{$localeConfig}/{$this->lang_name}.php"));
$this->assertFileNotExists(app_path("Policies/ProblemPolicy.php"));
$this->assertFileNotExists(database_path("factories/ProblemFactory.php"));
$this->assertFileNotExists(base_path("tests/Unit/Models/ProblemTest.php"));
$this->assertFileNotExists(base_path("tests/Feature/ManageProblemsTest.php"));
$this->removeFileOrDir(app_path('Entities/Projects'));
$this->removeFileOrDir(resource_path('views/problems'));
$this->removeFileOrDir(resource_path("lang/en/problem.php"));
}
/** @test */
public function it_can_generate_crud_files_for_namespaced_model()
{
$inputName = 'Entities/References/Category';
$modelName = 'Category';
$pluralModelName = 'Categories';
$tableName = 'categories';
$langName = 'category';
$modelPath = 'Entities/References';
$this->artisan('make:crud-api', ['name' => $inputName, '--no-interaction' => true]);
$this->assertNotContains("{$modelName} model already exists.", app(Kernel::class)->output());
$this->assertFileExists(app_path($modelPath.'/'.$modelName.'.php'));
$this->assertFileExists(app_path("Http/Controllers/Api/{$pluralModelName}Controller.php"));
$migrationFilePath = database_path('migrations/'.date('Y_m_d_His').'_create_'.$tableName.'_table.php');
$this->assertFileExists($migrationFilePath);
$this->assertFileExists(resource_path("views/{$tableName}/index.blade.php"));
$this->assertFileExists(resource_path("views/{$tableName}/forms.blade.php"));
$localeConfig = config('app.locale');
$this->assertFileExists(resource_path("lang/{$localeConfig}/{$langName}.php"));
$this->assertFileExists(app_path("Policies/{$modelName}Policy.php"));
$this->assertFileExists(database_path("factories/{$modelName}Factory.php"));
$this->assertFileExists(base_path("tests/Unit/Models/{$modelName}Test.php"));
$this->assertFileExists(base_path("tests/Feature/Manage{$pluralModelName}Test.php"));
}
/** @test */
public function it_can_generate_crud_files_with_parent_option()
{
$inputName = 'Entities/References/Category';
$modelName = 'Category';
$parentName = 'Projects';
$pluralModelName = 'Categories';
$tableName = 'categories';
$langName = 'category';
$modelPath = 'Entities/References';
$this->artisan('make:crud-api', ['name' => $inputName, '--parent' => $parentName, '--no-interaction' => true]);
$this->assertNotContains("{$modelName} model already exists.", app(Kernel::class)->output());
$this->assertFileExists(app_path($modelPath.'/'.$modelName.'.php'));
$this->assertFileExists(app_path("Http/Controllers/Api/{$parentName}/{$pluralModelName}Controller.php"));
$migrationFilePath = database_path('migrations/'.date('Y_m_d_His').'_create_'.$tableName.'_table.php');
$this->assertFileExists($migrationFilePath);
$this->assertFileExists(resource_path("views/{$tableName}/index.blade.php"));
$this->assertFileExists(resource_path("views/{$tableName}/forms.blade.php"));
$localeConfig = config('app.locale');
$this->assertFileExists(resource_path("lang/{$localeConfig}/{$langName}.php"));
$this->assertFileExists(database_path("factories/{$modelName}Factory.php"));
$this->assertFileExists(base_path("tests/Unit/Models/{$modelName}Test.php"));
$this->assertFileExists(app_path("Policies/{$parentName}/{$modelName}Policy.php"));
$this->assertFileExists(base_path("tests/Feature/Manage{$pluralModelName}Test.php"));
}
}

106
tests/Generators/Api/ApiControllerGeneratorTest.php

@ -0,0 +1,106 @@
<?php
namespace Tests\Generators\Simple;
use Tests\TestCase;
class ApiControllerGeneratorTest extends TestCase
{
/** @test */
public function it_creates_correct_controller_class_content()
{
$this->artisan('make:crud-api', ['name' => $this->model_name, '--no-interaction' => true]);
$this->assertFileExists(app_path("Http/Controllers/Api/{$this->plural_model_name}Controller.php"));
$ctrlClassContent = "<?php
namespace App\Http\Controllers\Api;
use {$this->full_model_name};
use Illuminate\Http\Request;
class {$this->plural_model_name}Controller extends Controller
{
/**
* Display a listing of the {$this->single_model_var_name}.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
\${$this->collection_model_var_name} = {$this->model_name}::where(function (\$query) {
\$query->where('name', 'like', '%'.request('q').'%');
})->paginate(25);
return \${$this->collection_model_var_name};
}
/**
* Store a newly created {$this->single_model_var_name} in storage.
*
* @param \Illuminate\Http\Request \$request
* @return \Illuminate\Http\Response
*/
public function store(Request \$request)
{
\$this->authorize('create', new {$this->model_name});
\$this->validate(\$request, [
'name' => 'required|max:60',
'description' => 'nullable|max:255',
]);
\$new{$this->model_name} = \$request->only('name', 'description');
\$new{$this->model_name}['creator_id'] = auth()->id();
\${$this->single_model_var_name} = {$this->model_name}::create(\$new{$this->model_name});
return \${$this->single_model_var_name};
}
/**
* Update the specified {$this->single_model_var_name} in storage.
*
* @param \Illuminate\Http\Request \$request
* @param \\{$this->full_model_name} \${$this->single_model_var_name}
* @return \Illuminate\Http\Response
*/
public function update(Request \$request, {$this->model_name} \${$this->single_model_var_name})
{
\$this->authorize('update', \${$this->single_model_var_name});
\$this->validate(\$request, [
'name' => 'required|max:60',
'description' => 'nullable|max:255',
]);
\${$this->single_model_var_name}->update(\$request->only('name', 'description'));
return \${$this->single_model_var_name};
}
/**
* Remove the specified {$this->single_model_var_name} from storage.
*
* @param \\{$this->full_model_name} \${$this->single_model_var_name}
* @return \Illuminate\Http\Response
*/
public function destroy({$this->model_name} \${$this->single_model_var_name})
{
\$this->authorize('delete', \${$this->single_model_var_name});
\$this->validate(request(), [
'{$this->lang_name}_id' => 'required',
]);
if (request('{$this->lang_name}_id') == \${$this->single_model_var_name}->id && \${$this->single_model_var_name}->delete()) {
return response()->json('{$this->lang_name} deleted.', 204);
}
return response()->json('Unprocessable Entity.', 422);
}
}
";
$this->assertEquals($ctrlClassContent, file_get_contents(app_path("Http/Controllers/Api/{$this->plural_model_name}Controller.php")));
}
}
Loading…
Cancel
Save