Skip to content

Commit

Permalink
Merge pull request simonhamp#28 from monaye/master
Browse files Browse the repository at this point in the history
Added importable resouce, importable attributes and custom importer
  • Loading branch information
simonhamp authored Jan 31, 2021
2 parents 127f94f + 458fbda commit 78b5198
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 32 deletions.
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,54 @@ class NovaServiceProvider extends NovaApplicationServiceProvider
}
```

## Options
By default, all of your Nova Resources will be available for import. However, there are a number of ways that you can explicitly limit what's available for importing.

`public static $canImportResource = false;`
*Default:* `true`
Add this static property to your Resource to prevent it from showing up in the Nova CSV Import tool interface.

`public static function canImportResource($request): bool`
Define a `canImportResource` method to use more complex logic to decide if this Resource can be shown during import. If defined, this takes precedence over the `$canImportResource` property.

`public static function excludeAttributesFromImport(): array`
*Default:* `[]`
Define a `excludeAttributesFromImport` method that returns an array of attribute names that you want to _exclude_ from being visible in the import tool for this Resource.


### Example

```php
// App\Nova\User
public static function canImportResource(Request $request)
{
return $request->user()->can("create", self::$model);
}

public static function excludeAttributesFromImport()
{
return ['password'];
}
```

## Importer Class
This package uses [maatwebsite/excel](https://github.com/Maatwebsite/Laravel-Excel) behind the scenes to handle the actual import. You can find more information about how importing [works here](https://docs.laravel-excel.com/3.1/imports/basics.html#importing-basics).

You can define your own importer class by providing the relevant class name in your published copy of this package's config file.

First, publish the config file:
```
php artisan vendor:publish --tag=nova-csv-import
```

Then, define and register your own importer class:
```
<?php
return [
'importer' => App\Utilities\Importer::class,
];
```
## Testing

We need tests! Can you help? Please consider contributing.
Expand Down
78 changes: 49 additions & 29 deletions src/Http/Controllers/ImportController.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ class ImportController

public function __construct()
{
$class = config('laravel-nova-csv-import.importer');

$class = config('nova-csv-importer.importer');
$this->importer = new $class;
}

Expand All @@ -37,46 +36,67 @@ public function preview(NovaRequest $request, $file)

$sample = $import->take(10)->all();

$resources = collect(Nova::$resources);

$resources = $resources->filter(function ($resource) {
if ($resource === ActionResource::class) {
return false;
}
$resources = $this->getAvailableResourcesForImport($request);

if (!isset($resource::$model)) {
return false;
}
$fields = $resources->mapWithKeys(function ($resource) use ($request) {
return $this->getAvailableFieldsForImport($resource, $request);
});

$static_vars = (new \ReflectionClass((string) $resource))->getStaticProperties();
$resources = $resources->mapWithKeys(function ($resource) {
return [$resource::uriKey() => $resource::label()];
});

if(!isset($static_vars['canImportResource'])) {
return true;
}
return response()->json(compact('sample', 'resources', 'fields', 'total_rows', 'headings'));
}

return isset($static_vars['canImportResource']) && $static_vars['canImportResource'];
});
public function getAvailableFieldsForImport(String $resource, $request)
{
$novaResource = new $resource(new $resource::$model);
$fieldsCollection = collect($novaResource->creationFields($request));

$fields = $resources->map(function ($resource) {
$model = $resource::$model;
if (method_exists($novaResource, 'excludeAttributesFromImport')) {
$fieldsCollection = $fieldsCollection->filter(function(Field $field) use ($novaResource, $request) {
return !in_array($field->attribute, $novaResource::excludeAttributesFromImport($request));
});
}

return new $resource(new $model);
})->mapWithKeys(function (Resource $resource) use ($request) {
$fields = collect($resource->creationFields($request))
->map(function (Field $field) {
$fields = $fieldsCollection->map(function (Field $field) {
return [
'name' => $field->name,
'attribute' => $field->attribute
];
});
return [$resource->uriKey() => $fields];
});

return [$novaResource->uriKey() => $fields];
}

$resources = $resources->mapWithKeys(function ($resource) {
return [$resource::uriKey() => $resource::label()];
});
public function getAvailableResourcesForImport(NovaRequest $request) {

return response()->json(compact('sample', 'resources', 'fields', 'total_rows', 'headings'));
$novaResources = collect(Nova::authorizedResources($request));

return $novaResources->filter(function ($resource) use ($request) {
if ($resource === ActionResource::class) {
return false;
}

if (!isset($resource::$model)) {
return false;
}

$resourceReflection = (new \ReflectionClass((string) $resource));

if ($resourceReflection->hasMethod('canImportResource')) {
return $resource::canImportResource($request);
}

$static_vars = $resourceReflection->getStaticProperties();

if (!isset($static_vars['canImportResource'])) {
return true;
}

return isset($static_vars['canImportResource']) && $static_vars['canImportResource'];
});
}

public function import(NovaRequest $request, $file)
Expand Down
8 changes: 5 additions & 3 deletions src/ToolServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,17 @@ public function boot()
{
$this->loadViewsFrom(__DIR__.'/../resources/views', 'laravel-nova-csv-import');

$this->mergeConfigFrom(__DIR__.'/config.php', 'laravel-nova-csv-import');

$this->app->booted(function () {
$this->routes();
});

Nova::serving(function (ServingNova $event) {

});

$this->publishes([
__DIR__.'/config.php' => config_path('nova-csv-importer.php')
], 'nova-csv-import');
}

/**
Expand All @@ -54,6 +56,6 @@ protected function routes()
*/
public function register()
{
//
$this->mergeConfigFrom(__DIR__.'/config.php', 'nova-csv-importer');
}
}

0 comments on commit 78b5198

Please sign in to comment.