Skip to content

Commit 138c661

Browse files
committed
Improve request management
1 parent 1c31a7b commit 138c661

7 files changed

Lines changed: 94 additions & 40 deletions

File tree

‎src/Exceptions/FilterException.php‎

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,39 @@ class FilterException extends LaramoreException
1919

2020
protected $errors;
2121

22-
public function __construct(Filter $filter, $errors, int $code=400)
22+
public function __construct(Filter|string $filter, $errors, int $code=400)
2323
{
2424
$this->filter = $filter;
2525
$this->errors = Arr::wrap($errors);
2626

27-
parent::__construct("Filter {$filter->getName()} excepted: ".implode('. ', $this->errors), $code);
27+
parent::__construct("Filter {$this->name()} excepted: ".implode('. ', $this->errors), $code);
2828
}
2929

3030
/**
3131
* Return the filter that threw the exception.
3232
*
33-
* @return Filter
33+
* @return Filter|string
3434
*/
35-
public function filter(): Filter
35+
public function filter(): Filter|string
3636
{
3737
return $this->filter;
3838
}
3939

40+
/**
41+
* Return the filter name that threw the exception.
42+
*
43+
* @return Filter|string
44+
*/
45+
public function name(): string
46+
{
47+
if ($this->filter instanceof Filter) {
48+
return $this->filter->getName();
49+
}
50+
51+
return $this->filter;
52+
}
53+
54+
4055
/**
4156
* Return the filter that threw the exception.
4257
*
@@ -45,7 +60,7 @@ public function filter(): Filter
4560
public function errors(): array
4661
{
4762
return [
48-
$this->filter->getName() => $this->errors,
63+
$this->name() => $this->errors,
4964
];
5065
}
5166
}

‎src/Http/Filters/BaseFilter.php‎

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Illuminate\Support\Facades\Event;
1515
use Illuminate\Support\Str;
1616
use Laramore\Contracts\Http\Filters\Filter;
17+
use Laramore\Exceptions\FilterException;
1718
use Laramore\Traits\{
1819
HasLockedMacros, HasProperties, IsLocked, IsOwned
1920
};
@@ -117,28 +118,35 @@ public function getName(): string
117118

118119
public function buildParams($params): Collection
119120
{
120-
$builtParams = collect();
121-
122-
if (!\is_array($params)) {
123-
$params = ['value' => $this->checkValue($params)];
121+
if (! \is_array($params)) {
122+
$params = ['value' => $params];
124123
}
125124

126125
$defaultParams = $this->getDefaultParams();
127-
$params = \array_merge($defaultParams, $params);
126+
$params = new Collection(\array_merge($defaultParams, $params));
128127

129-
foreach ($params as $subName => $subValue) {
130-
if (\method_exists($this, $method = 'check'.Str::studly($subName))) {
131-
$subValue = \call_user_func([$this, $method], $subValue, $params);
132-
}
128+
if (! $params->has('value')) {
129+
throw new FilterException($this, 'Missing value for filter');
130+
}
131+
132+
if (count($params) !== count($defaultParams)) {
133+
$keys = implode(', ', array_diff(array_keys($params->toArray()), array_keys($defaultParams)));
133134

134-
$builtParams->put($subName, $subValue);
135+
throw new FilterException($this, 'Some parameters are not allowed for this filter: '.$keys);
135136
}
136137

137-
if (!$builtParams->has('value')) {
138-
throw new \Exception('Missing value for filter !');
138+
// Follow keys and retrieve at execution the value.
139+
$keys = $params->keys();
140+
141+
foreach ($keys as $key) {
142+
if (\method_exists($this, $method = 'check'.Str::studly($key))) {
143+
$subValue = \call_user_func([$this, $method], $params->get($key), $params);
144+
}
145+
146+
$params->put($key, $subValue);
139147
}
140148

141-
return $builtParams;
149+
return $params;
142150
}
143151

144152
protected function locking()

‎src/Http/Filters/OrderBy.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public function getDefaultParams(): array
3636
];
3737
}
3838

39-
public function checkValue($value=null, array $params=[])
39+
public function checkValue($value=null, Collection $params=null)
4040
{
4141
if (\in_array($value, $this->allowedValues)) {
4242
if ($value === 'random' && !\is_null($params['field'])) {

‎src/Http/Filters/Page.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public function getDefaultParams(): array
2020
];
2121
}
2222

23-
public function checkValue($value=null)
23+
public function checkValue($value)
2424
{
2525
return (int) $value;
2626
}
Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/**
3-
* Filter to filter values on a specific field.
3+
* Filter values on a specific field.
44
* Ex: show only users with a specific father.
55
* Both father or father_id can be used (the composed field or the unique attribute).
66
*
@@ -17,11 +17,15 @@
1717

1818
use Illuminate\Support\Collection;
1919
use Laramore\Contracts\Eloquent\LaramoreBuilder;
20-
use Laramore\Contracts\Field\ComposedField;
20+
use Laramore\Contracts\Field\{
21+
Field, ComposedField,
22+
RelationField
23+
};
2124
use Laramore\Contracts\Http\Filters\BuilderFilter;
25+
use Laramore\Elements\OperatorElement;
2226
use Laramore\Traits\Http\Filters\HasOperatorParameter;
2327

24-
class Filter extends BaseFilter implements BuilderFilter
28+
class Related extends BaseFilter implements BuilderFilter
2529
{
2630
use HasOperatorParameter;
2731

@@ -35,7 +39,7 @@ public function getDefaultParams(): array
3539
];
3640
}
3741

38-
public function getField()
42+
public function getField(): Field
3943
{
4044
$this->needsToBeOwned();
4145

@@ -49,21 +53,37 @@ protected function owned()
4953
$meta = $this->getOwner()->getMeta();
5054

5155
$this->field = $meta->getField($this->getName());
56+
57+
if (! ($this->field instanceof RelationField)) {
58+
throw new \Exception("The field {$this->getName()} is not a relation field");
59+
}
5260
}
5361

54-
public function checkValue($value=null)
62+
public function checkValue($value=null, Collection $params=null)
5563
{
56-
// TODO.
57-
5864
if ($this->getField() instanceof ComposedField) {
59-
return explode(',', $value);
65+
if ($params->get('operator')->needs(OperatorElement::COLLECTION_TYPE)) {
66+
return $value->map(function ($subValue) {
67+
return new Collection(explode(',', $subValue));
68+
});
69+
}
70+
71+
return new Collection(explode(',', $value));
6072
}
6173

6274
return $value;
6375
}
6476

6577
public function filterBuilder(LaramoreBuilder $builder, Collection $params): ?LaramoreBuilder
6678
{
67-
return $this->getField()->where($builder, $params->get('operator'), $params->get('value'));
79+
$field = $this->getField();
80+
$operator = $params->get('operator');
81+
$method = $operator->getWhereMethod();
82+
83+
if (method_exists($field, $method) || $field::hasMacro($method)) {
84+
return \call_user_func([$field, $method], $builder, collect($params->get('value')));
85+
}
86+
87+
return $field->where($builder, $operator, $params->get('value'));
6888
}
6989
}

‎src/Traits/Http/Filters/HasOperatorParameter.php‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,28 @@
1010

1111
namespace Laramore\Traits\Http\Filters;
1212

13+
use Illuminate\Support\Collection;
1314
use Laramore\Elements\OperatorElement;
1415
use Laramore\Facades\Operator;
1516

1617
trait HasOperatorParameter
1718
{
1819
protected $operators;
1920

20-
public function checkOperator($operator=null): OperatorElement
21+
public function checkOperator($operator, Collection $params): OperatorElement
2122
{
2223
$operator = ($operator ?? '=');
2324

2425
if (\is_array($this->operators) && !\in_array($operator, $this->operators)) {
2526
throw new \Error("Wrong operator `$operator`");
2627
}
2728

28-
return Operator::find($operator);
29+
$opElement = Operator::find($operator);
30+
31+
if ($opElement->needs(OperatorElement::COLLECTION_TYPE)) {
32+
$params->put('value', collect($params->get('value')));
33+
}
34+
35+
return $opElement;
2936
}
3037
}

‎src/Traits/Http/Requests/HasLaramoreRelatedRequest.php‎

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
namespace Laramore\Traits\Http\Requests;
1212

1313
use Illuminate\Support\Str;
14+
use Laramore\Contracts\Field\ComposedField;
1415
use Laramore\Contracts\Field\RelationField;
1516

1617
trait HasLaramoreRelatedRequest
@@ -119,17 +120,20 @@ public function fields(): array
119120
$fields = parent::fields();
120121
$relatedField = $this->relatedField();
121122
$fieldsToRemove = [$relatedField->getName()];
122-
$decomposed = $relatedField->decompose();
123123

124-
if (isset($decomposed[$this->modelClass()])) {
125-
$fieldsToRemove = array_merge($fieldsToRemove, array_map(function ($field) {
126-
return $field->getName();
127-
}, $decomposed[$this->modelClass()]));
128-
}
124+
if ($relatedField instanceof ComposedField) {
125+
$decomposed = $relatedField->decompose();
126+
127+
if (isset($decomposed[$this->modelClass()])) {
128+
$fieldsToRemove = array_merge($fieldsToRemove, array_map(function ($field) {
129+
return $field->getName();
130+
}, $decomposed[$this->modelClass()]));
131+
}
129132

130-
foreach ($fieldsToRemove as $name) {
131-
if (($key = array_search($name, $fields)) !== false) {
132-
unset($fields[$key]);
133+
foreach ($fieldsToRemove as $name) {
134+
if (($key = array_search($name, $fields)) !== false) {
135+
unset($fields[$key]);
136+
}
133137
}
134138
}
135139

0 commit comments

Comments
 (0)