From aaddd5e0e3b18caf5fd793fd312429c84c71b7e9 Mon Sep 17 00:00:00 2001 From: Daniel Weaver Date: Thu, 23 May 2024 14:35:51 -0400 Subject: [PATCH 1/2] Add only modifier --- src/Modifiers/CoreModifiers.php | 35 +++++ tests/Modifiers/OnlyTest.php | 270 ++++++++++++++++++++++++++++++++ 2 files changed, 305 insertions(+) create mode 100644 tests/Modifiers/OnlyTest.php diff --git a/src/Modifiers/CoreModifiers.php b/src/Modifiers/CoreModifiers.php index 36f9ff6bf0..8d419b8940 100644 --- a/src/Modifiers/CoreModifiers.php +++ b/src/Modifiers/CoreModifiers.php @@ -1754,6 +1754,41 @@ public function pluck($value, $params) return $wasArray ? $items->all() : $items; } + /** + * Gets certain values from a collection of items. + * + * @param array|Collection $value + * @param array $params + * @return array|Collection + */ + public function only($value, $params) + { + $keys = Arr::wrap($params); + + if ($wasArray = is_array($value)) { + $value = collect($value); + } + + if (Compare::isQueryBuilder($value)) { + $value = $value->get(); + } + + $items = $value->map(function ($item) use ($keys) { + return collect($keys)->mapWithKeys(function ($key) use ($item) { + $value = null; + if (is_array($item) || $item instanceof ArrayAccess) { + $value = Arr::get($item, $key); + } else { + $value = method_exists($item, 'value') ? $item->value($key) : $item->get($key); + } + + return [$key => $value]; + })->all(); + }); + + return $wasArray ? $items->all() : $items; + } + /** * Get the plural form of an English word with access to $context. * diff --git a/tests/Modifiers/OnlyTest.php b/tests/Modifiers/OnlyTest.php new file mode 100644 index 0000000000..5d30d89b5d --- /dev/null +++ b/tests/Modifiers/OnlyTest.php @@ -0,0 +1,270 @@ +items(); + + $modified = $this->modify($items, ['title', 'type']); + $this->assertIsArray($modified); + $this->assertEquals( + [ + ['title' => 'Bread', 'type' => 'food'], + ['title' => 'Coffee', 'type' => 'drink'], + ], + $modified, + ); + + $modified = $this->modify($items, ['title', 'stock']); + $this->assertIsArray($modified); + $this->assertEquals( + [ + ['title' => 'Bread', 'stock' => 1], + ['title' => 'Coffee', 'stock' => 2], + ], + $modified, + ); + } + + /** @test */ + public function it_gets_only_certain_values_from_collections_of_items() + { + $items = Collection::make($this->items()); + + $modified = $this->modify($items, ['title', 'type']); + $this->assertInstanceOf(Collection::class, $modified); + $this->assertEquals( + [ + ['title' => 'Bread', 'type' => 'food'], + ['title' => 'Coffee', 'type' => 'drink'], + ], + $modified->all(), + ); + + $modified = $this->modify($items, ['title', 'stock']); + $this->assertInstanceOf(Collection::class, $modified); + $this->assertEquals( + [ + ['title' => 'Bread', 'stock' => 1], + ['title' => 'Coffee', 'stock' => 2], + ], + $modified->all(), + ); + } + + /** @test */ + public function it_gets_only_certain_values_from_query_builder() + { + $builder = Mockery::mock(Builder::class); + $builder->shouldReceive('get')->andReturn(Collection::make($this->items())); + + $modified = $this->modify($builder, ['title', 'type']); + $this->assertInstanceOf(Collection::class, $modified); + $this->assertEquals( + [ + ['title' => 'Bread', 'type' => 'food'], + ['title' => 'Coffee', 'type' => 'drink'], + ], + $modified->all(), + ); + + $modified = $this->modify($builder, ['title', 'stock']); + $this->assertInstanceOf(Collection::class, $modified); + $this->assertEquals( + [ + ['title' => 'Bread', 'stock' => 1], + ['title' => 'Coffee', 'stock' => 2], + ], + $modified->all(), + ); + } + + /** @test */ + public function it_gets_only_certain_values_from_array_of_items_with_origins() + { + $items = $this->itemsWithOrigins(); + + $modified = $this->modify($items, ['title', 'type']); + $this->assertIsArray($modified); + $this->assertEquals( + [ + ['title' => 'Bread', 'type' => 'food'], + ['title' => 'Pan', 'type' => 'food'], + ['title' => 'Coffee', 'type' => 'drink'], + ['title' => 'Cafe', 'type' => 'drink'], + ], + $modified, + ); + + $modified = $this->modify($items, ['title', 'stock']); + $this->assertIsArray($modified); + $this->assertEquals( + [ + ['title' => 'Bread', 'stock' => 1], + ['title' => 'Pan', 'stock' => 1], + ['title' => 'Coffee', 'stock' => 2], + ['title' => 'Cafe', 'stock' => 2], + ], + $modified, + ); + } + + /** @test */ + public function it_gets_only_certain_values_from_collections_of_items_with_origins() + { + $items = EntryCollection::make($this->itemsWithOrigins()); + + $modified = $this->modify($items, ['title', 'type']); + $this->assertInstanceOf(EntryCollection::class, $modified); + $this->assertEquals( + [ + ['title' => 'Bread', 'type' => 'food'], + ['title' => 'Pan', 'type' => 'food'], + ['title' => 'Coffee', 'type' => 'drink'], + ['title' => 'Cafe', 'type' => 'drink'], + ], + $modified->all(), + ); + + $modified = $this->modify($items, ['title', 'stock']); + $this->assertInstanceOf(EntryCollection::class, $modified); + $this->assertEquals( + [ + ['title' => 'Bread', 'stock' => 1], + ['title' => 'Pan', 'stock' => 1], + ['title' => 'Coffee', 'stock' => 2], + ['title' => 'Cafe', 'stock' => 2], + ], + $modified->all(), + ); + } + + /** @test */ + public function it_gets_only_certain_values_from_array_of_items_of_type_array() + { + $items = $this->itemsOfTypeArray(); + + $modified = $this->modify($items, ['title', 'type']); + $this->assertIsArray($modified); + $this->assertEquals( + [ + ['title' => 'Bread', 'type' => 'food'], + ['title' => 'Coffee', 'type' => 'drink'], + ], + $modified, + ); + + $modified = $this->modify($items, ['title', 'stock']); + $this->assertIsArray($modified); + $this->assertEquals( + [ + ['title' => 'Bread', 'stock' => 1], + ['title' => 'Coffee', 'stock' => 2], + ], + $modified, + ); + } + + /** @test */ + public function it_gets_only_certain_values_from_collections_of_items_of_type_array() + { + $items = EntryCollection::make($this->itemsOfTypeArray()); + + $modified = $this->modify($items, ['title', 'type']); + $this->assertInstanceOf(EntryCollection::class, $modified); + $this->assertEquals( + [ + ['title' => 'Bread', 'type' => 'food'], + ['title' => 'Coffee', 'type' => 'drink'], + ], + $modified->all(), + ); + + $modified = $this->modify($items, ['title', 'stock']); + $this->assertInstanceOf(EntryCollection::class, $modified); + $this->assertEquals( + [ + ['title' => 'Bread', 'stock' => 1], + ['title' => 'Coffee', 'stock' => 2], + ], + $modified->all(), + ); + } + + /** @test */ + public function it_gets_only_certain_values_from_array_of_items_of_type_arrayaccess() + { + $items = $this->itemsOfTypeArrayAccess(); + + $modified = $this->modify($items, ['title', 'type']); + $this->assertIsArray($modified); + $this->assertEquals( + [ + ['title' => 'Bread', 'type' => 'food'], + ['title' => 'Coffee', 'type' => 'drink'], + ], + $modified, + ); + + $modified = $this->modify($items, ['title', 'stock']); + $this->assertIsArray($modified); + $this->assertEquals( + [ + ['title' => 'Bread', 'stock' => 1], + ['title' => 'Coffee', 'stock' => 2], + ], + $modified, + ); + } + + private function items() + { + return [ + new Item(['title' => 'Bread', 'type' => 'food', 'stock' => 1]), + new Item(['title' => 'Coffee', 'type' => 'drink', 'stock' => 2]), + ]; + } + + private function itemsWithOrigins() + { + return [ + $breadEn = new ItemWithOrigin(['title' => 'Bread', 'type' => 'food', 'stock' => 1]), + $breadEs = new ItemWithOrigin(['title' => 'Pan'], $breadEn), + $coffeeEn = new ItemWithOrigin(['title' => 'Coffee', 'type' => 'drink', 'stock' => 2]), + $coffeeEs = new ItemWithOrigin(['title' => 'Cafe'], $coffeeEn), + ]; + } + + private function itemsOfTypeArray() + { + return [ + ['title' => 'Bread', 'type' => 'food', 'stock' => 1], + ['title' => 'Coffee', 'type' => 'drink', 'stock' => 2], + ]; + } + + private function itemsOfTypeArrayAccess() + { + return [ + new ArrayAccessType(['title' => 'Bread', 'type' => 'food', 'stock' => 1]), + new ArrayAccessType(['title' => 'Coffee', 'type' => 'drink', 'stock' => 2]), + ]; + } + + private function modify($value, ...$keys) + { + return Modify::value($value)->only(Arr::flatten($keys))->fetch(); + } +} From 31ec02a7e43c8a4d6cb25875d01c1902c2e67e9e Mon Sep 17 00:00:00 2001 From: Daniel Weaver Date: Thu, 23 May 2024 15:41:12 -0400 Subject: [PATCH 2/2] Change modifier name to select --- src/Modifiers/CoreModifiers.php | 4 ++-- .../{OnlyTest.php => SelectTest.php} | 20 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) rename tests/Modifiers/{OnlyTest.php => SelectTest.php} (91%) diff --git a/src/Modifiers/CoreModifiers.php b/src/Modifiers/CoreModifiers.php index 8d419b8940..6de21c971c 100644 --- a/src/Modifiers/CoreModifiers.php +++ b/src/Modifiers/CoreModifiers.php @@ -1755,13 +1755,13 @@ public function pluck($value, $params) } /** - * Gets certain values from a collection of items. + * Selects certain values from each item in a collection. * * @param array|Collection $value * @param array $params * @return array|Collection */ - public function only($value, $params) + public function select($value, $params) { $keys = Arr::wrap($params); diff --git a/tests/Modifiers/OnlyTest.php b/tests/Modifiers/SelectTest.php similarity index 91% rename from tests/Modifiers/OnlyTest.php rename to tests/Modifiers/SelectTest.php index 5d30d89b5d..2a8b5cd58f 100644 --- a/tests/Modifiers/OnlyTest.php +++ b/tests/Modifiers/SelectTest.php @@ -10,10 +10,10 @@ use Statamic\Modifiers\Modify; use Tests\TestCase; -class OnlyTest extends TestCase +class SelectTest extends TestCase { /** @test */ - public function it_gets_only_certain_values_from_array_of_items() + public function it_selects_certain_values_from_array_of_items() { $items = $this->items(); @@ -39,7 +39,7 @@ public function it_gets_only_certain_values_from_array_of_items() } /** @test */ - public function it_gets_only_certain_values_from_collections_of_items() + public function it_selects_certain_values_from_collections_of_items() { $items = Collection::make($this->items()); @@ -65,7 +65,7 @@ public function it_gets_only_certain_values_from_collections_of_items() } /** @test */ - public function it_gets_only_certain_values_from_query_builder() + public function it_selects_certain_values_from_query_builder() { $builder = Mockery::mock(Builder::class); $builder->shouldReceive('get')->andReturn(Collection::make($this->items())); @@ -92,7 +92,7 @@ public function it_gets_only_certain_values_from_query_builder() } /** @test */ - public function it_gets_only_certain_values_from_array_of_items_with_origins() + public function it_selects_certain_values_from_array_of_items_with_origins() { $items = $this->itemsWithOrigins(); @@ -122,7 +122,7 @@ public function it_gets_only_certain_values_from_array_of_items_with_origins() } /** @test */ - public function it_gets_only_certain_values_from_collections_of_items_with_origins() + public function it_selects_certain_values_from_collections_of_items_with_origins() { $items = EntryCollection::make($this->itemsWithOrigins()); @@ -152,7 +152,7 @@ public function it_gets_only_certain_values_from_collections_of_items_with_origi } /** @test */ - public function it_gets_only_certain_values_from_array_of_items_of_type_array() + public function it_selects_certain_values_from_array_of_items_of_type_array() { $items = $this->itemsOfTypeArray(); @@ -178,7 +178,7 @@ public function it_gets_only_certain_values_from_array_of_items_of_type_array() } /** @test */ - public function it_gets_only_certain_values_from_collections_of_items_of_type_array() + public function it_selects_certain_values_from_collections_of_items_of_type_array() { $items = EntryCollection::make($this->itemsOfTypeArray()); @@ -204,7 +204,7 @@ public function it_gets_only_certain_values_from_collections_of_items_of_type_ar } /** @test */ - public function it_gets_only_certain_values_from_array_of_items_of_type_arrayaccess() + public function it_selects_certain_values_from_array_of_items_of_type_arrayaccess() { $items = $this->itemsOfTypeArrayAccess(); @@ -265,6 +265,6 @@ private function itemsOfTypeArrayAccess() private function modify($value, ...$keys) { - return Modify::value($value)->only(Arr::flatten($keys))->fetch(); + return Modify::value($value)->select(Arr::flatten($keys))->fetch(); } }