Skip to content

Commit

Permalink
service provider register
Browse files Browse the repository at this point in the history
  • Loading branch information
recca0120 committed Apr 26, 2018
1 parent d6febc5 commit 0010638
Show file tree
Hide file tree
Showing 8 changed files with 263 additions and 24 deletions.
13 changes: 9 additions & 4 deletions config/generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

return [
'model' => [
'path' => base_path('app'),
'path' => app_path(''),
'stub' => resource_path('stubs/app/Model.stub'),
'attributes' => [
'namespace' => 'App',
'extends' => 'Illuminate\Database\Eloquent\Model',
],
],
'repository-contract' => [
'path' => base_path('app/Repositories/Contracts'),
'path' => app_path('Repositories/Contracts'),
'stub' => resource_path('stubs/app/Repositories/Contracts/Repository.stub'),
'suffix' => 'Repository',
'sort' => false,
Expand All @@ -19,16 +19,21 @@
],
],
'repository' => [
'path' => base_path('app/Repositories/Contracts'),
'path' => app_path('Repositories'),
'stub' => resource_path('stubs/app/Repositories/Repository.stub'),
'suffix' => 'Repository',
'attributes' => [
'namespace' => 'App\Repositories',
'extends' => 'Recca0120\Repository\EloquentRepository',
'extends' => \Recca0120\Repository\EloquentRepository::class,
],
'dependencies' => [
'model',
'repository-contract',
],
'plugins' => [
\Recca0120\Generator\Plugins\ServiceProviderRegister::class => [
'path' => app_path('Providers/AppServiceProvider.php'),
],
],
],
];
45 changes: 31 additions & 14 deletions src/Code.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class Code

private $files;

private $useSortFixer;

public function __construct($name, $config, $dependencies = [], Filesystem $files = null, UseSortFixer $useSortFixer = null)
{
$this->files = $files ?: new Filesystem;
Expand All @@ -31,7 +33,10 @@ public function __construct($name, $config, $dependencies = [], Filesystem $file
$this->dependencies = $dependencies;

$this->className = $this->name.Arr::get($this->config, 'suffix', '');
$this->attributes = $this->mergeAttributes($dependencies);
$this->attributes = $this->mergeAttributes(
$dependencies,
Arr::get($this->config, 'plugins', [])
);
}

public function __toString()
Expand All @@ -47,7 +52,7 @@ public function getAttributes($prefix = null)

$attributes = [];
foreach ($this->attributes as $key => $value) {
$attributes[$prefix.'_'.$key] = $value;
$attributes[str_replace('-', '_', $prefix.'_'.$key)] = $value;
}

return $attributes;
Expand Down Expand Up @@ -76,17 +81,6 @@ public function store()
: false;
}

private function getDummyAttributes()
{
$dummy = [];
foreach ($this->attributes as $key => $value) {
$dummy['Dummy'.Str::studly($key)] = $value;
$dummy['dummy'.Str::studly($key)] = Str::camel($value);
}

return $dummy;
}

private function renderStub()
{
return strtr($this->files->get($this->config['stub']), $this->getDummyAttributes());
Expand All @@ -97,7 +91,7 @@ private function format($content, $useSort = false)
return $useSort === true ? $this->useSortFixer->fix($content) : $content;
}

private function mergeAttributes($dependencies)
private function mergeAttributes($dependencies, $plugins)
{
$attributes = array_merge(Arr::get($this->config, 'attributes', []), [
'name' => $this->name,
Expand All @@ -117,6 +111,29 @@ private function mergeAttributes($dependencies)
$attributes = array_merge($attributes, $dependency->getAttributes($name));
}

foreach ($plugins as $pluginClass => $pluginConfig) {
$plugin = new $pluginClass();
$plugin->setConfig($pluginConfig);
$plugin->setAttributes($attributes);
$plugin->setFilesystem($this->files);
$plugin->setUseSortFixer($this->useSortFixer);
$processedAttributes = $plugin->process();
if (is_array($processedAttributes) === true) {
$attributes = array_merge($attributes, $processedAttributes);
}
}

return $attributes;
}

private function getDummyAttributes()
{
$dummy = [];
foreach ($this->attributes as $key => $value) {
$dummy['Dummy'.Str::studly($key)] = $value;
$dummy['dummy'.Str::studly($key)] = Str::camel($value);
}

return $dummy;
}
}
48 changes: 48 additions & 0 deletions src/Plugins/Plugin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace Recca0120\Generator\Plugins;

use Illuminate\Filesystem\Filesystem;
use Recca0120\Generator\Fixers\UseSortFixer;

abstract class Plugin
{
protected $config = [];

protected $attributes = [];

protected $files;

protected $useSortFixer;

public function setConfig($config)
{
$this->config = $config;

return $this;
}

public function setAttributes($attributes)
{
$this->attributes = $attributes;

return $this;
}

public function setFilesystem(Filesystem $files)
{
$this->files = $files;

return $this;
}

public function setUseSortFixer(UseSortFixer $useSortFixer)
{
$this->useSortFixer = $useSortFixer;
$this->useSortFixer->setSortType(UseSortFixer::SORT_TYPE_LENGTH);

return $this;
}

abstract public function process();
}
81 changes: 81 additions & 0 deletions src/Plugins/ServiceProviderRegister.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

namespace Recca0120\Generator\Plugins;

use Illuminate\Support\Arr;
use Illuminate\Support\Str;

class ServiceProviderRegister extends Plugin
{
public function process()
{
$path = Arr::get($this->config, 'path');

if (empty($path) === true) {
return;
}

$content = $this->files->get($path);

if (strpos($content, '$this->registerRepositories') === false) {
$content = preg_replace_callback('/public function register\(.+\n\s+{/', function ($m) {
return $m[0]."\n".
str_repeat(' ', 8).
'$this->registerRepositories();';
}, $content);
}

if (strpos($content, 'protected function registerRepositories()') === false) {
$content = substr($content, 0, strrpos($content, '}')).
"\n".str_repeat(' ', 4).
'protected function registerRepositories()'.
"\n".str_repeat(' ', 4).'{'.
"\n".str_repeat(' ', 4).'}'.
"\n}\n";
}

$qualifiedName = $this->attributes['qualified_name'];
$class = $this->attributes['class'];

if ($qualifiedName && strpos($content, sprintf('use %s;', $qualifiedName)) === false) {
$content = preg_replace_callback(
'/namespace.+/',
[$this, 'replaceServieProviderCallback'],
$content
);
}

if ($class && strpos($content, sprintf('$this->app->singleton(%sContract::class, %s::class);', $class, $class)) === false) {
$content = preg_replace_callback(
'/protected function registerRepositories.+\n\s+{/',
[$this, 'replaceServieProviderCallback'],
$content
);
}

$this->files->put($path, $this->useSortFixer->fix($content));
}

/**
* replaceServieProviderCallback.
*
* @param array $match
* @return string
*/
private function replaceServieProviderCallback($match)
{
$qualifiedName = $this->attributes['qualified_name'];
$class = $this->attributes['class'];
$contractQualifiedName = $this->attributes['repository_contract_qualified_name'];

if (Str::startsWith($match[0], 'namespace') === true) {
return $match[0]."\n\n".
sprintf("use %s as %sContract;\n", $contractQualifiedName, $class).
sprintf("use %s;\n", $qualifiedName);
}

return $match[0]."\n".
str_repeat(' ', 8).
sprintf('$this->app->singleton(%sContract::class, %s::class);', $class, $class);
}
}
29 changes: 23 additions & 6 deletions tests/GeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,25 @@ protected function setUp()
{
$this->root = vfsStream::setup();

mkdir($this->root->url().'/app');
mkdir($this->root->url().'/app/Providers');
file_put_contents(
$this->root->url().'/app/Providers/AppServiceProvider.php',
file_get_contents(__DIR__.'/fixtures/app/Providers/AppServiceProvider.php')
);

parent::setUp();
$this->config = [
'model' => [
'path' => $this->base_path('app'),
'path' => $this->app_path(''),
'stub' => resource_path('stubs/app/Model.stub'),
'attributes' => [
'namespace' => 'App',
'extends' => 'Illuminate\Database\Eloquent\Model',
],
],
'repository-contract' => [
'path' => $this->base_path('app/Repositories/Contracts'),
'path' => $this->app_path('Repositories/Contracts'),
'stub' => resource_path('stubs/app/Repositories/Contracts/Repository.stub'),
'suffix' => 'Repository',
'sort' => false,
Expand All @@ -35,17 +42,22 @@ protected function setUp()
],
],
'repository' => [
'path' => $this->base_path('app/Repositories'),
'path' => $this->app_path('Repositories'),
'stub' => resource_path('stubs/app/Repositories/Repository.stub'),
'suffix' => 'Repository',
'attributes' => [
'namespace' => 'App\Repositories',
'extends' => 'Recca0120\Repository\EloquentRepository',
'extends' => \Recca0120\Repository\EloquentRepository::class,
],
'dependencies' => [
'model',
'repository-contract',
],
'plugins' => [
\Recca0120\Generator\Plugins\ServiceProviderRegister::class => [
'path' => $this->app_path('Providers/AppServiceProvider.php'),
],
],
],
];
}
Expand Down Expand Up @@ -96,6 +108,11 @@ public function it_should_generate_repository()
$this->lineEncoding($code->render()),
$this->getFixture('app/Repositories/FooBarRepository.php')
);

$this->assertSame(
$this->lineEncoding(file_get_contents($this->app_path('Providers/AppServiceProvider.php'))),
$this->getFixture('app/Providers/AppServiceProviderSnapshot.php')
);
}

/** @test */
Expand Down Expand Up @@ -138,8 +155,8 @@ private function lineEncoding($content)
return str_replace("\r\n", "\n", $content);
}

private function base_path($path)
private function app_path($path)
{
return $this->root->url().'/'.$path;
return $this->root->url().'/app/'.$path;
}
}
7 changes: 7 additions & 0 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ function base_path($path)
}
}

if (function_exists('app_path') === false) {
function app_path($path)
{
return realpath(__DIR__.'/fixtures/app/'.$path);
}
}

if (function_exists('resource_path') === false) {
function resource_path($path)
{
Expand Down
28 changes: 28 additions & 0 deletions tests/fixtures/app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
}

/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}

0 comments on commit 0010638

Please sign in to comment.