-
-
Notifications
You must be signed in to change notification settings - Fork 868
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(laravel): Eloquent filters search date or #6554
base: main
Are you sure you want to change the base?
feat(laravel): Eloquent filters search date or #6554
Conversation
NathanPesneau
commented
Aug 29, 2024
Q | A |
---|---|
Branch? | main |
License | MIT |
@@ -48,7 +48,7 @@ public function apply(Builder $builder, array $uriVariables, Operation $operatio | |||
continue; | |||
} | |||
|
|||
$filter = $this->filterLocator->has($filterId) ? $this->filterLocator->get($filterId) : null; | |||
$filter = $filterId instanceof FilterInterface ? $filterId : ($this->filterLocator->has($filterId) ? $this->filterLocator->get($filterId) : null); | |||
if ($filter instanceof FilterInterface) { | |||
$builder = $filter->apply($builder, $values, $parameter, $context); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$builder = $filter->apply($builder, $values, $parameter, $context); | |
$builder = $filter->apply($builder, $values, $parameter, ($parameter->getFilterContext() ?? []) + $context); |
} | ||
|
||
public function create(string $resourceClass): ResourceMetadataCollection | ||
{ | ||
$resourceMetadataCollection = $this->decorated?->create($resourceClass) ?? new ResourceMetadataCollection($resourceClass); | ||
|
||
$properties = array_flip(iterator_to_array($this->propertyNameCollectionFactory->create($resourceClass))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$properties = array_flip(iterator_to_array($this->propertyNameCollectionFactory->create($resourceClass))); | |
$propertyNameCollection = iterator_to_array($this->propertyNameCollectionFactory->create($resourceClass)); | |
$properties = array_flip($propertyNameCollection); |
@@ -61,18 +66,18 @@ public function create(string $resourceClass): ResourceMetadataCollection | |||
$parameters = $operation->getParameters() ?? new Parameters(); | |||
foreach ($parameters as $key => $parameter) { | |||
if (':property' === $key) { | |||
foreach ($this->propertyNameCollectionFactory->create($resourceClass) as $property) { | |||
$parameter = $this->setDefaults($property, $parameter, $resourceClass); | |||
foreach ($properties as $property) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
foreach ($properties as $property) { | |
foreach ($propertyNameCollection as $property) { |
@@ -61,18 +66,18 @@ public function create(string $resourceClass): ResourceMetadataCollection | |||
$parameters = $operation->getParameters() ?? new Parameters(); | |||
foreach ($parameters as $key => $parameter) { | |||
if (':property' === $key) { | |||
foreach ($this->propertyNameCollectionFactory->create($resourceClass) as $property) { | |||
$parameter = $this->setDefaults($property, $parameter, $resourceClass); | |||
foreach ($properties as $property) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dump maybe $property
to check its value
class Author extends Model | ||
{ | ||
use HasFactory; | ||
use IsApiResource; | ||
// use IsApiResource; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public function apiResource(): ApiResource
{
return new ApiResource(parameters: [new QueryParameter(key: ':property', filter: PartialSearchFilter::class)]);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#[QueryParameter(key: ':property', filter: SearchFilter::class)]
use IsApiResource
src/Laravel/ServiceLocator.php
Outdated
@@ -13,6 +13,7 @@ | |||
|
|||
namespace ApiPlatform\Laravel; | |||
|
|||
use ApiPlatform\Laravel\Eloquent\Filter\FilterInterface; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use ApiPlatform\Laravel\Eloquent\Filter\FilterInterface; |
return $builder; | ||
} | ||
|
||
// TODO: orderByRaw -> add protection against SQL injection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// TODO: orderByRaw -> add protection against SQL injection |
return $builder->whereDate($parameter->getProperty(), '>=', $datetime) | ||
->orWhereNull($parameter->getProperty()) | ||
->orderByRaw("{$parameter->getProperty()} ASC NULLS LAST"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use only 2 strategies: 'include_null', 'exclude_null' (defaults to exclude_null)
->where(function (Builder $query) {
$query->orWhere()
->orWhereNull();
})
SELECT * WHERE .... AND (date >= NOW() OR date IS NULL)
SELECT * WHERE .... AND (date >= NOW() AND date IS NOT NULL)
filterContext: ['nulls_comparison' => 'include_null_before_and_after'] | ||
)] | ||
#[QueryParameter(key: 'isbn_range', schema: ['type' => 'string'], filter: RangeFilter::class, property: 'isbn', description: 'Syntax: \<lt\>.\<valueToCompareTo\> You can use lt, gt, lte, gte or between (to do it, add: .\<value\> at the end)')] | ||
#[QueryParameter(key: 'order', schema: ['type' => 'string'], filter: OrderFilter::class, description: 'Syntax: \<propertyToOrderOn\>.\<asc|desc\>', filterContext: ['nulls_comparison' => 'nulls_smallest'])] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A garder:
#[QueryParameter(key: 'order[:property]', schema: ['type' => 'string'], filter: OrderFilter::class, description: 'Syntax: \<propertyToOrderOn\>.\<asc|desc\>'])]
order[name]=asc|desc
#[QueryParameter(key: 'order[name]', schema: ['type' => 'string'], filter: OrderFilter::class)]
order[name]=asc|desc
#[QueryParameter(key: 'name', schema: ['type' => 'string'], filter: OrderFilter::class, description: 'Syntax: \<propertyToOrderOn\>.\<asc|desc\>'])]
name=asc
property: 'publication_date', | ||
filterContext: ['nulls_comparison' => 'include_null_before_and_after'] | ||
)] | ||
#[QueryParameter(key: 'isbn_range', schema: ['type' => 'string'], filter: RangeFilter::class, property: 'isbn', description: 'Syntax: \<lt\>.\<valueToCompareTo\> You can use lt, gt, lte, gte or between (to do it, add: .\<value\> at the end)')] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isbn_range[lt]=2
03189ac
to
11e5b66
Compare
11e5b66
to
94691b2
Compare