Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Naoray committed May 6, 2020
1 parent 887d3f4 commit 929feb6
Show file tree
Hide file tree
Showing 15 changed files with 395 additions and 121 deletions.
20 changes: 11 additions & 9 deletions README.md
Expand Up @@ -81,25 +81,31 @@ public function fields(Request $request)
}
```

If you want to edit the tasks that are run in the background you can publish the configuration file by running the following command:
## Configuration
You may publish the configuration with the following command:

`php artisan vendor:publish --provider="Naoray\BlueprintNovaAddon\BlueprintNovaAddonServiceProvider" --tag="nova_generator"`
```bash
php artisan vendor:publish --tag=blueprint-nova-config
```

### Timestamp fields
To disable the generation of `timestamp` fields for all Nova resources set this option to `false`.

### Testing
## Testing

``` bash
composer test
```

### Changelog
## Changelog

Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.

## Contributing

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

### Security
## Security

If you discover any security related issues, please email krishan.koenig@gmail.com instead of using the issue tracker.

Expand All @@ -111,7 +117,3 @@ If you discover any security related issues, please email krishan.koenig@gmail.c
## License

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

## Laravel Package Boilerplate

This package was generated using the [Laravel Package Boilerplate](https://laravelpackageboilerplate.com).
18 changes: 18 additions & 0 deletions config/nova_blueprint.php
@@ -0,0 +1,18 @@
<?php

return [

/*
|--------------------------------------------------------------------------
| Resource Timestamps
|--------------------------------------------------------------------------
|
| Nova Blueprint by default adds the timestamp fields 'created_at',
| 'updated_at' and 'deleted_at' (if model uses SoftDeletes Trait) to
| the generated resources. if you want to prevent the generator from
| adding these fields set this option to `false`.
|
*/

'timestamps' => true,
];
17 changes: 0 additions & 17 deletions config/nova_generator.php

This file was deleted.

26 changes: 21 additions & 5 deletions src/BlueprintNovaAddonServiceProvider.php
Expand Up @@ -5,6 +5,10 @@
use Blueprint\Blueprint;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Support\DeferrableProvider;
use Naoray\BlueprintNovaAddon\Tasks\AddRegularFields;
use Naoray\BlueprintNovaAddon\Tasks\AddIdentifierField;
use Naoray\BlueprintNovaAddon\Tasks\AddTimestampFields;
use Naoray\BlueprintNovaAddon\Tasks\AddRelationshipFields;

class BlueprintNovaAddonServiceProvider extends ServiceProvider implements DeferrableProvider
{
Expand All @@ -15,8 +19,8 @@ public function boot()
{
if ($this->app->runningInConsole()) {
$this->publishes([
dirname(__DIR__) . '/config/nova_generator.php' => config_path('nova_generator.php'),
], 'nova_generator');
dirname(__DIR__) . '/config/nova_blueprint.php' => config_path('nova_blueprint.php'),
], 'nova_blueprint');
}
}

Expand All @@ -26,12 +30,23 @@ public function boot()
public function register()
{
$this->mergeConfigFrom(
dirname(__DIR__) . '/config/nova_generator.php',
'nova_generator'
dirname(__DIR__) . '/config/nova_blueprint.php',
'blueprint-nova-config'
);

$this->app->singleton(NovaGenerator::class, function ($app) {
$generator = new NovaGenerator($app['files']);

$generator->registerTask(new AddIdentifierField());
$generator->registerTask(new AddRegularFields());
$generator->registerTask(new AddRelationshipFields());
$generator->registerTask(new AddTimestampFields());

return $generator;
});

$this->app->extend(Blueprint::class, function ($blueprint, $app) {
$blueprint->registerGenerator(new NovaGenerator($app['files']));
$blueprint->registerGenerator($app[NovaGenerator::class]);

return $blueprint;
});
Expand All @@ -46,6 +61,7 @@ public function provides()
{
return [
'command.blueprint.build',
NovaGenerator::class,
Blueprint::class,
];
}
Expand Down
10 changes: 10 additions & 0 deletions src/Contracts/Task.php
@@ -0,0 +1,10 @@
<?php

namespace Naoray\BlueprintNovaAddon\Contracts;

use Closure;

interface Task
{
public function handle(array $data, Closure $next): array;
}
66 changes: 49 additions & 17 deletions src/NovaGenerator.php
Expand Up @@ -3,10 +3,13 @@
namespace Naoray\BlueprintNovaAddon;

use Blueprint\Blueprint;
use Blueprint\Contracts\Generator;
use Blueprint\Models\Model;
use Illuminate\Pipeline\Pipeline;
use Illuminate\Support\Str;
use Illuminate\Pipeline\Pipeline;
use Blueprint\Contracts\Generator;
use Naoray\BlueprintNovaAddon\Contracts\Task;
use Naoray\BlueprintNovaAddon\Tasks\RemapImports;
use Naoray\BlueprintNovaAddon\Tasks\AddTimestampFields;

class NovaGenerator implements Generator
{
Expand All @@ -18,6 +21,9 @@ class NovaGenerator implements Generator
/** @var array */
private $imports = [];

/** @var array */
private $tasks = [];

public function __construct($files)
{
$this->files = $files;
Expand All @@ -27,13 +33,13 @@ public function output(array $tree): array
{
$output = [];

$stub = $this->files->get($this->stubPath().DIRECTORY_SEPARATOR.'class.stub');
$stub = $this->files->get($this->stubPath() . DIRECTORY_SEPARATOR . 'class.stub');

/** @var \Blueprint\Models\Model $model */
foreach ($tree['models'] as $model) {
$path = $this->getPath($model);

if (! $this->files->exists(dirname($path))) {
if (!$this->files->exists(dirname($path))) {
$this->files->makeDirectory(dirname($path), 0755, true);
}

Expand All @@ -47,27 +53,25 @@ public function output(array $tree): array

protected function getPath(Model $model): string
{
$path = str_replace('\\', '/', Blueprint::relativeNamespace($this->getNovaNamespace($model).'/'.$model->name()));
$path = str_replace('\\', '/', Blueprint::relativeNamespace($this->getNovaNamespace($model) . '/' . $model->name()));

return config('blueprint.app_path').'/'.$path.'.php';
return config('blueprint.app_path') . '/' . $path . '.php';
}

protected function populateStub(string $stub, Model $model): string
{
$data = [
'fields' => '',
'imports' => [],
'model' => $model,
];

$data = resolve(Pipeline::class)
->send($data)
->through(config('nova_generator.field_tasks'))
->send([
'fields' => '',
'imports' => [],
'model' => $model,
])
->through($this->filteredTasks())
->thenReturn();

$stub = str_replace('DummyNamespace', $this->getNovaNamespace($model), $stub);
$stub = str_replace('DummyClass', $model->name(), $stub);
$stub = str_replace('DummyModel', '\\'.$model->fullyQualifiedClassName(), $stub);
$stub = str_replace('DummyModel', '\\' . $model->fullyQualifiedClassName(), $stub);
$stub = str_replace('// fields...', $data['fields'], $stub);
$stub = str_replace('use Illuminate\Http\Request;', implode(PHP_EOL, $data['imports']), $stub);

Expand All @@ -78,12 +82,40 @@ protected function getNovaNamespace(Model $model): string
{
$namespace = Str::of($model->fullyQualifiedNamespace())
->after(config('blueprint.namespace'))
->prepend(config('blueprint.namespace').'\Nova');
->prepend(config('blueprint.namespace') . '\Nova');

if (config('blueprint.models_namespace')) {
$namespace = $namespace->replace('\\'.config('blueprint.models_namespace'), '');
$namespace = $namespace->replace('\\' . config('blueprint.models_namespace'), '');
}

return $namespace->__toString();
}

public function registerTask(Task $task): void
{
$this->tasks[get_class($task)] = $task;
}

public function removeTask(string $taskName)
{
$taskClassNames = array_map(function ($taskObj) {
return get_class($taskObj);
}, $this->tasks);

$targetIndex = array_search($taskName, $taskClassNames);
array_splice($this->tasks, $targetIndex, 1);
}

protected function filteredTasks(): array
{
$tasks = $this->tasks;

if (!config('nova_blueprint.timestamps')) {
$tasks = array_filter($tasks, function ($key) {
return $key !== AddTimestampFields::class;
}, ARRAY_FILTER_USE_KEY);
}

return array_merge($tasks, [new RemapImports]);
}
}
26 changes: 11 additions & 15 deletions src/Tasks/AddIdentifierField.php
Expand Up @@ -2,41 +2,37 @@

namespace Naoray\BlueprintNovaAddon\Tasks;

use Blueprint\Models\Column;
use Blueprint\Models\Model;
use Closure;
use Blueprint\Models\Model;
use Illuminate\Support\Arr;
use Blueprint\Models\Column;
use Naoray\BlueprintNovaAddon\Contracts\Task;

class AddIdentifierField
class AddIdentifierField implements Task
{
use InteractWithRelationships;

const INDENT = ' ';

/** @var Model */
private $model;

public function handle($data, Closure $next): array
{
$this->model = $data['model'];

$column = $this->identifierColumn();
$column = $this->identifierColumn($data['model']);

$identifierName = $column->name() === 'id' ? '' : "'".$column->name()."'";
$data['fields'] .= 'ID::make('.$identifierName.')->sortable(),'.PHP_EOL.PHP_EOL;
$identifierName = $column->name() === 'id' ? '' : "'" . $column->name() . "'";
$data['fields'] .= 'ID::make(' . $identifierName . ')->sortable(),' . PHP_EOL . PHP_EOL;
$data['imports'][] = 'ID';

return $next($data);
}

private function identifierColumn(): Column
private function identifierColumn(Model $model): Column
{
$name = $this->relationshipIdentifiers($this->model->columns())
$name = $this->relationshipIdentifiers($model->columns())
->values()
// filter out all relationships
->diff(Arr::get($this->model->relationships(), 'belongsTo', []))
->diff(Arr::get($model->relationships(), 'belongsTo', []))
->first();

return $this->model->columns()[$name];
return $model->columns()[$name];
}
}

0 comments on commit 929feb6

Please sign in to comment.