Laravel Nova — Single Responsibility Principle Approach

<?php

namespace App\Nova;

...

class Plugin extends \App\Nova\Resource
{
...

/**
* Get the fields displayed by the resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request)
{
return [
ID::make()->sortable(),

Text::make('Name')->rules([
'required',
Rule::unique(\App\Models\Plugin::class)->ignoreModel($this->resource)
]),

File::make('Attachment')
->rules(function () {
return [
'nullable',
'mimetypes:application/zip'
];
})
->store(function (Request $request) {
$fluent = new Fluent(config('plugin.filesystem'));
return [
'attachment' => $request->attachment
->store($fluent->directory, $fluent->disk)
];
}),
];
}

...
}
<?php

namespace App\Nova\Plugin;

...

class Resource extends \App\Nova\Resource
{
/**
* The model the resource corresponds to.
*
* @var string
*/
public static $model = \App\Models\Plugin::class;

/**
* The single value that should be used to represent the resource when being displayed.
*
* @var string
*/
public static $title = 'name';

/**
* The columns that should be searched.
*
* @var array
*/
public static $search = [
'id', 'name'
];

/**
* Get the fields displayed by the resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request)
{
return [
ID::make()->sortable(),

Text::make('Name')->rules(new RulesName($this->resource)),

File::make('Attachment')
->rules(new RulesAttachment)
->store(New StoreAttachment),
];
}
}
<?php

namespace App\Nova\Plugin;

use Illuminate\Http\Request;

class StoreAttachment
{
public function __invoke(Request $request)
{
$fluent = config('plugin.filesystem');

return [
'attachment' => $request->attachment
->store($fluent->directory, $fluent->disk)
];
}
}
<?php

namespace App\Nova;

use App\Support\Str;
use ReflectionClass;
use Laravel\Nova\Resource as NovaResource;
use Laravel\Nova\Http\Requests\NovaRequest;

abstract class Resource extends NovaResource
{
/**
* Get the displayable label of the resource.
*
* @return string
*/
public static function label()
{
$class = new ReflectionClass(get_called_class());

return Str::of($class->getNamespaceName())->classBasename()->snake()->title()->plural();
}

/**
* Get the URI key for the resource.
*
* @return string
*/
public static function uriKey()
{
return Str::plural(Str::kebab(class_basename(self::label())));
}
}
return Str::plural(Str::kebab(class_basename(self::label())));}...
}
<?php

namespace App\Providers;

...

class NovaServiceProvider extends NovaApplicationServiceProvider
{
...

/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
parent::boot();

Nova::mainMenu(fn () => [
...

MenuSection::make('Theming', [
MenuItem::resource(\App\Nova\Plugin\Resource::class),
])->icon('puzzle')->collapsable(),

...
]);
}


...
}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store