Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 25 additions & 11 deletions src/Traits/SearchTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,19 +57,24 @@ public function paginate(): LengthAwarePaginator
*/
public function filterBy(string $field, ?string $filterName = null): self
{
if (empty($filterName)) {
if (Str::contains($field, '.')) {
list ($filterName) = extract_last_part($field);
} else {
$filterName = $field;
}
}
$filterName ??= $this->getFilterName($field);

if (Arr::has($this->filter, $filterName)) {
$values = Arr::wrap($this->filter[$filterName]);
$this->applyWhereCallback($this->query, $field, function (&$query, $conditionField) use ($filterName) {
$query->where($conditionField, $this->filter[$filterName]);
});
}

return $this;
}

public function filterByList(string $field, ?string $filterName = null): self
{
$filterName ??= $this->getFilterName($field);

$this->applyWhereCallback($this->query, $field, function (&$query, $conditionField) use ($values) {
$query->whereIn($conditionField, $values);
if (Arr::has($this->filter, $filterName)) {
$this->applyWhereCallback($this->query, $field, function (&$query, $conditionField) use ($filterName) {
$query->whereIn($conditionField, $this->filter[$filterName]);
});
}

Expand Down Expand Up @@ -145,7 +150,7 @@ public function searchQuery(array $filter = []): self
$this->filterTo($field, false, $fieldName);
} elseif (Str::endsWith($fieldName, '_in_list')) {
$field = Str::replace('_in_list', '', $fieldName);
$this->query->whereIn($field, $value);
$this->filterByList($field, $fieldName);
} else {
$this->filterBy($fieldName);
}
Expand Down Expand Up @@ -385,4 +390,13 @@ protected function postQueryHook(): void
$this->withCount([]);
}
}

protected function getFilterName(string $field): string
{
if (Str::contains($field, '.')) {
[$field] = extract_last_part($field);
}

return $field;
}
}
40 changes: 39 additions & 1 deletion tests/SearchTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,44 @@ public function testSearchQueryWithFilters()
->getSearchResults();
}

public function testSearchQueryWithNullFilters()
{
$this->mockSelectWithAggregate(
'select count(*) as aggregate from `test_models` where `user_id` is null and `test_models`.`deleted_at` is null'
);

$this->mockSelect(
'select * from `test_models` where `user_id` is null and `test_models`.`deleted_at` is null order by `id` asc limit 15 offset 0'
);

$this->testRepositoryClass
->searchQuery(['user_id' => null])
->getSearchResults();
}

public function testSearchQueryWithListFilters()
{
$this->setAdditionalReservedFiltersMethod->invokeArgs($this->testRepositoryClass, [
'user_id'
]);

$this->mockSelectWithAggregate(
'select count(*) as aggregate from `test_models` where `user_id` in (?, ?, ?) and `test_models`.`deleted_at` is null',
[1, 2, 3]
);

$this->mockSelect(
'select * from `test_models` where `user_id` in (?, ?, ?) and `test_models`.`deleted_at` is null order by `id` asc limit 15 offset 0',
[],
[1, 2, 3]
);

$this->testRepositoryClass
->searchQuery(['user_id' => [1, 2, 3]])
->filterByList('user_id')
->getSearchResults();
}

public function testSearchQueryWithFiltersFunctions()
{
$this->shouldSettablePropertiesBeResetProperty->setValue($this->testRepositoryClass, false);
Expand All @@ -273,4 +311,4 @@ public function testSearchQueryWithFiltersFunctions()
->filterLessThan('updated_at', Carbon::now())
->getSearchResults();
}
}
}
10 changes: 5 additions & 5 deletions tests/support/Traits/SqlMockTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ protected function mockGetSearchResultWithRelations(array $selectResult): void
. "where ((`query_field` like '%search_string%') or exists (select * from `relation_models` "
. "where `test_models`.`id` = `relation_models`.`test_model_id` "
. "and (`another_query_field` like '%search_string%'))) and exists (select * from `relation_models` "
. "where `test_models`.`id` = `relation_models`.`test_model_id` and `name` in (?)) "
. "where `test_models`.`id` = `relation_models`.`test_model_id` and `name` = ?) "
. "and `test_models`.`deleted_at` is null",
['some_value']
);
Expand All @@ -359,7 +359,7 @@ protected function mockGetSearchResultWithRelations(array $selectResult): void
. "where `test_models`.`id` = `relation_models`.`test_model_id` "
. "and (`another_query_field` like '%search_string%'))) and "
. "exists (select * from `relation_models` where `test_models`.`id` = `relation_models`.`test_model_id` "
. "and `name` in (?)) and `test_models`.`deleted_at` is null "
. "and `name` = ?) and `test_models`.`deleted_at` is null "
. "order by `relation_id` asc, `id` asc limit 15 offset 0",
$selectResult,
['some_value'],
Expand All @@ -370,7 +370,7 @@ protected function mockGetSearchResultWithFilters(array $selectResult): void
{
$this->mockSelectWithAggregate(
"select count(*) as aggregate from `test_models` where `user_id` in (?, ?) and `user_id` "
. "not in (?, ?) and `name` in (?) and `date` >= ? and `date` <= ? "
. "not in (?, ?) and `name` = ? and `date` >= ? and `date` <= ? "
. "and `created_at` >= ? and `created_at` <= ? and `updated_at` > ? "
. "and `updated_at` < ? and `test_models`.`deleted_at` is null",
[
Expand All @@ -390,7 +390,7 @@ protected function mockGetSearchResultWithFilters(array $selectResult): void

$this->mockSelect(
"select * from `test_models` where `user_id` in (?, ?) and `user_id` not in (?, ?) "
. "and `name` in (?) and `date` >= ? and `date` <= ? and `created_at` >= ? and `created_at` <= ? "
. "and `name` = ? and `date` >= ? and `date` <= ? and `created_at` >= ? and `created_at` <= ? "
. "and `updated_at` > ? and `updated_at` < ? and `test_models`.`deleted_at` is null "
. "order by `id` asc limit 15 offset 0",
$selectResult,
Expand Down Expand Up @@ -500,4 +500,4 @@ protected function getPdo(): SingleConnectionProxy

return $this->pdo;
}
}
}