From 250864ff8e6d1506e81f2f2a2cc3a541d3b8ec6b Mon Sep 17 00:00:00 2001 From: carly Date: Thu, 15 Aug 2024 13:00:37 +0800 Subject: [PATCH] Can get attributes from field type config --- .../Configs/Contracts/FieldTypeConfig.php | 14 +++++ .../Configs/FieldTypeBaseConfig.php | 54 +++++++++++++++++++ src/FilamentFieldGroup.php | 51 +++++------------- 3 files changed, 82 insertions(+), 37 deletions(-) diff --git a/src/FieldTypes/Configs/Contracts/FieldTypeConfig.php b/src/FieldTypes/Configs/Contracts/FieldTypeConfig.php index a9bf68a..4acb7fd 100644 --- a/src/FieldTypes/Configs/Contracts/FieldTypeConfig.php +++ b/src/FieldTypes/Configs/Contracts/FieldTypeConfig.php @@ -15,4 +15,18 @@ public function getFormSchema(): array; * Apply the configuration to the component. */ public function applyConfig(Forms\Components\Component $component): void; + + /** + * Get the form components for the field type. + * + * @return array> + */ + public static function getFormComponents(): array; + + /** + * Get the configuration names for the field type. + * + * @return array> + */ + public static function getConfigNames(): array; } diff --git a/src/FieldTypes/Configs/FieldTypeBaseConfig.php b/src/FieldTypes/Configs/FieldTypeBaseConfig.php index 71d432d..7366ef7 100644 --- a/src/FieldTypes/Configs/FieldTypeBaseConfig.php +++ b/src/FieldTypes/Configs/FieldTypeBaseConfig.php @@ -3,7 +3,10 @@ namespace SolutionForest\FilamentFieldGroup\FieldTypes\Configs; use Filament\Forms; +use Illuminate\Support\Arr; use ReflectionClass; +use SolutionForest\FilamentFieldGroup\FieldTypes\Configs\Attributes\ConfigName; +use SolutionForest\FilamentFieldGroup\FieldTypes\Configs\Attributes\FormComponent; use SolutionForest\FilamentFieldGroup\FieldTypes\Configs\Contracts\FieldTypeConfig; abstract class FieldTypeBaseConfig implements Contracts\FieldTypeConfig @@ -60,6 +63,43 @@ protected static function fiComponentHasTrait($component, $trait): bool return false; } + /** @inheritDoc */ + public static function getFormComponents(): array + { + $attributes = static::findFieldConfigAttribute(static::class, FormComponent::class); + + $result = []; + + // Map the attributes to array + foreach ($attributes as $attribute) { + $attributeInstance = $attribute->newInstance(); + $result[] = [ + 'component' => $attributeInstance->fqcn, + ]; + } + + return $result; + } + + /** @inheritDoc */ + public static function getConfigNames(): array + { + $attributes = static::findFieldConfigAttribute(static::class, ConfigName::class); + + $result = []; + // Map the attributes to array + foreach ($attributes as $attribute) { + $attributeInstance = $attribute->newInstance(); + $result[] = [ + 'name' => $attributeInstance->name, + 'label' => $attributeInstance->label, + 'group' => $attributeInstance->group, + ]; + } + + return $result; + } + public function __toArray(): array { return get_object_vars($this); @@ -72,4 +112,18 @@ public function __toString(): string { return json_encode($this->__toArray()); } + + private static function findFieldConfigAttribute($objectOrFQCN, $attributeFQCN, ?\Closure $extraCheck = null) + { + $reflection = new ReflectionClass($objectOrFQCN); + + $attributes = $reflection->getAttributes(); + + return Arr::where($attributes, function ($attribute) use ($attributeFQCN, $extraCheck) { + $attributeInstance = $attribute->newInstance(); + + return $attribute->getName() === $attributeFQCN && + ($extraCheck ? $extraCheck($attributeInstance) : true); + }); + } } diff --git a/src/FilamentFieldGroup.php b/src/FilamentFieldGroup.php index e535a32..94987d7 100644 --- a/src/FilamentFieldGroup.php +++ b/src/FilamentFieldGroup.php @@ -5,8 +5,6 @@ use Filament\Forms; use Illuminate\Support\Arr; use ReflectionClass; -use SolutionForest\FilamentFieldGroup\FieldTypes\Configs\Attributes\ConfigName; -use SolutionForest\FilamentFieldGroup\FieldTypes\Configs\Attributes\FormComponent; use SolutionForest\FilamentFieldGroup\FieldTypes\Configs\Contracts\FieldTypeConfig; use SolutionForest\FilamentFieldGroup\Models\FieldGroup; @@ -20,18 +18,16 @@ public function getFieldTypeOptions(): array foreach ($fieldTypes as $fieldFQCN) { - $targetAttributes = $this->findFieldConfigAttribute($fieldFQCN, ConfigName::class); + $targetAttributes = Arr::first($fieldFQCN::getConfigNames()); - if (count($targetAttributes) === 0) { + if (count($targetAttributes) === 0 || ! $targetAttributes) { continue; } - $attributeInstance = $targetAttributes[0]->newInstance(); - $result[] = [ - 'name' => $attributeInstance->name, - 'display' => $attributeInstance->label, - 'group' => $attributeInstance->group, + 'name' => $targetAttributes['name'], + 'display' => $targetAttributes['label'], + 'group' => $targetAttributes['group'], ]; } @@ -62,13 +58,7 @@ public function getFieldTypeDisplayValue($name): ?string } // Get the display value from the attribute of the field type - $attributes = $this->findFieldConfigAttribute($fieldTypeConfig, ConfigName::class); - - if (count($attributes) === 0) { - return null; - } - - return $attributes[0]->newInstance()->label; + return data_get(Arr::first($fieldTypeConfig->getConfigNames()), 'label'); } /** @@ -103,19 +93,18 @@ public function findFieldGroup($name): ?Forms\Components\Component $schema = []; foreach ($fieldGroup->fields as $field) { + $fiFormConfig = $this->getFieldTypeConfig($field->type, $field->config); if (! $fiFormConfig) { continue; } - $fiFormComponentAttribute = Arr::first($this->findFieldConfigAttribute($fiFormConfig, FormComponent::class)); - if (! $fiFormComponentAttribute) { + $fiFormComponentFQCN = Arr::first(Arr::pluck($fiFormConfig->getFormComponents(), 'component')); + if (! $fiFormComponentFQCN) { throw new \Exception("The field type config class {$fiFormConfig} does not have a FormComponent attribute."); } - $fiFormComponentAttributeInstance = $fiFormComponentAttribute->newInstance(); - $fiFormComponentFQCN = $fiFormComponentAttributeInstance->fqcn; $fiFormComponent = $fiFormComponentFQCN::make($field->name); // @todo - some components may not have these methods @@ -136,15 +125,17 @@ public function findFieldGroup($name): ?Forms\Components\Component * Get the field type config by name. * * @param string $name + * + * @return FieldTypeConfig|null */ - public function getFieldTypeConfig($name, array | string $data = []): ?FieldTypeConfig + public function getFieldTypeConfig($name, array | string $data = []) { $fieldTypes = FilamentFieldGroupPlugin::get()->getFieldTypeConfigs(); foreach ($fieldTypes as $fieldFQCN) { - $targetAttributes = $this->findFieldConfigAttribute($fieldFQCN, ConfigName::class, function ($attributeInstance) use ($name) { - return $attributeInstance->name === $name; + $targetAttributes = Arr::where($fieldFQCN::getConfigNames(), function ($attribute) use ($name) { + return $attribute['name'] === $name; }); if (count($targetAttributes) > 0) { @@ -182,20 +173,6 @@ public function getFieldTypeConfig($name, array | string $data = []): ?FieldType return null; } - private function findFieldConfigAttribute($objectOrFQCN, $attributeFQCN, ?\Closure $extraCheck = null) - { - $reflection = new ReflectionClass($objectOrFQCN); - - $attributes = $reflection->getAttributes(); - - return Arr::where($attributes, function ($attribute) use ($attributeFQCN, $extraCheck) { - $attributeInstance = $attribute->newInstance(); - - return $attribute->getName() === $attributeFQCN && - ($extraCheck ? $extraCheck($attributeInstance) : true); - }); - } - private function fieldGroupModel() { return config('filament-field-group.models.field_group', FieldGroup::class);