Skip to content

Commit

Permalink
Merge pull request #171 from Laravel-Backpack/generate_nested_control…
Browse files Browse the repository at this point in the history
…lers_and_models

Generate nested controllers and models
  • Loading branch information
tabacitu authored Jan 19, 2023
2 parents 6383103 + 310ee4b commit 7cad4b6
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 41 deletions.
20 changes: 10 additions & 10 deletions src/Console/Commands/CrudBackpackCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

namespace Backpack\Generators\Console\Commands;

use Illuminate\Console\GeneratorCommand;
use Backpack\Generators\Services\BackpackCommand;
use Illuminate\Support\Str;

class CrudBackpackCommand extends GeneratorCommand
class CrudBackpackCommand extends BackpackCommand
{
use \Backpack\CRUD\app\Console\Commands\Traits\PrettyCommandOutput;

Expand All @@ -32,9 +32,9 @@ class CrudBackpackCommand extends GeneratorCommand
public function handle()
{
$name = $this->getNameInput();
$nameTitle = ucfirst(Str::camel($name));
$nameKebab = Str::kebab($nameTitle);
$namePlural = ucfirst(str_replace('-', ' ', Str::plural($nameKebab)));
$nameTitle = $this->buildCamelName($name);
$nameKebab = $this->buildKebabName($nameTitle);
$fullNameWithSpaces = $this->buildNameWithSpaces($nameTitle);

// Validate if the name is reserved
if ($this->isReservedName($nameTitle)) {
Expand All @@ -52,24 +52,24 @@ public function handle()
}

// Create the CRUD Model and show output
$this->call('backpack:crud-model', ['name' => $nameTitle]);
$this->call('backpack:crud-model', ['name' => $name]);

// Create the CRUD Controller and show output
$this->call('backpack:crud-controller', ['name' => $nameTitle, '--validation' => $validation]);
$this->call('backpack:crud-controller', ['name' => $name, '--validation' => $validation]);

// Create the CRUD Request and show output
if ($validation === 'request') {
$this->call('backpack:crud-request', ['name' => $nameTitle]);
$this->call('backpack:crud-request', ['name' => $name]);
}

// Create the CRUD route
$this->call('backpack:add-custom-route', [
'code' => "Route::crud('$nameKebab', '{$nameTitle}CrudController');",
'code' => "Route::crud('$nameKebab', '{$this->convertSlashesForNamespace($nameTitle)}CrudController');",
]);

// Create the sidebar item
$this->call('backpack:add-sidebar-content', [
'code' => "<li class=\"nav-item\"><a class=\"nav-link\" href=\"{{ backpack_url('$nameKebab') }}\"><i class=\"nav-icon la la-th-list\"></i> $namePlural</a></li>",
'code' => "<li class=\"nav-item\"><a class=\"nav-link\" href=\"{{ backpack_url('$nameKebab') }}\"><i class=\"nav-icon la la-question\"></i> $fullNameWithSpaces</a></li>",
]);

// if the application uses cached routes, we should rebuild the cache so the previous added route will
Expand Down
31 changes: 17 additions & 14 deletions src/Console/Commands/CrudControllerBackpackCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

namespace Backpack\Generators\Console\Commands;

use Illuminate\Console\GeneratorCommand;
use Backpack\Generators\Services\BackpackCommand;
use Illuminate\Support\Str;

class CrudControllerBackpackCommand extends GeneratorCommand
class CrudControllerBackpackCommand extends BackpackCommand
{
use \Backpack\CRUD\app\Console\Commands\Traits\PrettyCommandOutput;

Expand Down Expand Up @@ -47,8 +47,10 @@ class CrudControllerBackpackCommand extends GeneratorCommand
*/
public function handle()
{
$name = $this->qualifyClass($this->getNameInput());
$path = $this->getPath($name);
$name = $this->getNameInput();
$nameTitle = $this->buildCamelName($name);
$qualifiedClassName = $this->qualifyClass($nameTitle);
$path = $this->getPath($qualifiedClassName);
$relativePath = Str::of($path)->after(base_path())->trim('\\/');

$this->progressBlock("Creating Controller <fg=blue>$relativePath</>");
Expand All @@ -67,7 +69,7 @@ public function handle()
// stub files so that it gets the correctly formatted namespace and class name.
$this->makeDirectory($path);

$this->files->put($path, $this->sortImports($this->buildClass($name)));
$this->files->put($path, $this->sortImports($this->buildClass($nameTitle)));

$this->closeProgressBlock();
}
Expand Down Expand Up @@ -116,11 +118,12 @@ protected function getDefaultNamespace($rootNamespace)
protected function replaceNameStrings(&$stub, $name)
{
$nameTitle = Str::afterLast($name, '\\');
$nameKebab = Str::kebab($nameTitle);
$nameSingular = str_replace('-', ' ', $nameKebab);
$namePlural = Str::plural($nameSingular);
$nameKebab = $this->buildKebabName($name);
$nameSingular = $this->buildSingularName($nameKebab);
$namePlural = $this->buildPluralName($nameSingular);

$stub = str_replace('DummyClass', $nameTitle, $stub);
$stub = str_replace('DummyModelClass', $this->convertSlashesForNamespace($nameTitle), $stub);
$stub = str_replace('DummyClass', $this->buildClassName($nameTitle), $stub);
$stub = str_replace('dummy-class', $nameKebab, $stub);
$stub = str_replace('dummy singular', $nameSingular, $stub);
$stub = str_replace('dummy plural', $namePlural, $stub);
Expand Down Expand Up @@ -196,7 +199,7 @@ protected function replaceSetFromDb(&$stub, $name)
protected function replaceModel(&$stub, $name)
{
$class = str_replace($this->getNamespace($name).'\\', '', $name);
$stub = str_replace(['DummyClass', '{{ class }}', '{{class}}'], $class, $stub);
$stub = str_replace(['DummyClass', '{{ class }}', '{{class}}'], $this->buildClassName($name), $stub);

return $this;
}
Expand Down Expand Up @@ -235,11 +238,11 @@ protected function buildClass($name)
{
$stub = $this->files->get($this->getStub());

$this->replaceNamespace($stub, $name)
$this->replaceNamespace($stub, $this->qualifyClass($name))
->replaceRequest($stub)
->replaceNameStrings($stub, $name)
->replaceModel($stub, $name)
->replaceSetFromDb($stub, $name);
->replaceNameStrings($stub, $this->buildCamelName($name))
->replaceModel($stub, $this->buildCamelName($name))
->replaceSetFromDb($stub, $this->buildCamelName($name));

return $stub;
}
Expand Down
22 changes: 12 additions & 10 deletions src/Console/Commands/CrudModelBackpackCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

namespace Backpack\Generators\Console\Commands;

use Illuminate\Console\GeneratorCommand;
use Backpack\Generators\Services\BackpackCommand;
use Illuminate\Support\Str;

class CrudModelBackpackCommand extends GeneratorCommand
class CrudModelBackpackCommand extends BackpackCommand
{
use \Backpack\CRUD\app\Console\Commands\Traits\PrettyCommandOutput;

Expand Down Expand Up @@ -54,9 +54,10 @@ class CrudModelBackpackCommand extends GeneratorCommand
public function handle()
{
$name = $this->getNameInput();
$namespaceApp = $this->qualifyClass($this->getNameInput());
$namespaceModels = $this->qualifyClass('/Models/'.$this->getNameInput());
$relativePath = lcfirst(Str::of("$namespaceModels.php")->replace('\\', '/'));
$nameTitle = $this->buildCamelName($name);
$namespaceApp = $this->qualifyClass($nameTitle);
$namespaceModels = $this->qualifyClass('/Models/'.$nameTitle);
$relativePath = $this->buildRelativePath($namespaceModels);

$this->progressBlock("Creating Model <fg=blue>$relativePath</>");

Expand All @@ -68,9 +69,9 @@ public function handle()
// should be written. Then, we will build the class and make the proper replacements on
// the stub files so that it gets the correctly formatted namespace and class name.
if (! $existsOnApp && ! $existsOnModels) {
$this->makeDirectory($namespaceModels);
$this->makeDirectory($this->getPath($namespaceModels));

$this->files->put($this->getPath($namespaceModels), $this->sortImports($this->buildClass($namespaceModels)));
$this->files->put($this->getPath($namespaceModels), $this->sortImports($this->buildClass($nameTitle)));

$this->closeProgressBlock();

Expand Down Expand Up @@ -113,7 +114,7 @@ public function handle()

// if it does not have CrudTrait, add the trait on the Model
foreach ($lines as $key => $line) {
if (Str::contains($line, "class {$this->getNameInput()} extends")) {
if (Str::contains($line, "class {$name} extends")) {
if (Str::endsWith($line, '{')) {
// add the trait on the next
$position = $key + 1;
Expand Down Expand Up @@ -164,7 +165,8 @@ protected function getStub()
*/
protected function replaceTable(&$stub, $name)
{
$name = ltrim(strtolower(preg_replace('/[A-Z]/', '_$0', str_replace($this->getNamespace($name).'\\', '', $name))), '_');
$name = str_replace('/', '', $this->buildCamelName($name));
$name = ltrim(strtolower(preg_replace('/[A-Z]/', '_$0', $name)), '_');

$table = Str::snake(Str::plural($name));

Expand All @@ -183,6 +185,6 @@ protected function buildClass($name)
{
$stub = $this->files->get($this->getStub());

return $this->replaceNamespace($stub, $name)->replaceTable($stub, $name)->replaceClass($stub, $name);
return $this->replaceNamespace($stub, $this->qualifyClass('/Models/'.$name))->replaceTable($stub, $name)->replaceClass($stub, $this->buildClassName($name));
}
}
12 changes: 7 additions & 5 deletions src/Console/Commands/CrudRequestBackpackCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

namespace Backpack\Generators\Console\Commands;

use Illuminate\Console\GeneratorCommand;
use Backpack\Generators\Services\BackpackCommand;
use Illuminate\Support\Str;

class CrudRequestBackpackCommand extends GeneratorCommand
class CrudRequestBackpackCommand extends BackpackCommand
{
use \Backpack\CRUD\app\Console\Commands\Traits\PrettyCommandOutput;

Expand Down Expand Up @@ -46,8 +46,10 @@ class CrudRequestBackpackCommand extends GeneratorCommand
*/
public function handle()
{
$name = $this->qualifyClass($this->getNameInput());
$path = $this->getPath($name);
$name = $this->getNameInput();
$nameTitle = $this->buildCamelName($name);
$qualifiedClassName = $this->qualifyClass($nameTitle);
$path = $this->getPath($qualifiedClassName);
$relativePath = Str::of($path)->after(base_path())->trim('\\/');

$this->progressBlock("Creating Request <fg=blue>$relativePath</>");
Expand All @@ -66,7 +68,7 @@ public function handle()
// stub files so that it gets the correctly formatted namespace and class name.
$this->makeDirectory($path);

$this->files->put($path, $this->sortImports($this->buildClass($name)));
$this->files->put($path, $this->sortImports($this->buildClass($qualifiedClassName)));

$this->closeProgressBlock();
}
Expand Down
4 changes: 2 additions & 2 deletions src/Console/stubs/crud-controller.stub
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace DummyNamespace;

use App\Http\Requests\DummyClassRequest;
use App\Http\Requests\DummyModelClassRequest;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;

Expand All @@ -26,7 +26,7 @@ class DummyClassCrudController extends CrudController
*/
public function setup()
{
CRUD::setModel(\App\Models\DummyClass::class);
CRUD::setModel(\App\Models\DummyModelClass::class);
CRUD::setRoute(config('backpack.base.route_prefix') . '/dummy-class');
CRUD::setEntityNameStrings('dummy singular', 'dummy plural');
}
Expand Down
85 changes: 85 additions & 0 deletions src/Services/BackpackCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

namespace Backpack\Generators\Services;

use Illuminate\Console\GeneratorCommand;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

class BackpackCommand extends GeneratorCommand
{
private const STR_CAMEL = 'camel';

private const STR_KEBAB = 'kebab';

public function buildCamelName(string $name): string
{
return self::buildName($name, self::STR_CAMEL);
}

public function buildKebabName(string $name): string
{
return self::buildName($name, self::STR_KEBAB);
}

public function buildName(string $name, string $type): string
{
$nameTitles = explode('/', $name);
$nameTitle = '';

$applyCasing = fn (string $title) => $type === self::STR_CAMEL ? ucfirst($title) : strtolower($title);

foreach ($nameTitles as $key => $title) {
$nameTitle .= $key > 0 ? '/' : '';
$nameTitle .= $applyCasing(Str::$type($title));
}

return $nameTitle;
}

public function buildPluralName(string $nameKebab)
{
return Str::plural(str_replace('-', ' ', Arr::last(explode('/', $nameKebab))));
}

public function buildNameWithSpaces(string $nameTitle): string
{
$words = preg_split('/(?=[A-Z])/', str_replace('/', '', $nameTitle));

// Transform last word into plural
$lastWord = Arr::last($words);
array_pop($words);
$words[] = Str::plural($lastWord);

$name = [];

foreach ($words as $word) {
if ($word === '') {
continue;
}
$name[] = count($name) === 0 ? ucfirst($word) : strtolower($word);
}

return implode(' ', $name);
}

public function buildSingularName(string $nameKebab)
{
return str_replace('-', ' ', Arr::last(explode('/', $nameKebab)));
}

public function buildRelativePath(string $name): string
{
return lcfirst(Str::of("$name.php")->replace('\\', '/'));
}

public function buildClassName(string $name): string
{
return ucfirst(Arr::last(explode('/', $name)));
}

public function convertSlashesForNamespace(string $name): string
{
return Str::replace('/', '\\', $name);
}
}

0 comments on commit 7cad4b6

Please sign in to comment.