diff --git a/CHANGELOG.md b/CHANGELOG.md index 35f2175..f9c9e3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to `laravel-cross-eloquent-search` will be documented in this file +## 1.9.0 - 2020-12-23 + +- Support for `addMany` and `andWhen` methods. + ## 1.8.0 - 2020-12-23 - Support for simple pagination (credit to @mewejo). diff --git a/README.md b/README.md index 3a9e8d2..49aed29 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,24 @@ Search::new() ->get('howto'); ``` +You can add multiple models at once by using the `addMany` method: + +```php +Search::addMany([ + [Post::class, 'title'], + [Video::class, 'title'], +])->get('howto'); +``` + +There's also an `addWhen` method, that adds the model when the first argument given to the method evaluates to `true`: + +```php +Search::new() + ->addWhen($user, Post::class, 'title') + ->addWhen($user->isAdmin(), Video::class, 'title') + ->get('howto'); +``` + ### Sorting If you want to sort the results by another column, you can pass that column to the `add` method as a third parameter. Call the `orderByDesc` method to sort the results in descending order. diff --git a/src/Searcher.php b/src/Searcher.php index 428b790..f572db7 100644 --- a/src/Searcher.php +++ b/src/Searcher.php @@ -140,6 +140,39 @@ public function add($query, $columns = null, string $orderByColumn = 'updated_at return $this; } + /** + * Apply the model if the value is truthy. + * + * @param mixed $value + * @param \Illuminate\Database\Eloquent\Builder|string $query + * @param string|array|\Illuminate\Support\Collection $columns + * @param string $orderByColumn + * @return self + */ + public function addWhen($value, $query, $columns = null, string $orderByColumn = 'updated_at'): self + { + if (!$value) { + return $this; + } + + return $this->add($query, $columns, $orderByColumn); + } + + /** + * Loop through the queries and add them. + * + * @param mixed $value + * @return self + */ + public function addMany($queries): self + { + Collection::make($queries)->each(function ($query) { + $this->add(...$query); + }); + + return $this; + } + /** * Set the 'orderBy' column of the latest added model. * diff --git a/tests/SearchTest.php b/tests/SearchTest.php index 8073b2b..98603ce 100644 --- a/tests/SearchTest.php +++ b/tests/SearchTest.php @@ -152,6 +152,40 @@ public function it_can_search_without_a_term() $this->assertCount(4, $results); } + /** @test */ + public function it_can_conditionally_add_queries() + { + $postA = Post::create(['title' => 'foo']); + Post::create(['title' => 'bar']); + Video::create(['title' => 'foo']); + Video::create(['title' => 'bar']); + + $results = Search::new() + ->addWhen(true, Post::class, 'title') + ->addWhen(false, Video::class, 'title', 'published_at') + ->get('foo'); + + $this->assertCount(1, $results); + $this->assertTrue($results->first()->is($postA)); + } + + /** @test */ + public function it_can_add_many_models_at_once() + { + $videoA = Video::create(['title' => 'foo']); + $videoB = Video::create(['title' => 'bar', 'subtitle' => 'foo']); + + $results = Search::addMany([ + [Video::class, 'title'], + [Video::class, 'subtitle', 'created_at'], + ])->get('foo'); + + $this->assertCount(2, $results); + + $this->assertTrue($results->contains($videoA)); + $this->assertTrue($results->contains($videoB)); + } + /** @test */ public function it_can_search_on_the_left_side_of_the_term() {