1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace NovaEntitySelectField\Http\Controllers; |
4
|
|
|
|
5
|
|
|
use Illuminate\Database\Eloquent\Model; |
6
|
|
|
use Illuminate\Support\Facades\Response; |
7
|
|
|
use Laravel\Nova\Http\Requests\NovaRequest; |
8
|
|
|
use Laravel\Nova\Nova; |
9
|
|
|
use Laravel\Nova\Resource; |
10
|
|
|
|
11
|
|
|
class AutocompleteController extends Controller |
12
|
|
|
{ |
13
|
6 |
|
public function __invoke(NovaRequest $request) |
14
|
|
|
{ |
15
|
6 |
|
$searchKeyword = $request->input('search'); |
16
|
|
|
// TODO: currently limit we pass via requests as we have not field by attribute |
17
|
6 |
|
$limit = $request->integer('limit') ?: 20; |
18
|
6 |
|
$currentEntityId = $request->input('current'); |
19
|
6 |
|
$entityResourceKey = $request->input('entityResourceKey'); |
20
|
6 |
|
$withTrashed = $request->boolean('withTrashed'); |
21
|
|
|
|
22
|
6 |
|
throw_if(!$entityResourceKey, __('entityResourceKey is required.')); |
23
|
|
|
|
24
|
|
|
/** @var class-string<Resource>|Resource $resourceClass */ |
25
|
6 |
|
$resourceClass = Nova::authorizedResources($request) |
26
|
6 |
|
->filter(fn ($resource) => $resource::uriKey() == $entityResourceKey) |
27
|
6 |
|
->first(); |
28
|
6 |
|
throw_if(!$resourceClass, __("Resource for key [{$entityResourceKey}] not found")); |
29
|
|
|
|
30
|
|
|
/** @var Model $model */ |
31
|
6 |
|
$model = $resourceClass::newModel(); |
32
|
6 |
|
$idColumn = $model->getKeyName(); |
33
|
6 |
|
$titleColumn = $resourceClass::$title; |
34
|
|
|
|
35
|
6 |
|
$builder = $resourceClass::buildIndexQuery($request, $model::query(), $searchKeyword, withTrashed: $withTrashed); |
36
|
|
|
|
37
|
6 |
|
$currentEntities = null; |
38
|
6 |
|
if ($currentEntityId) { |
39
|
3 |
|
$currentEntities = $model::query()->whereKey($currentEntityId)->get(); |
40
|
|
|
} |
41
|
|
|
|
42
|
6 |
|
$builder->limit($limit); |
43
|
|
|
|
44
|
6 |
|
$items = $builder->get(); |
45
|
|
|
|
46
|
6 |
|
if ($currentEntities?->isNotEmpty()) { |
47
|
3 |
|
foreach ($currentEntities as $currentEntity) { |
48
|
3 |
|
$items->prepend($currentEntity); |
49
|
|
|
} |
50
|
3 |
|
$items = $items->unique($idColumn); |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
|
54
|
6 |
|
return Response::json([ |
55
|
6 |
|
'resources' => |
56
|
6 |
|
$items->map(function (Model $row) use ($resourceClass, $idColumn, $titleColumn) { |
57
|
5 |
|
$resource = new $resourceClass($row); |
58
|
5 |
|
$avatar = $resource->resolveAvatarField(app(NovaRequest::class)); |
59
|
|
|
|
60
|
5 |
|
if (!is_null($avatar)) { |
61
|
5 |
|
$avatar = $avatar->resolveThumbnailUrl(); |
62
|
|
|
} |
63
|
|
|
|
64
|
5 |
|
return [ |
65
|
5 |
|
'value' => $row->$idColumn, |
66
|
5 |
|
'display' => $row->$titleColumn, |
67
|
5 |
|
'avatar' => $avatar ?: null, |
68
|
5 |
|
'subtitle' => $resource->subtitle(), |
69
|
5 |
|
]; |
70
|
6 |
|
})->all(), |
71
|
6 |
|
'withTrashed' => $withTrashed, |
72
|
6 |
|
]); |
73
|
|
|
} |
74
|
|
|
} |
75
|
|
|
|