diff --git a/src/Elements/Concerns/HasValue.php b/src/Elements/Concerns/HasValue.php index 779ecd1..810d6f2 100644 --- a/src/Elements/Concerns/HasValue.php +++ b/src/Elements/Concerns/HasValue.php @@ -2,6 +2,9 @@ namespace Galahad\Aire\Elements\Concerns; +use BackedEnum; +use UnitEnum; + trait HasValue { /** @@ -12,6 +15,12 @@ trait HasValue */ public function defaultValue($value): self { + if ($value instanceof BackedEnum) { + $value = $value->value; + } elseif ($value instanceof UnitEnum) { + $value = $value->name; + } + $this->attributes->setDefault('value', $value); return $this; diff --git a/src/Support/OptionsCollection.php b/src/Support/OptionsCollection.php index 1b0170a..f7b3ec1 100644 --- a/src/Support/OptionsCollection.php +++ b/src/Support/OptionsCollection.php @@ -2,8 +2,11 @@ namespace Galahad\Aire\Support; +use BackedEnum; use Galahad\Aire\Contracts\SelectableEntity; use Illuminate\Support\Collection; +use Illuminate\Support\Str; +use UnitEnum; class OptionsCollection extends Collection { @@ -21,11 +24,25 @@ public function getOptions(): array protected function getArrayableItems($items) { - if (is_string($items) && is_subclass_of($items, '\\BenSampo\\Enum\\Enum')) { - if (method_exists($items, 'asSelectArray')) { - $items = forward_static_call([$items, 'asSelectArray']); - } elseif (method_exists($items, 'toSelectArray')) { - $items = forward_static_call([$items, 'toSelectArray']); + if (is_string($items)) { + if (is_subclass_of($items, '\\BenSampo\\Enum\\Enum')) { + if (method_exists($items, 'asSelectArray')) { + $items = forward_static_call([$items, 'asSelectArray']); + } elseif (method_exists($items, 'toSelectArray')) { + $items = forward_static_call([$items, 'toSelectArray']); + } + } elseif (is_subclass_of($items, UnitEnum::class)) { + $items = collect($items::cases())->mapWithKeys(function(UnitEnum $case) { + $label = method_exists($case, 'description') + ? $case->description() + : Str::headline($case->name); + + if ($case instanceof BackedEnum) { + return [$case->value => $label]; + } + + return [$case->name => $label]; + }); } } diff --git a/tests/Unit/DataBindingTest.php b/tests/Unit/DataBindingTest.php index cdb5ae7..19e00d6 100644 --- a/tests/Unit/DataBindingTest.php +++ b/tests/Unit/DataBindingTest.php @@ -105,13 +105,15 @@ public function test_backed_enums_are_bound_propery(): void require_once __DIR__.'/enum-stubs.php'; - $model = new EnumModelStub(['name' => 'Chris']); + $model = new EnumModelStub(['name' => 'inxilpro']); + + $this->assertEquals(Names::ChrisMorrell, $model->name); $this->aire()->form()->bind($model); $input = $this->aire()->input('name'); - $this->assertSelectorAttribute($input, 'input', 'value', 'Chris'); + $this->assertSelectorAttribute($input, 'input', 'value', 'inxilpro'); } public function test_bound_data_with_square_brackets_is_supported(): void diff --git a/tests/Unit/SelectTest.php b/tests/Unit/SelectTest.php index 78d4b2b..0434a1a 100644 --- a/tests/Unit/SelectTest.php +++ b/tests/Unit/SelectTest.php @@ -125,6 +125,24 @@ public function test_an_enum_class_name_will_be_converted_to_a_selectable_array( $this->assertSelectorTextEquals($html, 'option[value="2"]', 'Ann Patchett'); $this->assertSelectorTextEquals($html, 'option[selected]', 'Ann Patchett'); } + + public function test_a_native_enum_is_supported(): void + { + if (version_compare(PHP_VERSION, '8.1.0', '<')) { + $this->markTestSkipped('Only applies to PHP 8.1 and higher.'); + } + + require_once __DIR__.'/enum-stubs.php'; + + $html = $this->aire() + ->select(Names::class) + ->defaultValue(Names::BogdanKharchenko) + ->render(); + + $this->assertSelectorTextEquals($html, 'option[value="inxilpro"]', 'Chris Morrell'); + $this->assertSelectorTextEquals($html, 'option[value="boggybot"]', 'Bogdan Kharchenko'); + $this->assertSelectorTextEquals($html, 'option[selected]', 'Bogdan Kharchenko'); + } } if (class_exists('BenSampo\Enum\Enum')) { diff --git a/tests/Unit/enum-stubs.php b/tests/Unit/enum-stubs.php index 899cac1..8956a84 100644 --- a/tests/Unit/enum-stubs.php +++ b/tests/Unit/enum-stubs.php @@ -15,7 +15,7 @@ class EnumModelStub extends Model enum Names: string { - case CM = 'Chris'; + case ChrisMorrell = 'inxilpro'; - case TE = 'Tim'; + case BogdanKharchenko = 'boggybot'; }