Skip to content

Commit

Permalink
Allow custom models
Browse files Browse the repository at this point in the history
  • Loading branch information
cklei-carly committed Sep 5, 2024
1 parent d9416f6 commit f795f54
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 209 deletions.
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,15 @@ This is the contents of the published config file:
```php
return [
'enabled' => false,
'models' => [
'field' => \SolutionForest\FilamentFieldGroup\Models\Field::class,
'field_group' => SolutionForest\FilamentFieldGroup\Models\FieldGroup::class,
],
'table_names' => [
'fields' => 'advanced_fields',
'field_groups' => 'advanced_field_groups',
],
];
```

## Usage
Expand Down Expand Up @@ -159,13 +162,15 @@ $panel

This section allows you to customize the model used for field groups in the Filament Field Group package. By replacing the default `FieldGroup` model with your own implementation, you can extend or modify its behavior to suit your application's needs.
To do this, use the `replace` method from the `ModelManifest` facade, specifying the original model and your custom model. Here's an example:
To do this, use the `setFieldGroupModelClass` or `setFieldModelClass` methods from the `FilamentFieldGroup` facade, specifying the original model and your custom model. Here's an example:

```php
\SolutionForest\FilamentFieldGroup\Facades\ModelManifest::replace(
\SolutionForest\FilamentFieldGroup\Models\Contracts\FieldGroup::class,
\SolutionForest\FilamentFieldGroup\Facades\FilamentFieldGroup::setFieldGroupModelClass(
Your\Models\FieldGroup::class
);
\SolutionForest\FilamentFieldGroup\Facades\FilamentFieldGroup::setFieldModelClass(
Your\Models\Field::class
);
```

## Testing
Expand Down
4 changes: 4 additions & 0 deletions config/filament-field-group.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
// config for SolutionForest/FilamentFieldGroup
return [
'enabled' => false,
'models' => [
'field' => \SolutionForest\FilamentFieldGroup\Models\Field::class,
'field_group' => SolutionForest\FilamentFieldGroup\Models\FieldGroup::class,
],
'table_names' => [
'fields' => 'advanced_fields',
'field_groups' => 'advanced_field_groups',
Expand Down
125 changes: 0 additions & 125 deletions src/Base/Manifests/ModelManifest.php

This file was deleted.

36 changes: 0 additions & 36 deletions src/Base/Manifests/ModelManifestInterface.php

This file was deleted.

25 changes: 0 additions & 25 deletions src/Facades/ModelManifest.php

This file was deleted.

118 changes: 118 additions & 0 deletions src/FilamentFieldGroup.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,70 @@
namespace SolutionForest\FilamentFieldGroup;

use Filament\Forms;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use ReflectionClass;
use SolutionForest\FilamentFieldGroup\FieldTypes\Configs\Contracts\FieldTypeConfig;
use SolutionForest\FilamentFieldGroup\Supports\FieldGroupConfig;

class FilamentFieldGroup
{
/**
* The collection of models to register.
*/
protected array $models = [];

public function registerModels(): void
{
$modelClasses = config('filament-field-group.models');

foreach ($modelClasses as $modelClass) {
$interfaceClass = $this->guessModelContractClass($modelClass);
$this->models[$interfaceClass] = $modelClass;
$this->bindModel($interfaceClass, $modelClass);
}
}

public function getFieldGroupModelClass(): string
{
$interfaceClass = \SolutionForest\FilamentFieldGroup\Models\Contracts\FieldGroup::class;

return $this->getModelClass($interfaceClass);
}

public function setFieldGroupModelClass($modelClass)
{
$interfaceClass = \SolutionForest\FilamentFieldGroup\Models\Contracts\FieldGroup::class;

$this->validateClassIsEloquentModel($modelClass);

config()->set('filament-field-group.models.field', $modelClass);

$this->models[$interfaceClass] = $modelClass;

$this->bindModel($interfaceClass, $modelClass);
}

public function getFieldModelClass(): string
{
$interfaceClass = \SolutionForest\FilamentFieldGroup\Models\Contracts\Field::class;

return $this->getModelClass($interfaceClass);
}

public function setFieldModelClass($modelClass): void
{
$interfaceClass = \SolutionForest\FilamentFieldGroup\Models\Contracts\Field::class;

$this->validateClassIsEloquentModel($modelClass);

config()->set('filament-field-group.models.field', $modelClass);

$this->models[$interfaceClass] = $modelClass;

$this->bindModel($interfaceClass, $modelClass);
}

public function getFieldTypeOptions(): array
{
$fieldTypes = FilamentFieldGroupPlugin::get()->getFieldTypeConfigs();
Expand Down Expand Up @@ -143,4 +200,65 @@ public function getFieldTypeConfig($name, array | string $data = [])

return null;
}

//region Helper methods
protected function replaceModelClass(string $interfaceClass, string $modelClass): void
{
switch ($interfaceClass)
{
case \SolutionForest\FilamentFieldGroup\Models\Contracts\FieldGroup::class:
$this->setFieldGroupModelClass($modelClass);
break;
case \SolutionForest\FilamentFieldGroup\Models\Contracts\Field::class:
$this->setFieldModelClass($modelClass);
break;
}
}

protected function getModelClass(string $interfaceClass, ?string $fallback = null): ?string
{
return $this->models[$interfaceClass] ?? $fallback;
}

/**
* Bind a model to the interface in the container.
*
* @param string $interfaceClass The interface class to bind.
* @param string $modelClass The model class to bind.
*/
protected function bindModel(string $interfaceClass, string $modelClass): void
{
app()->bind($interfaceClass, $modelClass);
}

/**
* Guess the contract class for a given model class.
*
* @param string $modelClass The model class to guess the contract for.
* @return string The guessed contract class name.
*/
protected function guessModelContractClass(string $modelClass): string
{
$class = new \ReflectionClass($modelClass);

$shortName = $class->getShortName();
$namespace = $class->getNamespaceName();

return "{$namespace}\\Contracts\\$shortName";
}

/**
* Validate that a class is an Eloquent model.
*
* @param string $class The class to validate.
*
* @throws \InvalidArgumentException If the class is not a subclass of Model.
*/
private function validateClassIsEloquentModel(string $class): void
{
if (! is_subclass_of($class, Model::class)) {
throw new \InvalidArgumentException(sprintf('Given [%s] is not a subclass of [%s].', $class, Model::class));
}
}
//endregion Helper methods
}
11 changes: 2 additions & 9 deletions src/FilamentFieldGroupServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
use Filament\Support\Facades\FilamentIcon;
use Illuminate\Filesystem\Filesystem;
use Livewire\Features\SupportTesting\Testable;
use SolutionForest\FilamentFieldGroup\Base\Manifests\ModelManifest;
use SolutionForest\FilamentFieldGroup\Base\Manifests\ModelManifestInterface;
use SolutionForest\FilamentFieldGroup\Testing\TestsFilamentFieldGroup;
use Spatie\LaravelPackageTools\Commands\InstallCommand;
use Spatie\LaravelPackageTools\Package;
Expand Down Expand Up @@ -56,15 +54,10 @@ public function configurePackage(Package $package): void
}
}

public function registeringPackage(): void
{
$this->app->singleton(ModelManifestInterface::class, fn () => $this->app->make(ModelManifest::class));

\SolutionForest\FilamentFieldGroup\Facades\ModelManifest::register();
}

public function packageBooted(): void
{
\SolutionForest\FilamentFieldGroup\Facades\FilamentFieldGroup::registerModels();

// Asset Registration
FilamentAsset::register(
$this->getAssets(),
Expand Down
Loading

0 comments on commit f795f54

Please sign in to comment.