migrants-nt-sec/app/Http/Controllers/HistoricalSearchController.php

104 lines
3.0 KiB
PHP

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use ProtoneMedia\LaravelCrossEloquentSearch\Search;
use App\Models\Person;
use App\Models\Migration;
use App\Models\Residence;
use Exception;
class HistoricalSearchController extends Controller
{
public function search(Request $request): JsonResponse
{
$query = $request->input('query');
$page = (int) $request->input('page', 1);
$perPage = 10;
$results = empty($query)
? $this->mergeModels([Person::class, Migration::class, Residence::class])
: $this->performSearch($query);
$paginated = $this->paginateCollection($results, $perPage, $page);
return response()->json([
'success' => true,
'message' => 'Records fetched successfully',
'data' => $paginated->items(),
'pagination' => [
'total' => $paginated->total(),
'perPage' => $paginated->perPage(),
'currentPage' => $paginated->currentPage(),
'totalPages' => $paginated->lastPage(),
]
]);
}
public function getRecord($id): JsonResponse
{
try {
$person = Person::with([
'migration',
'naturalization',
'residence',
'family',
'internment'
])->findOrFail($id);
return response()->json([
'success' => true,
'data' => $person,
'message' => 'Record retrieved successfully'
]);
} catch (Exception $e) {
Log::error('Error retrieving record', [
'id' => $id,
'error' => $e->getMessage()
]);
return response()->json([
'success' => false,
'message' => 'Record not found',
'error' => $e->getMessage()
], 404);
}
}
private function paginateCollection(Collection $collection, int $perPage, int $page): LengthAwarePaginator
{
$items = $collection->forPage($page, $perPage)->values();
return new LengthAwarePaginator(
$items,
$collection->count(),
$perPage,
$page,
[
'path' => request()->url(),
'query' => request()->query(),
]
);
}
private function mergeModels(array $models): Collection
{
return collect($models)
->flatMap(fn ($model) => $model::all());
}
private function performSearch(string $query): Collection
{
return Search::add(Person::class, ['christian_name', 'surname', 'place_of_birth'])
->add(Migration::class, ['date_of_arrival_nt'])
->add(Residence::class, ['town_or_city'])
->beginWithWildcard()
->search($query);
}
}