Caved and moved to separate resources and models as some resources could not be model-based.

This commit is contained in:
Ryan Scherler
2020-11-07 22:48:56 -08:00
parent 1394923e01
commit 0a2aa2d857
12 changed files with 72 additions and 70 deletions
+7 -15
View File
@@ -37,28 +37,22 @@ class User extends Authenticatable
}
```
### Define a Resource
### Create a Resource
To define a Resource Model, add the `Filament\Traits\FilamentResource` trait to your model.
> Make note of the properties and methods added to the model example below for how to configure a resource.
To define a Resource, create a new resource file in `app/Filament/Resources` like the following `Page.php`:
```php
<?php
namespace App\Models;
namespace App\Filament\Resources;
use Illuminate\Database\Eloquent\Model;
use Filament\Traits\FilamentResource;
use Filament\FilamentResource;
use App\Http\Livewire\Pages\Index;
// use App\Http\Livewire\Pages\Show;
class Page extends Model
class Page extends FilamentResource
{
use FilamentResource;
protected $guarded = [];
public $label = 'Pages';
public $label = 'My Pages'; // defaults to pluralized classname
public $icon = 'heroicon-o-database';
public $sort = 0;
public $hideFromNav = false;
@@ -70,8 +64,6 @@ class Page extends Model
// 'show' => Show::class,
];
}
//...
}
```
+1 -1
View File
@@ -29,7 +29,7 @@ return [
'features' => [
Features::registration(),
Features::resourceModels()
Features::resources()
],
'models' => [
+4 -4
View File
@@ -4,7 +4,7 @@ use Illuminate\Support\Facades\Route;
use Filament\Features;
use Filament\Http\Controllers\{
AssetController,
ResourceModelController,
ResourceController,
};
// Assets
@@ -32,8 +32,8 @@ Route::group(['middleware' => ['auth']], function () {
// Dashboard
Route::get('/', config('filament.livewire.dashboard'))->name('dashboard');
// Resource Models
if (Features::hasResourceModels()) {
Route::get('/resources/{model}/{action?}/{id?}', ResourceModelController::class)->name('resource');
// Resources
if (Features::hasResources()) {
Route::get('/resources/{resource}/{action?}/{id?}', ResourceController::class)->name('resource');
}
});
+8
View File
@@ -0,0 +1,8 @@
<?php
namespace Filament\Contracts;
interface Resource
{
public function actions(): array;
}
+4 -4
View File
@@ -26,13 +26,13 @@ class Features
}
/**
* Determine if the application has resource models.
* Determine if the application has resources.
*
* @return bool
*/
public static function hasResourceModels()
public static function hasResources()
{
return static::enabled(static::resourceModels());
return static::enabled(static::resources());
}
/**
@@ -50,7 +50,7 @@ class Features
*
* @return string
*/
public static function resourceModels()
public static function resources()
{
return 'resourceModels';
}
+11 -13
View File
@@ -12,7 +12,7 @@ use Illuminate\Support\{
Collection,
HtmlString,
};
use Filament\Traits\FilamentResource;
use Filament\FilamentResource;
class Filament
{
@@ -142,27 +142,25 @@ class Filament
return $manifest[$key];
}
public function getResourceModels(): Collection
public function resources(): Collection
{
$app_path = config('filament.paths.models', app_path());
$models = collect(File::allFiles($app_path))
->map(function ($item) {
$resources_path = config('filament.resources', app_path('Filament/Resources'));
$models = collect(File::allFiles($resources_path))->map(function ($item) {
$path = $item->getRelativePathName();
$class = sprintf('\%s%s',
Container::getInstance()->getNamespace(),
strtr(substr($path, 0, strrpos($path, '.')), '/', '\\'));
$class = sprintf(
'\%s%s',
Container::getInstance()->getNamespace().'Filament\\Resources\\',
strtr(substr($path, 0, strrpos($path, '.')), '/', '\\')
);
return $class;
})
->filter(function ($class) {
})->filter(function ($class) {
if (!class_exists($class)) {
return false;
}
$reflection = new \ReflectionClass($class);
return $reflection->isSubclassOf(Model::class) &&
in_array(FilamentResource::class, class_uses_recursive($class)) &&
!$reflection->isAbstract();
return $reflection->isSubclassOf(FilamentResource::class) && !$reflection->isAbstract();
})->mapWithKeys(function ($class) {
return [class_basename($class) => $class];
});
+17
View File
@@ -0,0 +1,17 @@
<?php
namespace Filament;
use Filament\Contracts\Resource;
abstract class FilamentResource implements Resource
{
public $icon = 'heroicon-o-document-text';
public $sort = 0;
public $hideFromNav = false;
public function actions(): array
{
return [];
}
}
+13 -15
View File
@@ -36,9 +36,9 @@ class FilamentServiceProvider extends ServiceProvider
public function boot(): void
{
$this->bootModelBindings();
$this->bootResources();
$this->bootLoaders();
$this->bootDirectives();
$this->bootResourceModels();
$this->bootResources();
$this->bootCommands();
$this->bootPublishing();
}
@@ -82,7 +82,7 @@ class FilamentServiceProvider extends ServiceProvider
$this->app->bind('Filament\User', $models['user']);
}
protected function bootResources(): void
protected function bootLoaders(): void
{
$this->loadViewsFrom(__DIR__.'/../resources/views', 'filament');
$this->loadViewComponentsAs(config('filament.prefix.component', 'filament'), config('filament.components', []));
@@ -119,25 +119,23 @@ class FilamentServiceProvider extends ServiceProvider
], 'filament-assets');
}
protected function bootResourceModels(): void
protected function bootResources(): void
{
if (Features::hasResourceModels()) {
if (Features::hasResources()) {
$this->app->booted(function () {
$models = $this->app->filament->getResourceModels();
$models->each(function ($item, $key) {
$model = $this->app->make($item);
$this->app->filament->resources()->each(function ($item, $key) {
$resource = $this->app->make($item);
if (array_key_exists('index', $model->actions())) {
$route = route('filament.resource', ['model' => $key]);
if (array_key_exists('index', $resource->actions())) {
$route = route('filament.resource', ['resource' => $key]);
app(Navigation::class)->$key = [
'path' => $route,
'active' => $route.'*',
'label' => $model->label ?? Str::plural($key),
'icon' => $model->icon ?? 'heroicon-o-database',
'sort' => $model->sort ?? 0,
'hideFromNav' => $model->hideFromNav ?? false,
'label' => $resource->label ?? Str::plural($key),
'icon' => $resource->icon,
'sort' => $resource->sort,
'hideFromNav' => $resource->hideFromNav,
];
}
});
@@ -7,15 +7,15 @@ use Illuminate\Routing\Route;
use Illuminate\View\View;
use Filament;
class ResourceModelController extends Controller
class ResourceController extends Controller
{
public function __invoke(Container $container, Route $route, string $model, string $action = 'index'): View
public function __invoke(Container $container, Route $route, string $resource, string $action = 'index'): View
{
$model = Filament::getResourceModels()->get($model);
abort_unless($model, 404);
$resourceClass = Filament::resources()->get($resource);
abort_unless($resourceClass, 400, __("`$resource` is not a valid resource."));
$component = collect(app($model)->actions())->get($action);
abort_unless($component, 400, __("`$action` is not a valid resource action in `$model`"));
$component = collect(app($resourceClass)->actions())->get($action);
abort_unless($component, 400, __("`$action` is not a valid resource action in `$resourceClass`."));
return call_user_func((new $component), $container, $route);
}
-11
View File
@@ -1,11 +0,0 @@
<?php
namespace Filament\Traits;
trait FilamentResource
{
public function actions(): array
{
return [];
}
}
View File
+1 -1
View File
@@ -89,7 +89,7 @@ abstract class TestCase extends OrchestraTestCase
'prefix' => '',
]);
$app['config']->set('filament.paths.models', __DIR__.'/Database/Models');
$app['config']->set('filament.resources', __DIR__.'/Resources');
$app['config']->set('auth.providers.users.model', User::class);
$app['config']->set('filament.models.user', User::class);
}