Skip to content

Commit 4507042

Browse files
committed
⚡ lazy nested field validation
1 parent b5966d9 commit 4507042

File tree

4 files changed

+65
-48
lines changed

4 files changed

+65
-48
lines changed

config/rest.php

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,6 @@
11
<?php
22

33
return [
4-
5-
/*
6-
|--------------------------------------------------------------------------
7-
| Filters
8-
|--------------------------------------------------------------------------
9-
|
10-
| Custom filters
11-
|
12-
*/
13-
14-
'filters' => [
15-
'max_depth' => 3,
16-
],
17-
184
/*
195
|--------------------------------------------------------------------------
206
| Rest Gates

src/Concerns/Resource/ConfiguresRestParameters.php

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
namespace Lomkit\Rest\Concerns\Resource;
44

5+
use Illuminate\Support\Facades\App;
6+
use Illuminate\Support\Str;
57
use Lomkit\Rest\Http\Requests\RestRequest;
8+
use Lomkit\Rest\Relations\Relation;
69

710
trait ConfiguresRestParameters
811
{
@@ -38,45 +41,26 @@ public function getFields(\Lomkit\Rest\Http\Requests\RestRequest $request): arra
3841
}
3942

4043
/**
41-
* Get nested fields by prefixing them with a given prefix.
44+
* Verify the field is correct including nested relations
4245
*
43-
* @param RestRequest $request
44-
* @param string $prefix
45-
* @param array $loadedRelations
46-
*
47-
* @return array
46+
* @param string $field
47+
* @return bool
4848
*/
49-
public function getNestedFields(RestRequest $request, int $maxDepth = 3, string $prefix = '', array $loadedRelations = [])
49+
public function isNestedField(string $field, Relation $relation = null)
5050
{
51-
if ($prefix !== '') {
52-
$prefix = $prefix.'.';
53-
}
51+
if (Str::contains($field ,'.')) {
52+
53+
// In case we are on a pivot we look for the relation pivot fields
54+
if (Str::before($field, '.') === 'pivot') {
55+
return method_exists($relation, 'getPivotFields') && in_array(Str::after($field, '.'), $relation->getPivotFields());
56+
}
57+
58+
$fieldRelation = $this->relation(Str::before($field, '.'));
5459

55-
$fields = array_map(
56-
function ($field) use ($prefix) {
57-
return $prefix.$field;
58-
},
59-
$this->getFields($request)
60-
);
61-
62-
foreach (
63-
collect($this->getRelations($request))
64-
->filter(function ($relation) use ($loadedRelations) {
65-
return !in_array($relation->relation, $loadedRelations);
66-
})
67-
as $relation
68-
) {
69-
$loadedRelations[] = $relation->relation;
70-
array_push(
71-
$fields,
72-
...($maxDepth > 0 ? $relation->resource()->getNestedFields($request, $maxDepth - 1, $prefix.$relation->relation, $loadedRelations) : []),
73-
// We push the pivot fields if they exists
74-
...collect(method_exists($relation, 'getPivotFields') ? $relation->getPivotFields() : [])
75-
->map(function ($field) use ($relation, $prefix) { return $prefix.$relation->relation.'.pivot.'.$field; })
76-
);
60+
return $fieldRelation->resource()->isNestedField(Str::after($field, '.'), $fieldRelation);
7761
}
7862

79-
return $fields;
63+
return in_array($field, $this->getFields(App::make(RestRequest::class)));
8064
}
8165

8266
/**

src/Rules/IsNestedField.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace Lomkit\Rest\Rules;
4+
5+
use Closure;
6+
use Illuminate\Contracts\Validation\ValidationRule;
7+
use Illuminate\Contracts\Validation\ValidatorAwareRule;
8+
use Illuminate\Validation\Validator;
9+
use Lomkit\Rest\Http\Requests\RestRequest;
10+
use Lomkit\Rest\Http\Resource;
11+
12+
class IsNestedField implements ValidationRule
13+
{
14+
/**
15+
* The validator instance.
16+
*
17+
* @var \Illuminate\Validation\Validator
18+
*/
19+
protected $validator;
20+
21+
/**
22+
* The resource instance.
23+
*
24+
* @var resource
25+
*/
26+
protected Resource $resource;
27+
28+
/**
29+
* The request instance.
30+
*
31+
* @var RestRequest
32+
*/
33+
protected RestRequest $request;
34+
35+
public function __construct(\Lomkit\Rest\Http\Resource $resource, RestRequest $request)
36+
{
37+
$this->resource = $resource;
38+
$this->request = $request;
39+
}
40+
41+
public function validate(string $attribute, mixed $value, Closure $fail): void
42+
{
43+
if (!$this->resource->isNestedField($value)) {
44+
$fail('The '.$attribute.' field is not valid.');
45+
}
46+
}
47+
}

src/Rules/SearchRules.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public function filtersRules(\Lomkit\Rest\Http\Resource $resource, string $prefi
111111
$rules = array_merge(
112112
[
113113
$prefix.'.*.field' => [
114-
Rule::in($resource->getNestedFields($this->request, config('rest.filters.max_depth'))),
114+
new IsNestedField($resource, $this->request),
115115
"required_without:$prefix.*.nested",
116116
'string',
117117
],

0 commit comments

Comments
 (0)