diff --git a/.github/workflows/coveralls.yml b/.github/workflows/coveralls.yml index 6941f66..9174801 100644 --- a/.github/workflows/coveralls.yml +++ b/.github/workflows/coveralls.yml @@ -42,7 +42,7 @@ jobs: uses: "ramsey/composer-install@v1" with: dependency-versions: "${{ matrix.dependencies }}" - composer-options: "--prefer-dist" + composer-options: "--prefer-dist --no-cache" - name: Execute tests run: vendor/bin/phpunit --coverage-clover build/logs/clover.xml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index dcb5b52..67b1e40 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -49,7 +49,7 @@ jobs: uses: "ramsey/composer-install@v1" with: dependency-versions: "${{ matrix.dependencies }}" - composer-options: "--prefer-dist" + composer-options: "--prefer-dist --no-cache" - name: Execute tests run: vendor/bin/phpunit diff --git a/src/Concerns/ConditionallySearchingWildcard.php b/src/Concerns/ConditionallySearchingWildcard.php index 0f808cb..3b430f0 100644 --- a/src/Concerns/ConditionallySearchingWildcard.php +++ b/src/Concerns/ConditionallySearchingWildcard.php @@ -11,6 +11,27 @@ trait ConditionallySearchingWildcard */ public $wildcardSearching = null; + /** + * Widlcard search variants. + * + * @var array|null + */ + public $wildcardSearchVariants = null; + + /** + * Set wildcard search variants. + * + * @param array $searchVariants + * + * @return $this + */ + public function wildcardSearchVariants(?array $searchVariants) + { + $this->wildcardSearchVariants = $searchVariants; + + return $this; + } + /** * Set wildcard searching status. * diff --git a/src/Keyword.php b/src/Keyword.php index 6dcbde1..b8829c9 100644 --- a/src/Keyword.php +++ b/src/Keyword.php @@ -60,7 +60,8 @@ public function all(): array $this->value, $this->wildcardCharacter, $this->wildcardReplacement, - $this->wildcardSearching ?? true + $this->wildcardSearching ?? true, + $this->wildcardSearchVariants ?? null ); } @@ -94,8 +95,13 @@ public function __toString() /** * Convert basic string to searchable result. */ - public static function searchable(string $text, ?string $wildcard = '*', ?string $replacement = '%', bool $wildcardSearching = true): array - { + public static function searchable( + string $text, + ?string $wildcard = '*', + ?string $replacement = '%', + bool $wildcardSearching = true, + ?array $wildcardSearchVariants = null + ): array { $text = static::sanitize($text); if (empty($text)) { @@ -103,7 +109,7 @@ public static function searchable(string $text, ?string $wildcard = '*', ?string } elseif (\is_null($replacement)) { return [$text]; } elseif (! Str::contains($text, array_filter([$wildcard, $replacement])) && $wildcardSearching === true) { - return Collection::make(static::$defaultSearchVariations) + return Collection::make($wildcardSearchVariants ?? static::$defaultSearchVariations) ->map(static function ($string) use ($text) { return Str::replaceFirst('{keyword}', $text, $string); })->all(); diff --git a/src/Searchable.php b/src/Searchable.php index 309e58d..b42caed 100644 --- a/src/Searchable.php +++ b/src/Searchable.php @@ -60,6 +60,7 @@ public function apply($query) $keywords->wildcardCharacter($this->wildcardCharacter) ->wildcardReplacement($this->wildcardReplacement) + ->wildcardSearchVariants($this->wildcardSearchVariants) ->wildcardSearching($this->wildcardSearching ?? true); $likeOperator = like_operator(connection_type($query)); @@ -130,6 +131,7 @@ protected function queryOnColumnUsing( $this->searchKeyword() ->wildcardCharacter($this->wildcardCharacter) ->wildcardReplacement($this->wildcardReplacement) + ->wildcardSearchVariants($this->wildcardSearchVariants) ->wildcardSearching($field->wildcardSearching ?? $this->wildcardSearching ?? true) ->handle($filter), $likeOperator, @@ -159,6 +161,7 @@ protected function queryOnJsonColumnUsing( $this->searchKeyword() ->wildcardCharacter($this->wildcardCharacter) ->wildcardReplacement($this->wildcardReplacement) + ->wildcardSearchVariants($this->wildcardSearchVariants) ->wildcardSearching($field->wildcardSearching ?? $this->wildcardSearching ?? true) ->handle($filter), $likeOperator, @@ -183,6 +186,7 @@ protected function queryOnColumnUsingRelation( $this->searchKeyword() ->wildcardCharacter($this->wildcardCharacter) ->wildcardReplacement($this->wildcardReplacement) + ->wildcardSearchVariants($this->wildcardSearchVariants) ->wildcardSearching($field->wildcardSearching ?? $this->wildcardSearching ?? true) ->handle($filter), $likeOperator, diff --git a/tests/Feature/EloquentSearchableTest.php b/tests/Feature/EloquentSearchableTest.php index 6d1f69d..7327a8f 100644 --- a/tests/Feature/EloquentSearchableTest.php +++ b/tests/Feature/EloquentSearchableTest.php @@ -43,6 +43,37 @@ public function it_can_build_search_query() $this->assertSame(5, $query->count()); } + /** @test */ + public function it_can_build_search_query_with_custom_search_variants() + { + UserFactory::new()->times(5)->create([ + 'name' => 'hello world', + ]); + + UserFactory::new()->times(3)->create([ + 'name' => 'goodbye world', + ]); + + $stub = (new Searchable( + 'hello', ['name'] + ))->wildcardSearchVariants(['%{keyword}%']); + + $query = User::query(); + $stub->apply($query); + + $this->assertSame( + 'select * from "users" where ("users"."name" like ?)', + $query->toSql() + ); + + $this->assertSame( + ['%hello%'], + $query->getBindings() + ); + + $this->assertSame(5, $query->count()); + } + /** @test */ public function it_can_build_search_query_with_combined_with_search_filters() {