Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e5a6490

Browse files
committedMar 28, 2024·
feat: initial work on filter validation
1 parent c91e448 commit e5a6490

16 files changed

+121
-50
lines changed
 

‎src/Contracts/Filter.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313

1414
use Illuminate\Database\Eloquent\Builder;
1515
use LaravelJsonApi\Contracts\Schema\Filter as BaseFilter;
16+
use LaravelJsonApi\Validation\Filters\IsValidated;
1617

17-
interface Filter extends BaseFilter
18+
interface Filter extends BaseFilter, IsValidated
1819
{
19-
2020
/**
2121
* Does the filter return a singular resource?
2222
*

‎src/Filters/Concerns/DeserializesValue.php

+14-7
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,26 @@
1616

1717
trait DeserializesValue
1818
{
19-
2019
/**
2120
* @var Closure|null
2221
*/
2322
private ?Closure $deserializer = null;
2423

24+
/**
25+
* @var bool
26+
*/
27+
private bool $asBool = false;
28+
2529
/**
2630
* Use the supplied callback to deserialize the value.
2731
*
2832
* @param Closure $deserializer
2933
* @return $this
3034
*/
31-
public function deserializeUsing(Closure $deserializer): self
35+
public function deserializeUsing(Closure $deserializer): static
3236
{
3337
$this->deserializer = $deserializer;
38+
$this->asBool = false;
3439

3540
return $this;
3641
}
@@ -40,11 +45,9 @@ public function deserializeUsing(Closure $deserializer): self
4045
*
4146
* @return $this
4247
*/
43-
public function asBoolean(): self
48+
public function asBoolean(): static
4449
{
45-
$this->deserializeUsing(
46-
static fn($value) => filter_var($value, FILTER_VALIDATE_BOOL)
47-
);
50+
$this->asBool = true;
4851

4952
return $this;
5053
}
@@ -55,8 +58,12 @@ public function asBoolean(): self
5558
* @param mixed $value
5659
* @return mixed
5760
*/
58-
protected function deserialize($value)
61+
protected function deserialize(mixed $value): mixed
5962
{
63+
if (true === $this->asBool) {
64+
return filter_var($value, FILTER_VALIDATE_BOOL);
65+
}
66+
6067
if ($this->deserializer) {
6168
return ($this->deserializer)($value);
6269
}

‎src/Filters/Concerns/HasDelimiter.php

+5-8
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
trait HasDelimiter
2121
{
22-
2322
/**
2423
* @var string|null
2524
*/
@@ -28,14 +27,12 @@ trait HasDelimiter
2827
/**
2928
* If the filter accepts a string value, the delimiter to use to extract values.
3029
*
31-
* @param string $delimiter
30+
* @param non-empty-string $delimiter
3231
* @return $this
3332
*/
34-
public function delimiter(string $delimiter): self
33+
public function delimiter(string $delimiter): static
3534
{
36-
if (empty($delimiter)) {
37-
throw new InvalidArgumentException('Expecting a non-empty string delimiter.');
38-
}
35+
assert(!empty($delimiter), 'Expecting a non-empty string delimiter.');
3936

4037
$this->delimiter = $delimiter;
4138

@@ -45,10 +42,10 @@ public function delimiter(string $delimiter): self
4542
/**
4643
* Convert the provided value to an array.
4744
*
48-
* @param string|array|null $value
45+
* @param mixed $value
4946
* @return array
5047
*/
51-
protected function toArray($value): array
48+
protected function toArray(mixed $value): array
5249
{
5350
if ($this->delimiter && is_string($value)) {
5451
return ('' !== $value) ? explode($this->delimiter, $value) : [];

‎src/Filters/Has.php

+16-3
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,31 @@
1111

1212
namespace LaravelJsonApi\Eloquent\Filters;
1313

14+
use Illuminate\Http\Request;
15+
use LaravelJsonApi\Core\Query\Input\Query;
1416
use LaravelJsonApi\Eloquent\Contracts\Filter;
1517
use LaravelJsonApi\Eloquent\Filters\Concerns\HasRelation;
1618
use LaravelJsonApi\Eloquent\Filters\Concerns\IsSingular;
1719
use LaravelJsonApi\Eloquent\Schema;
20+
use LaravelJsonApi\Validation\Filters\Validated;
21+
use LaravelJsonApi\Validation\Rules\JsonBoolean;
1822
use function filter_var;
1923

2024
class Has implements Filter
2125
{
2226
use HasRelation;
2327
use IsSingular;
28+
use Validated;
2429

2530
/**
2631
* Create a new filter.
2732
*
2833
* @param Schema $schema
2934
* @param string $fieldName
3035
* @param string|null $key
31-
* @return static
36+
* @return self
3237
*/
33-
public static function make(Schema $schema, string $fieldName, string $key = null)
38+
public static function make(Schema $schema, string $fieldName, string $key = null): self
3439
{
3540
return new static($schema, $fieldName, $key);
3641
}
@@ -64,13 +69,21 @@ public function apply($query, $value)
6469
return $query->doesntHave($relationName);
6570
}
6671

72+
/**
73+
* @inheritDoc
74+
*/
75+
public function validationRules(?Request $request, Query $query): array
76+
{
77+
return [(new JsonBoolean())->asString()];
78+
}
79+
6780
/**
6881
* Deserialize the value.
6982
*
7083
* @param mixed $value
7184
* @return bool
7285
*/
73-
protected function deserialize($value): bool
86+
protected function deserialize(mixed $value): bool
7487
{
7588
return filter_var($value, FILTER_VALIDATE_BOOL);
7689
}

‎src/Filters/OnlyTrashed.php

-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
class OnlyTrashed extends WithTrashed
1717
{
18-
1918
/**
2019
* @inheritDoc
2120
*/
@@ -31,5 +30,4 @@ public function apply($query, $value)
3130

3231
throw new LogicException("Filter {$this->key()} expects query builder to have a `withTrashed` method.");
3332
}
34-
3533
}

‎src/Filters/Scope.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@
1313

1414
use LaravelJsonApi\Core\Support\Str;
1515
use LaravelJsonApi\Eloquent\Contracts\Filter;
16+
use LaravelJsonApi\Eloquent\Filters\Concerns\DeserializesValue;
17+
use LaravelJsonApi\Eloquent\Filters\Concerns\IsSingular;
1618

1719
class Scope implements Filter
1820
{
19-
20-
use Concerns\DeserializesValue;
21-
use Concerns\IsSingular;
21+
use DeserializesValue;
22+
use IsSingular;
2223

2324
/**
2425
* @var string

‎src/Filters/Where.php

+23-5
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,20 @@
1313

1414
use LaravelJsonApi\Core\Support\Str;
1515
use LaravelJsonApi\Eloquent\Contracts\Filter;
16+
use LaravelJsonApi\Eloquent\Filters\Concerns\DeserializesValue;
17+
use LaravelJsonApi\Eloquent\Filters\Concerns\HasColumn;
18+
use LaravelJsonApi\Eloquent\Filters\Concerns\HasOperator;
19+
use LaravelJsonApi\Eloquent\Filters\Concerns\IsSingular;
20+
use LaravelJsonApi\Validation\Filters\ValidatedWithRules;
21+
use LaravelJsonApi\Validation\Rules\JsonBoolean;
1622

1723
class Where implements Filter
1824
{
19-
20-
use Concerns\DeserializesValue;
21-
use Concerns\HasColumn;
22-
use Concerns\HasOperator;
23-
use Concerns\IsSingular;
25+
use DeserializesValue;
26+
use HasColumn;
27+
use HasOperator;
28+
use IsSingular;
29+
use ValidatedWithRules;
2430

2531
/**
2632
* @var string
@@ -72,6 +78,18 @@ public function apply($query, $value)
7278
);
7379
}
7480

81+
/**
82+
* @return array<int, mixed>
83+
*/
84+
protected function defaultRules(): array
85+
{
86+
if ($this->asBool) {
87+
return [(new JsonBoolean())->asString()];
88+
}
89+
90+
return [];
91+
}
92+
7593
/**
7694
* @return string
7795
*/

‎src/Filters/WhereHas.php

+15-1
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,23 @@
1212
namespace LaravelJsonApi\Eloquent\Filters;
1313

1414
use Closure;
15+
use Illuminate\Http\Request;
16+
use LaravelJsonApi\Core\Query\Input\Query;
1517
use LaravelJsonApi\Eloquent\Contracts\Filter;
1618
use LaravelJsonApi\Eloquent\Filters\Concerns\DeserializesToArray;
1719
use LaravelJsonApi\Eloquent\Filters\Concerns\HasRelation;
1820
use LaravelJsonApi\Eloquent\Filters\Concerns\IsSingular;
1921
use LaravelJsonApi\Eloquent\QueryBuilder\Applicators\FilterApplicator;
2022
use LaravelJsonApi\Eloquent\Schema;
23+
use LaravelJsonApi\Validation\Filters\FilterRuleMap;
24+
use LaravelJsonApi\Validation\Filters\Validated;
2125

2226
class WhereHas implements Filter
2327
{
2428
use DeserializesToArray;
2529
use HasRelation;
2630
use IsSingular;
31+
use Validated;
2732

2833
/**
2934
* Create a new filter.
@@ -63,13 +68,22 @@ public function apply($query, $value)
6368
);
6469
}
6570

71+
/**
72+
* @inheritDoc
73+
*/
74+
public function validationRules(?Request $request, Query $query): array
75+
{
76+
return FilterRuleMap::make($this->schema->filters())
77+
->rules($request, $query);
78+
}
79+
6680
/**
6781
* Get the relation query callback.
6882
*
6983
* @param mixed $value
7084
* @return Closure
7185
*/
72-
protected function callback($value): Closure
86+
protected function callback(mixed $value): Closure
7387
{
7488
return function($query) use ($value) {
7589
$relation = $this->relation();

‎src/Filters/WhereIdIn.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
use LaravelJsonApi\Contracts\Schema\Schema;
1717
use LaravelJsonApi\Core\Schema\IdParser;
1818
use LaravelJsonApi\Eloquent\Contracts\Filter;
19+
use LaravelJsonApi\Eloquent\Filters\Concerns\HasDelimiter;
1920
use LaravelJsonApi\Eloquent\Schema as EloquentSchema;
2021

2122
class WhereIdIn implements Filter
2223
{
23-
24-
use Concerns\HasDelimiter;
24+
use HasDelimiter;
2525

2626
/**
2727
* @var ID

‎src/Filters/WhereIdNotIn.php

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
class WhereIdNotIn extends WhereIdIn
1515
{
16-
1716
/**
1817
* @inheritDoc
1918
*/

‎src/Filters/WhereIn.php

+7-5
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@
1313

1414
use LaravelJsonApi\Core\Support\Str;
1515
use LaravelJsonApi\Eloquent\Contracts\Filter;
16+
use LaravelJsonApi\Eloquent\Filters\Concerns\DeserializesValue;
17+
use LaravelJsonApi\Eloquent\Filters\Concerns\HasColumn;
18+
use LaravelJsonApi\Eloquent\Filters\Concerns\HasDelimiter;
1619

1720
class WhereIn implements Filter
1821
{
19-
20-
use Concerns\DeserializesValue;
21-
use Concerns\HasColumn;
22-
use Concerns\HasDelimiter;
22+
use DeserializesValue;
23+
use HasColumn;
24+
use HasDelimiter;
2325

2426
/**
2527
* @var string
@@ -78,7 +80,7 @@ public function apply($query, $value)
7880
}
7981

8082
/**
81-
* Deserialize the fitler value.
83+
* Deserialize the filter value.
8284
*
8385
* @param string|array $value
8486
* @return array

‎src/Filters/WhereNull.php

+18-3
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,20 @@
1111

1212
namespace LaravelJsonApi\Eloquent\Filters;
1313

14+
use Illuminate\Http\Request;
15+
use LaravelJsonApi\Core\Query\Input\Query;
1416
use LaravelJsonApi\Core\Support\Str;
1517
use LaravelJsonApi\Eloquent\Contracts\Filter;
18+
use LaravelJsonApi\Eloquent\Filters\Concerns\HasColumn;
19+
use LaravelJsonApi\Eloquent\Filters\Concerns\IsSingular;
20+
use LaravelJsonApi\Validation\Filters\Validated;
21+
use LaravelJsonApi\Validation\Rules\JsonBoolean;
1622

1723
class WhereNull implements Filter
1824
{
19-
use Concerns\HasColumn;
20-
use Concerns\IsSingular;
25+
use HasColumn;
26+
use IsSingular;
27+
use Validated;
2128

2229
/**
2330
* @var string
@@ -71,6 +78,14 @@ public function apply($query, $value)
7178
return $query->whereNotNull($column);
7279
}
7380

81+
/**
82+
* @inheritDoc
83+
*/
84+
public function validationRules(?Request $request, Query $query): array
85+
{
86+
return [(new JsonBoolean())->asString()];
87+
}
88+
7489
/**
7590
* Should a "where null" query be used?
7691
*
@@ -88,7 +103,7 @@ protected function isWhereNull(bool $value): bool
88103
* @param mixed $value
89104
* @return bool
90105
*/
91-
private function deserialize($value): bool
106+
private function deserialize(mixed $value): bool
92107
{
93108
return filter_var($value, FILTER_VALIDATE_BOOL);
94109
}

‎src/Filters/WherePivot.php

-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
class WherePivot extends Where
1717
{
18-
1918
/**
2019
* @inheritDoc
2120
*/
@@ -40,5 +39,4 @@ public function apply($query, $value)
4039
$this->deserialize($value)
4140
);
4241
}
43-
4442
}

‎src/Filters/WherePivotIn.php

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
class WherePivotIn extends WhereIn
1717
{
18-
1918
/**
2019
* @inheritDoc
2120
*/

‎src/Filters/WherePivotNotIn.php

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
class WherePivotNotIn extends WhereIn
1717
{
18-
1918
/**
2019
* @inheritDoc
2120
*/

‎src/Filters/WithTrashed.php

+15-4
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,17 @@
1111

1212
namespace LaravelJsonApi\Eloquent\Filters;
1313

14+
use Illuminate\Http\Request;
15+
use LaravelJsonApi\Core\Query\Input\Query;
1416
use LaravelJsonApi\Eloquent\Contracts\Filter;
17+
use LaravelJsonApi\Validation\Filters\Validated;
18+
use LaravelJsonApi\Validation\Rules\JsonBoolean;
1519
use LogicException;
1620
use function filter_var;
1721

1822
class WithTrashed implements Filter
1923
{
24+
use Validated;
2025

2126
/**
2227
* @var string
@@ -75,13 +80,19 @@ public function key(): string
7580
}
7681

7782
/**
78-
* @param $value
83+
* @inheritDoc
84+
*/
85+
public function validationRules(?Request $request, Query $query): array
86+
{
87+
return [(new JsonBoolean())->asString()];
88+
}
89+
90+
/**
91+
* @param mixed $value
7992
* @return bool
8093
*/
81-
protected function deserialize($value): bool
94+
protected function deserialize(mixed $value): bool
8295
{
8396
return filter_var($value, FILTER_VALIDATE_BOOL);
8497
}
85-
86-
8798
}

0 commit comments

Comments
 (0)
Please sign in to comment.