diff --git a/src/Http/Controllers/Admin/DashboardController.php b/src/Http/Controllers/Admin/DashboardController.php index d6788c78b..2c4d60863 100644 --- a/src/Http/Controllers/Admin/DashboardController.php +++ b/src/Http/Controllers/Admin/DashboardController.php @@ -8,6 +8,7 @@ use Illuminate\Contracts\Auth\Factory as AuthFactory; use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\View\View; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -120,7 +121,11 @@ public function search(Request $request): Collection })->map(function ($module) use ($request) { $repository = $this->getRepository($module['name'], $module['repository'] ?? null); - $found = $repository->cmsSearch($request->get('search'), $module['search_fields'] ?? ['title'])->take(10); + $found = $repository->cmsSearch( + $request->get('search'), + $module['search_fields'] ?? ['title'], + isset($module['parentRelationship']) ? fn($q) => $q->whereHas($module['parentRelationship']) : null + )->take(10); return $found->map(function ($item) use ($module) { try { @@ -136,8 +141,11 @@ public function search(Request $request): Collection $date = $item->created_at->toIso8601String(); } - $parentRelationship = $module['parentRelationship'] ?? null; - $parent = $item->$parentRelationship; + if (isset($module['parentRelationship'])) { + /** @var BelongsTo $parent */ + $parent = call_user_func([$item, $module['parentRelationship']]); + $parent_id = $parent->getParentKey(); + } return [ 'id' => $item->id, @@ -145,7 +153,7 @@ public function search(Request $request): Collection $module['name'], $module['routePrefix'] ?? null, 'edit', - array_merge($parentRelationship ? [$parent->id] : [], [$item->id]) + array_filter([$parent_id ?? null, $item->id]) ), 'thumbnail' => method_exists($item, 'defaultCmsImage') ? $item->defaultCmsImage(['w' => 100, 'h' => 100]) : null, 'published' => $item->published, @@ -251,8 +259,16 @@ private function formatActivity(Activity $activity): ?array return null; } - $parentRelationship = $dashboardModule['parentRelationship'] ?? null; - $parent = $activity->subject->$parentRelationship; + if (isset($dashboardModule['parentRelationship'])) { + /** @var BelongsTo $parent */ + $parent = call_user_func([$activity->subject, $dashboardModule['parentRelationship']]); + $parent_id = $parent->getParentKey(); + + if (empty($parent_id)) { + // Prevent module route error + return null; + } + } // @todo: Improve readability of what is happening here. return [ @@ -269,7 +285,7 @@ private function formatActivity(Activity $activity): ?array $dashboardModule['name'], $dashboardModule['routePrefix'] ?? null, 'edit', - array_merge($parentRelationship ? [$parent->id] : [], [$activity->subject_id]) + array_filter([$parent_id ?? null, $activity->subject_id]) ), ] : []) + (! is_null($activity->subject->published) ? [ 'published' => $activity->description === 'published' ? true : ($activity->description === 'unpublished' ? false : $activity->subject->published), @@ -554,10 +570,15 @@ private function getDrafts(Collection $modules): Collection if ($repository->hasBehavior('revisions')) { $query->mine(); } - $parentRelationship = $module['parentRelationship'] ?? null; - return $query->get()->map(function ($draft) use ($module, $parentRelationship) { - $parent = $draft->$parentRelationship; + if (isset($module['parentRelationship'])) { + $query->whereHas($module['parentRelationship']); + } + + return $query->get()->map(function ($draft) use ($module) { + if (isset($module['parentRelationship'])) { + $parent_id = call_user_func([$draft, $module['parentRelationship']])->getParentKey(); + } return [ 'type' => ucfirst($module['label_singular'] ?? Str::singular($module['name'])), @@ -566,7 +587,7 @@ private function getDrafts(Collection $modules): Collection $module['name'], $module['routePrefix'] ?? null, 'edit', - array_merge($parentRelationship ? [$parent->id] : [], [$draft->id]) + array_filter([$parent_id ?? null, $draft->id]) ) ]; }); diff --git a/src/Repositories/ModuleRepository.php b/src/Repositories/ModuleRepository.php index 5ade539a3..5c8a1b375 100644 --- a/src/Repositories/ModuleRepository.php +++ b/src/Repositories/ModuleRepository.php @@ -15,6 +15,7 @@ use A17\Twill\Repositories\Behaviors\HandlePermissions; use A17\Twill\Repositories\Behaviors\HandleRelatedBrowsers; use A17\Twill\Repositories\Behaviors\HandleRepeaters; +use A17\Twill\Services\Listings\Filters\FreeTextSearch; use Exception; use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Illuminate\Database\Eloquent\Builder; @@ -152,19 +153,16 @@ public function listAll( return $query->get()->pluck($column, $pluckBy); } - public function cmsSearch(string $search, array $fields = []): Collection + public function cmsSearch(string $search, array $fields = [], callable $query = null): Collection { - $builder = $this->model->latest(); + $searchFilter = new FreeTextSearch(); + $searchFilter->queryString($search); + $searchFilter->searchColumns($fields); + $searchFilter->searchQuery($query); - $translatedAttributes = $this->model->getTranslatedAttributes() ?? []; + $builder = $this->model->latest(); - foreach ($fields as $field) { - if (in_array($field, $translatedAttributes, true)) { - $builder->orWhereTranslationLike($field, "%$search%"); - } else { - $builder->orWhere($field, getLikeOperator(), "%$search%"); - } - } + $searchFilter->applyFilter($builder); return $builder->get(); }