Skip to content

Commit 6785649

Browse files
committed
fix: filtering timestamp fields by date only
1 parent 7fefd8f commit 6785649

File tree

3 files changed

+59
-8
lines changed

3 files changed

+59
-8
lines changed

src/Drivers/Standard/QueryBuilder.php

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,12 @@ function ($relationQuery) use ($relationField, $filterDescriptor) {
122122
);
123123
}
124124
} else {
125-
$this->buildFilterQueryWhereClause($this->getQualifiedFieldName($filterDescriptor['field']), $filterDescriptor, $query, $or);
125+
$this->buildFilterQueryWhereClause(
126+
$this->getQualifiedFieldName($filterDescriptor['field']),
127+
$filterDescriptor,
128+
$query,
129+
$or
130+
);
126131
}
127132
}
128133
}
@@ -138,8 +143,16 @@ function ($relationQuery) use ($relationField, $filterDescriptor) {
138143
*/
139144
protected function buildFilterQueryWhereClause(string $field, array $filterDescriptor, $query, bool $or = false)
140145
{
141-
if (!is_array($filterDescriptor['value'])) {
142-
$query->{$or ? 'orWhere' : 'where'}($field, $filterDescriptor['operator'], $filterDescriptor['value']);
146+
if ($filterDescriptor['value'] !== null &&
147+
in_array($filterDescriptor['field'], (new $this->resourceModelClass)->getDates(), true)
148+
) {
149+
$constraint = 'whereDate';
150+
} else {
151+
$constraint = 'where';
152+
}
153+
154+
if (!is_array($filterDescriptor['value']) || $constraint === 'whereDate') {
155+
$query->{$or ? 'or' . ucfirst($constraint) : $constraint}($field, $filterDescriptor['operator'], $filterDescriptor['value']);
143156
} else {
144157
$query->{$or ? 'orWhereIn' : 'whereIn'}($field, $filterDescriptor['value'], 'and', $filterDescriptor['operator'] === 'not in');
145158
}
@@ -156,8 +169,12 @@ protected function buildFilterQueryWhereClause(string $field, array $filterDescr
156169
* @param bool $or
157170
* @return Builder|Relation
158171
*/
159-
protected function buildPivotFilterQueryWhereClause(string $field, array $filterDescriptor, $query, bool $or = false)
160-
{
172+
protected function buildPivotFilterQueryWhereClause(
173+
string $field,
174+
array $filterDescriptor,
175+
$query,
176+
bool $or = false
177+
) {
161178
if (!is_array($filterDescriptor['value'])) {
162179
$query->{$or ? 'orWherePivot' : 'wherePivot'}($field, $filterDescriptor['operator'], $filterDescriptor['value']);
163180
} else {
@@ -212,11 +229,19 @@ function ($relationQuery) use ($relationField, $requestedSearchString) {
212229
/**
213230
* @var Builder $relationQuery
214231
*/
215-
return $relationQuery->where($relationField, 'like', '%'.$requestedSearchString.'%');
232+
return $relationQuery->where(
233+
$relationField,
234+
'like',
235+
'%' . $requestedSearchString . '%'
236+
);
216237
}
217238
);
218239
} else {
219-
$whereQuery->orWhere($this->getQualifiedFieldName($searchable), 'like', '%'.$requestedSearchString.'%');
240+
$whereQuery->orWhere(
241+
$this->getQualifiedFieldName($searchable),
242+
'like',
243+
'%' . $requestedSearchString . '%'
244+
);
220245
}
221246
}
222247
}
@@ -257,7 +282,9 @@ public function applySortingToQuery($query, Request $request): void
257282
}
258283

259284
$relationTable = $this->relationsResolver->relationTableFromRelationInstance($relationInstance);
260-
$relationForeignKey = $this->relationsResolver->relationForeignKeyFromRelationInstance($relationInstance);
285+
$relationForeignKey = $this->relationsResolver->relationForeignKeyFromRelationInstance(
286+
$relationInstance
287+
);
261288
$relationLocalKey = $this->relationsResolver->relationLocalKeyFromRelationInstance($relationInstance);
262289

263290
$query->leftJoin($relationTable, $relationForeignKey, '=', $relationLocalKey)

tests/Feature/StandardIndexFilteringOperationsTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,4 +418,27 @@ public function getting_a_list_of_resources_filtered_by_model_field_using_nullab
418418
$this->makePaginator([$matchingPost], 'posts/search')
419419
);
420420
}
421+
422+
/** @test */
423+
public function getting_a_list_of_resources_filtered_by_model_date_field(): void
424+
{
425+
$matchingPost = factory(Post::class)->create(['publish_at' => Carbon::parse('2019-01-05 13:30:00')])->fresh();
426+
factory(Post::class)->create(['publish_at' => Carbon::now()])->fresh();
427+
428+
Gate::policy(Post::class, GreenPolicy::class);
429+
430+
$response = $this->post(
431+
'/api/posts/search',
432+
[
433+
'filters' => [
434+
['field' => 'publish_at', 'operator' => '=', 'value' => '2019-01-05'],
435+
],
436+
]
437+
);
438+
439+
$this->assertResourcesPaginated(
440+
$response,
441+
$this->makePaginator([$matchingPost], 'posts/search')
442+
);
443+
}
421444
}

tests/Fixtures/app/Models/Post.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class Post extends Model
3636
* @var array
3737
*/
3838
protected $dates = [
39+
'publish_at',
3940
'deleted_at' //workaround for Laravel 5.7 - SoftDeletes trait adds deleted_at column to dates automatically since Laravel 5.8
4041
];
4142

0 commit comments

Comments
 (0)