From dca4026f5da8b8f50351dd593e597ce839d465ed Mon Sep 17 00:00:00 2001 From: Lito Date: Wed, 9 Mar 2022 21:38:38 +0100 Subject: [PATCH 1/3] [9.x] Added callable support to operatorForWhere on Collection Added `callable` support to `operatorForWhere`. Currently only Collection methods `where` and `whereFirst` are used without `callable` support. Adding callable to `operatorForWhere` allow complex usages as: ```php $city = $cities->firstWhere(fn ($city) => $city->state->available && ($city->state->id === $stateId)); ``` or ```php $state = $states->firstWhere(fn ($state) => (bool)$state->cities->firstWhere('id', $cityId)); ``` --- src/Illuminate/Collections/Traits/EnumeratesValues.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Collections/Traits/EnumeratesValues.php b/src/Illuminate/Collections/Traits/EnumeratesValues.php index fec550211710..bf636c7ca790 100644 --- a/src/Illuminate/Collections/Traits/EnumeratesValues.php +++ b/src/Illuminate/Collections/Traits/EnumeratesValues.php @@ -311,7 +311,7 @@ public function every($key, $operator = null, $value = null) /** * Get the first item by the given key value pair. * - * @param string $key + * @param callable|string $key * @param mixed $operator * @param mixed $value * @return TValue|null @@ -548,7 +548,7 @@ public function unlessNotEmpty(callable $callback, callable $default = null) /** * Filter items by the given key value pair. * - * @param string $key + * @param callable|string $key * @param mixed $operator * @param mixed $value * @return static @@ -995,13 +995,17 @@ protected function getArrayableItems($items) /** * Get an operator checker callback. * - * @param string $key + * @param callable|string $key * @param string|null $operator * @param mixed $value * @return \Closure */ protected function operatorForWhere($key, $operator = null, $value = null) { + if (is_callable($key)) { + return $key; + } + if (func_num_args() === 1) { $value = true; From b848f18694106ee294ca51b2a1e3b41063214222 Mon Sep 17 00:00:00 2001 From: Lito Date: Wed, 9 Mar 2022 21:45:30 +0100 Subject: [PATCH 2/3] Added callable test to `where` and `firstWhere` collection methods --- tests/Support/SupportCollectionTest.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/Support/SupportCollectionTest.php b/tests/Support/SupportCollectionTest.php index f8263ed78010..1aafdd5b3daa 100755 --- a/tests/Support/SupportCollectionTest.php +++ b/tests/Support/SupportCollectionTest.php @@ -276,6 +276,11 @@ public function testFirstWhere($collection) $this->assertSame('gasket', $data->firstWhere('material', 'rubber')['type']); $this->assertNull($data->firstWhere('material', 'nonexistent')); $this->assertNull($data->firstWhere('nonexistent', 'key')); + + $this->assertSame('book', $data->firstWhere(fn ($value) => $value['material'] === 'papger')['type']); + $this->assertSame('gasket', $data->firstWhere(fn ($value) => $value['material'] === 'rubber')['type']); + $this->assertNull($data->firstWhere(fn ($value) => $value['material'] === 'nonexistent')); + $this->assertNull($data->firstWhere(fn ($value) => ($value['nonexistent'] ?? null) === 'key')); } /** @@ -1000,6 +1005,16 @@ public function testWhere($collection) $c->where('v', '>', $object)->values()->all() ); + $this->assertEquals( + [['v' => 3], ['v' => '3']], + $c->where(fn ($value) => $value['v'] == 3)->values()->all() + ); + + $this->assertEquals( + [['v' => 3]], + $c->where(fn ($value) => $value['v'] === 3)->values()->all() + ); + $c = new $collection([['v' => 1], ['v' => $object]]); $this->assertEquals( [['v' => $object]], From 82314e178f8c3dcbb5f3d40ea68b6b1712d76799 Mon Sep 17 00:00:00 2001 From: Lito Date: Wed, 9 Mar 2022 22:00:44 +0100 Subject: [PATCH 3/3] Fixed firstWhere callable test typo --- tests/Support/SupportCollectionTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Support/SupportCollectionTest.php b/tests/Support/SupportCollectionTest.php index 1aafdd5b3daa..1c49205f8fa5 100755 --- a/tests/Support/SupportCollectionTest.php +++ b/tests/Support/SupportCollectionTest.php @@ -277,7 +277,7 @@ public function testFirstWhere($collection) $this->assertNull($data->firstWhere('material', 'nonexistent')); $this->assertNull($data->firstWhere('nonexistent', 'key')); - $this->assertSame('book', $data->firstWhere(fn ($value) => $value['material'] === 'papger')['type']); + $this->assertSame('book', $data->firstWhere(fn ($value) => $value['material'] === 'paper')['type']); $this->assertSame('gasket', $data->firstWhere(fn ($value) => $value['material'] === 'rubber')['type']); $this->assertNull($data->firstWhere(fn ($value) => $value['material'] === 'nonexistent')); $this->assertNull($data->firstWhere(fn ($value) => ($value['nonexistent'] ?? null) === 'key'));