Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
RicoClark committed Jun 29, 2020
0 parents commit e8e53c1
Show file tree
Hide file tree
Showing 20 changed files with 884 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
vendor
.idea/
composer.lock
Empty file added LICENSE.txt
Empty file.
122 changes: 122 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Laravel CSR
CSR stands for Controller/Service/Repository. This package lets you set all that up with just a single command, with the additional options to disable one of the three layers or even generate a model and/or migration automatically aswell.

## Usage
### Installation

Install the package using composer:
```
composer require scrumble-nl/laravel-csr
```

Publish the configuration file for default class paths:
```
php artisan vendor:publish --tag=laravel-csr
```

It is possible to modify the default class paths in this newly created `csr.php` config file.

### Command usage

The base command is `php artisan csr:gen {name} {namespace (optional)}`.


This will generate a controller, service interface, service, repository interface and repository all at once. They automatically are dependency injected into eachother so they are ready for usage immediately. Nice!

Finally, you need to add the generated service and/or repository to your `AppServiceProvider.php`.


#### Example

`php artisan csr:gen picture holiday`
will generate the following files:

- `app/Http/Controllers/Holiday/PictureController.php`
- `app/Interfaces/Services/Holiday/IPictureService.php`
- `app/Services/Holiday/PictureService`
- `app/Interfaces/Repositories/Holiday/IPictureRepository`
- `app/Repositories/Holiday/PictureRepository`

**Note**: The command will automatically capitalize the first character, so `picture` will become `Picture`. If you want your classes to have a name like `PictureBook` you will have to type this correctly yourself.

Now you will need to register your service and repository:

AppServiceProvider.php:
```php
<?php

declare(strict_types=1);

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Services\Holiday\PictureService;
use App\Repositories\Holiday\PictureRepository;
use App\Interfaces\Services\Holiday\IPictureService;
use App\Interfaces\Repositories\Holiday\IPictureRepository;

class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
app()->bind(IPictureService::class, PictureService::class);
app()->bind(IPictureRepository::class, PictureRepository::class);
}
}

```

And it's done!

#### Example output


app/Http/Controllers/Holiday/PictureController.php:
```php
<?php

declare(strict_types=1);

namespace App\Http\Controllers\Holiday;

use App\Http\Controllers\Controller;
use App\Interfaces\Services\Holiday\IPictureService;

class PictureController extends Controller
{
/**
* @var IPictureService
*/
private $pictureService;

/**
* @param IPictureService $pictureService
*/
public function __construct(IPictureService $pictureService)
{
$this->pictureService = $pictureService;
}
}
```

### Command options

The following options can be used to disable some generation, or even add models and migrations to the command:

| Name | Type | Required | Description | Default |
|--------------|:----------------------------------------------------------------------------------------:|:----------:|:-------------------------------------| -------- |
| `name` | string | *true* | The base name for all items to generate | |
| `namespace` | string | *false* | The namespace items will be in |
| `--model` | | *false* | Automatically create a model aswell | `false`
| `--migration` | | *false* | Automatically create a migration aswell | `false`
| `--nc` | | *false* | Do not generate the controller | `false`
| `--ns` | | *false* | Do not generate the service and service interface | `false`
| `--nr` | | *false* | Do not generate the repository and repository interface | `false`

See also: `php artisan csr:gen --help`

## Contributing
If you would like to see additions/changes to this package you are always welcome to add some code or improve it.

## Scrumble
This product has been originally developed by [Scrumble](https://www.scrumble.nl) for internal use. As we have been using lots of open source packages we wanted to give back to the community. We hope this helps you getting forward as much as other people helped us!
53 changes: 53 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"name": "scrumble-nl/laravel-csr",
"type": "library",
"homepage": "https://github.com/scrumble-nl/laravel-csr",
"description": "This package makes it possible to generate a controller, service, repository, model and migration all in 1 command",
"keywords": [
"command",
"generate",
"CSR",
"controller",
"service",
"repository",
"model",
"migration"
],
"license": "MIT",
"authors": [
{
"name": "Rico Clark",
"email": "[email protected]"
},
{
"name": "Luuk de Weijer",
"email": "[email protected]"
}
],
"autoload": {
"psr-4": {"Scrumble\\Csr\\": "src/"},
"classmap": [
"src"
]
},
"autoload-dev": {
"classmap": [
]
},
"require": {
"php": ">=7.3.1",
"laravel/framework": "^7.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"replace": {
},
"extra": {
"laravel": {
"providers": [
"Scrumble\\Csr\\Src\\CsrServiceProvider"
]
}
}
}
12 changes: 12 additions & 0 deletions config/csr.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

return [
'paths' => [
'model' => 'Models',
'controller' => 'Http/Controllers',
'service' => 'Services',
'service_interface' => 'Interfaces/Services',
'repository' => 'Repositories',
'repository_interface' => 'Interfaces/Repositories',
],
];
189 changes: 189 additions & 0 deletions src/Commands/CreateCsr.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
<?php

declare(strict_types=1);

namespace Scrumble\Csr\Src\Commands;

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

class CreateCsr extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'csr:gen
{name : The name for the pattern to be created}
{namespace? : The namespace the pattern belongs to}
{--nc : Optional disable of controller generation}
{--ns : Optional disable of service generation}
{--nr : Optional disable of repository generation}
{--migration : If the pattern also needs a create migration}
{--model : If the pattern also needs a create model}';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Generate a full controller/service/repository pattern for the given name and namespace';

/**
* The type of class being generated.
*
* @var string
*/
protected $type = 'Controller, service, repository, optional model and migration';

/**
* Execute the console command.
*
* @return void
*/
public function handle(): void
{
$name = ucfirst($this->argument('name'));
$namespace = ucfirst($this->argument('namespace') ?? '');

$options = [
'controller' => !$this->option('nc'),
'service' => !$this->option('ns'),
'repository' => !$this->option('nr'),
'model' => $this->option('model'),
'migration' => $this->option('migration'),
];

$enabledOptions = array_filter($options, function ($option) {
return !!$option;
});

if (!$this->confirm('Are you sure you want to create: ['
. implode(', ', array_keys($enabledOptions))
. '] with the NAME: ' . $name
. ($namespace ? ' and NAMESPACE: ' . $namespace : '') . '?')) {
$this->warn('Cancelled');
return;
}

if (!$this->option('nc')) {
$this->createController($namespace, $name);
}

if (!$this->option('ns')) {
$this->createService($namespace, $name);
}

if (!$this->option('nr')) {
$this->createRepository($namespace, $name);
}

if ($this->option('model')) {
$this->createModel($namespace, $name);
}

if ($this->option('migration')) {
$this->createMigration();
}

$this->alert('Generation complete, have fun doing some actual programming!');

if (!$this->option('ns') || !$this->option('nr')) {
$this->info('But first, there\'s one more thing to do:');

if (!$this->option('ns')) {
$this->warn('> Don\'t forget to bind the service in the AppServiceProvider');
}

if (!$this->option('nr')) {
$this->warn('> Don\'t forget to bind the repository in the AppServiceProvider');
}
}
}

/**
* Create the controller
*
* @param string $namespace
* @param string $name
*/
private function createController(string $namespace, string $name): void
{
$this->call('csr:controller', [
'name' => config('csr.paths.controller') . '/' . $namespace . '/' . $name . 'Controller',
'basename' => $name,
'namespace' => $namespace,
]);
}

/**
* Create the service
*
* @param string $namespace
* @param string $name
*/
private function createService(string $namespace, string $name): void
{
$this->call('csr:iservice', [
'name' => config('csr.paths.service_interface') . '/' . $namespace . '/I' . $name . 'Service',
'basename' => $name,
'namespace' => $namespace,
]);

$asdf = $this->call('csr:service', [
'name' => config('csr.paths.service') . '/' . $namespace . '/' . $name . 'Service',
'basename' => $name,
'namespace' => $namespace,
]);
}

/**
* Create the repository
*
* @param string $namespace
* @param string $name
*/
private function createRepository(string $namespace, string $name): void
{
$this->call('csr:irepository', [
'name' => config('csr.paths.repository_interface') . '/' . $namespace . '/I' . $name . 'Repository',
'basename' => $name,
'namespace' => $namespace,
]);

$this->call('csr:repository', [
'name' => config('csr.paths.repository') . '/' . $namespace . '/' . $name . 'Repository',
'basename' => $name,
'namespace' => $namespace,
]);
}

/**
* Create the model
*
* @param string $namespace
* @param string $name
*/
private function createModel(string $namespace, string $name): void
{
$this->call('csr:model', [
'name' => config('csr.paths.model') . '/' . $namespace . '/' . $name,
'namespace' => $namespace,
]);
}

/**
* Create the migration
*/
private function createMigration(): void
{
$table = Str::singular(Str::snake(class_basename($this->argument('name'))));

$this->call('make:migration', [
'name' => "create_{$table}_table",
'--create' => $table,
]);
}
}
10 changes: 10 additions & 0 deletions src/Commands/stubs/abstract/irepository.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace DummyNamespace;

interface {{Variable}}
{

}
Loading

0 comments on commit e8e53c1

Please sign in to comment.