Skip to content

Commit 3873795

Browse files
committed
wip
1 parent 381fe14 commit 3873795

File tree

4 files changed

+166
-3
lines changed

4 files changed

+166
-3
lines changed

src/Fields/Hidden.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
namespace Cone\Root\Fields;
66

77
use Closure;
8+
use Cone\Root\Filters\Filter;
9+
use Cone\Root\Filters\RenderableFilter;
10+
use Illuminate\Database\Eloquent\Builder;
11+
use Illuminate\Http\Request;
812

913
class Hidden extends Field
1014
{
@@ -22,4 +26,33 @@ public function __construct(string $label, Closure|string|null $modelAttribute =
2226

2327
$this->type('hidden');
2428
}
29+
30+
/**
31+
* Get the filter representation of the field.
32+
*/
33+
public function toFilter(): Filter
34+
{
35+
return new class($this) extends RenderableFilter
36+
{
37+
protected Hidden $field;
38+
39+
public function __construct(Hidden $field)
40+
{
41+
parent::__construct($field->getModelAttribute());
42+
43+
$this->field = $field;
44+
}
45+
46+
public function apply(Request $request, Builder $query, mixed $value): Builder
47+
{
48+
return $this->field->resolveFilterQuery($request, $query, $value);
49+
}
50+
51+
public function toField(): Hidden
52+
{
53+
return Hidden::make($this->field->getLabel(), $this->getRequestKey())
54+
->value(fn (Request $request): mixed => $this->getValue($request));
55+
}
56+
};
57+
}
2558
}

src/Fields/MorphOneOrMany.php

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,14 @@
44

55
namespace Cone\Root\Fields;
66

7+
use Closure;
8+
use Cone\Root\Fields\Select as SelectField;
9+
use Cone\Root\Filters\Select;
10+
use Illuminate\Database\Eloquent\Builder;
711
use Illuminate\Database\Eloquent\Model;
812
use Illuminate\Database\Eloquent\Relations\MorphOneOrMany as EloquentRelation;
13+
use Illuminate\Http\Request;
14+
use Illuminate\Support\Str;
915

1016
/**
1117
* @template TRelation of \Illuminate\Database\Eloquent\Relations\MorphOneOrMany
@@ -14,11 +20,133 @@
1420
*/
1521
abstract class MorphOneOrMany extends HasOneOrMany
1622
{
23+
/**
24+
* The morph types.
25+
*/
26+
protected array $types = [];
27+
1728
/**
1829
* {@inheritdoc}
1930
*/
2031
public function getRelation(Model $model): EloquentRelation
2132
{
2233
return parent::getRelation($model);
2334
}
35+
36+
/**
37+
* Get the morph types.
38+
*/
39+
public function getTypes(): array
40+
{
41+
return $this->types;
42+
}
43+
44+
/**
45+
* {@inheritdoc}
46+
*/
47+
public function getSearchableColumns(): array
48+
{
49+
return match (true) {
50+
array_is_list($this->searchableColumns) => array_fill_keys($this->types, $this->searchableColumns),
51+
default => $this->searchableColumns,
52+
};
53+
}
54+
55+
/**
56+
* Map the async searchable fields.
57+
*/
58+
protected function mapAsyncSearchableFields(Request $request): Fields
59+
{
60+
$fields = new Fields;
61+
62+
foreach ($this->getSearchableColumns() as $type => $columns) {
63+
foreach ($columns as $column) {
64+
$field = Hidden::make($this->getRelationName(), sprintf('%s:%s', $type, $column))
65+
->searchable(callback: function (Request $request, Builder $query, mixed $value, string $attribute): Builder {
66+
[$type, $column] = explode(':', $attribute);
67+
68+
return match ($query->getModel()::class) {
69+
$type => $query->where($query->qualifyColumn($column), 'like', "%{$value}%", 'or'),
70+
default => $query,
71+
};
72+
});
73+
74+
$fields->push($field);
75+
}
76+
}
77+
78+
return $fields;
79+
}
80+
81+
/**
82+
* {@inheritdoc}
83+
*/
84+
public function searchable(bool|Closure $value = true, ?Closure $callback = null, array $columns = ['id']): static
85+
{
86+
$columns = match (true) {
87+
array_is_list($columns) => array_fill_keys($this->getTypes(), $columns),
88+
default => $columns,
89+
};
90+
91+
return parent::searchable($value, $callback, $columns);
92+
}
93+
94+
/**
95+
* {@inheritdoc}
96+
*/
97+
public function filters(Request $request): array
98+
{
99+
$typeFilter = new class($this) extends Select
100+
{
101+
public function __construct(protected MorphOneOrMany $field)
102+
{
103+
parent::__construct('type');
104+
}
105+
106+
public function getName(): string
107+
{
108+
return __('Type');
109+
}
110+
111+
public function apply(Request $request, Builder $query, mixed $value): Builder
112+
{
113+
return $query;
114+
}
115+
116+
public function options(Request $request): array
117+
{
118+
return array_map(
119+
static function (string $type): string {
120+
return __(Str::of($type)->classBasename()->headline()->value());
121+
},
122+
array_combine($this->field->getTypes(), $this->field->getTypes())
123+
);
124+
}
125+
126+
public function toField(): SelectField
127+
{
128+
return parent::toField()
129+
->options(function (Request $request, Model $model): array {
130+
$related = $this->field->getRelation($model)->getRelated()::class;
131+
132+
return array_replace(
133+
$this->options($request),
134+
[$related => __(Str::of($related)->classBasename()->headline()->value())],
135+
);
136+
});
137+
}
138+
};
139+
140+
return array_merge([$typeFilter], parent::filters($request));
141+
}
142+
143+
/**
144+
* Set the morph types.
145+
*/
146+
public function types(array $types): static
147+
{
148+
$this->types = array_merge($this->types, $types);
149+
150+
return $this;
151+
}
24152
}

src/Fields/MorphTo.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ public function newOption(Model $related, string $label): Option
215215
*/
216216
public function types(array $types): static
217217
{
218-
$this->types = $types;
218+
$this->types = array_merge($this->types, $types);
219219

220220
return $this;
221221
}

src/Fields/Relation.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ public function getRouteParameterName(): string
229229
*/
230230
public function getModalKey(): string
231231
{
232-
return sprintf('relation-field-%s', $this->getModelAttribute());
232+
return sprintf('relation-field-%s', str_replace(['.', '->'], '-', $this->getModelAttribute()));
233233
}
234234

235235
/**
@@ -555,7 +555,9 @@ protected function resolveAction(Request $request, Action $action): void
555555
*/
556556
protected function resolveFilter(Request $request, Filter $filter): void
557557
{
558-
$filter->setKey(sprintf('%s_%s', $this->getRequestKey(), $filter->getKey()));
558+
$key = Str::afterLast($this->getRequestKey(), '.');
559+
560+
$filter->setKey(sprintf('%s_%s', $key, $filter->getKey()));
559561
}
560562

561563
/**

0 commit comments

Comments
 (0)