From 2809b5c9832d8a866dc948f3b8f9d95fe390c83b Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 6 Dec 2024 20:54:47 +0800 Subject: [PATCH 1/4] [11.x] Improves `Collection` support for enums using `firstWhere()` and `value()` Fixes #53676 Signed-off-by: Mior Muhammad Zaki --- .../Collections/Traits/EnumeratesValues.php | 11 +++++-- tests/Support/SupportCollectionTest.php | 29 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Collections/Traits/EnumeratesValues.php b/src/Illuminate/Collections/Traits/EnumeratesValues.php index 6d2c708b8fa8..010924f67633 100644 --- a/src/Illuminate/Collections/Traits/EnumeratesValues.php +++ b/src/Illuminate/Collections/Traits/EnumeratesValues.php @@ -19,6 +19,8 @@ use UnitEnum; use WeakMap; +use function Illuminate\Support\enum_value; + /** * @template TKey of array-key * @@ -1092,10 +1094,15 @@ protected function operatorForWhere($key, $operator = null, $value = null) } return function ($item) use ($key, $operator, $value) { - $retrieved = data_get($item, $key); + $retrieved = enum_value(data_get($item, $key)); + $value = enum_value($value); $strings = array_filter([$retrieved, $value], function ($value) { - return is_string($value) || (is_object($value) && method_exists($value, '__toString')); + return match (true) { + is_string($value) => true, + $value instanceof \Stringable => true, + default => false, + }; }); if (count($strings) < 2 && count(array_filter([$retrieved, $value], 'is_object')) == 1) { diff --git a/tests/Support/SupportCollectionTest.php b/tests/Support/SupportCollectionTest.php index ef0a5fd68f42..96f8e0742841 100755 --- a/tests/Support/SupportCollectionTest.php +++ b/tests/Support/SupportCollectionTest.php @@ -257,6 +257,20 @@ public function testFirstWhere($collection) $this->assertNull($data->firstWhere(fn ($value) => ($value['nonexistent'] ?? null) === 'key')); } + #[DataProvider('collectionClassProvider')] + public function testFirstWhereUsingEnum($collection) + { + $data = new $collection([ + ['id' => 1, 'name' => StaffEnum::Taylor], + ['id' => 2, 'name' => StaffEnum::Joe], + ['id' => 3, 'name' => StaffEnum::James], + ]); + + $this->assertSame(1, $data->firstWhere('name', 'Taylor')['id']); + $this->assertSame(2, $data->firstWhere('name', StaffEnum::Joe)['id']); + $this->assertSame(3, $data->firstWhere('name', StaffEnum::James)['id']); + } + #[DataProvider('collectionClassProvider')] public function testLastReturnsLastItemInCollection($collection) { @@ -1130,6 +1144,15 @@ public function testValue($collection) $this->assertEquals('bar', $c->where('id', 2)->value('pivot.value')); } + #[DataProvider('collectionClassProvider')] + public function testValueUsingEnum($collection) + { + $c = new $collection([['id' => 1, 'name' => StaffEnum::Taylor], ['id' => 2, 'name' => StaffEnum::Joe]]); + + $this->assertSame(StaffEnum::Taylor, $c->value('name')); + $this->assertEquals(StaffEnum::Joe, $c->where('id', 2)->value('name')); + } + #[DataProvider('collectionClassProvider')] public function testBetween($collection) { @@ -5737,3 +5760,9 @@ class TestCollectionSubclass extends Collection { // } + +enum StaffEnum { + case Taylor; + case Joe; + case James; +} From 4d22d2d047eeb132ef556326653ad7e618151b30 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Fri, 6 Dec 2024 12:56:18 +0000 Subject: [PATCH 2/4] Apply fixes from StyleCI --- tests/Support/SupportCollectionTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Support/SupportCollectionTest.php b/tests/Support/SupportCollectionTest.php index 96f8e0742841..ce97342a2326 100755 --- a/tests/Support/SupportCollectionTest.php +++ b/tests/Support/SupportCollectionTest.php @@ -5761,7 +5761,8 @@ class TestCollectionSubclass extends Collection // } -enum StaffEnum { +enum StaffEnum +{ case Taylor; case Joe; case James; From f939e3d01f3b51ea027a0d9030456c74342b2711 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 6 Dec 2024 21:03:44 +0800 Subject: [PATCH 3/4] wip Signed-off-by: Mior Muhammad Zaki --- src/Illuminate/Collections/composer.json | 1 + src/Illuminate/Collections/functions.php | 27 ++++++++++++++++++++++++ src/Illuminate/Support/functions.php | 24 --------------------- 3 files changed, 28 insertions(+), 24 deletions(-) create mode 100644 src/Illuminate/Collections/functions.php diff --git a/src/Illuminate/Collections/composer.json b/src/Illuminate/Collections/composer.json index 1924032ab915..b537407909ad 100644 --- a/src/Illuminate/Collections/composer.json +++ b/src/Illuminate/Collections/composer.json @@ -24,6 +24,7 @@ "Illuminate\\Support\\": "" }, "files": [ + "functions.php", "helpers.php" ] }, diff --git a/src/Illuminate/Collections/functions.php b/src/Illuminate/Collections/functions.php new file mode 100644 index 000000000000..08cd5ba0a6f7 --- /dev/null +++ b/src/Illuminate/Collections/functions.php @@ -0,0 +1,27 @@ + match (true) { + $value instanceof \BackedEnum => $value->value, + $value instanceof \UnitEnum => $value->name, + + default => $value, + }, $default ?? $value); + } +} diff --git a/src/Illuminate/Support/functions.php b/src/Illuminate/Support/functions.php index bcc8040cd876..3fc76f87151e 100644 --- a/src/Illuminate/Support/functions.php +++ b/src/Illuminate/Support/functions.php @@ -28,30 +28,6 @@ function defer(?callable $callback = null, ?string $name = null, bool $always = } } -if (! function_exists('Illuminate\Support\enum_value')) { - /** - * Return a scalar value for the given value that might be an enum. - * - * @internal - * - * @template TValue - * @template TDefault - * - * @param TValue $value - * @param TDefault|callable(TValue): TDefault $default - * @return ($value is empty ? TDefault : mixed) - */ - function enum_value($value, $default = null) - { - return transform($value, fn ($value) => match (true) { - $value instanceof \BackedEnum => $value->value, - $value instanceof \UnitEnum => $value->name, - - default => $value, - }, $default ?? $value); - } -} - if (! function_exists('Illuminate\Support\php_binary')) { /** * Determine the PHP Binary. From 1db7e1f4c99980ac96f891ceecf7a6e930b80145 Mon Sep 17 00:00:00 2001 From: Mior Muhammad Zaki Date: Fri, 6 Dec 2024 21:10:43 +0800 Subject: [PATCH 4/4] wip Signed-off-by: Mior Muhammad Zaki --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index ee8ee45920c5..eed626cef342 100644 --- a/composer.json +++ b/composer.json @@ -132,6 +132,7 @@ }, "autoload": { "files": [ + "src/Illuminate/Collections/functions.php", "src/Illuminate/Collections/helpers.php", "src/Illuminate/Events/functions.php", "src/Illuminate/Filesystem/functions.php",