ldc-legaulois/app/Http/Controllers/Fo/SearchController.php
2025-06-11 09:59:07 +02:00

105 lines
3.5 KiB
PHP

<?php
namespace App\Http\Controllers\Fo;
use App\Enums\StaticPageType;
use App\Http\Controllers\Controller;
use App\Lib\Helpers\CollectionHelper;
use App\Models\StaticPage;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
class SearchController extends Controller
{
/**
* Search page.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Contracts\View\View
*/
public function search(Request $request): \Illuminate\Contracts\View\View
{
$searchString = $request->input('texte');
return view('fo.pages.search', [
'staticPageModel' => StaticPage::getCachedStaticPage(StaticPageType::search),
'productModels' => $this->getResultFromMeilisearch($searchString, 'App\Models\Product'),
'recipeModels' => $this->getResultFromMeilisearch($searchString, 'App\Models\Recipe'),
'newsModels' => $this->getResultFromMeilisearch($searchString, 'App\Models\News'),
'newsBreedingModels' => $this->getResultFromMeilisearch($searchString, 'App\Models\NewsBreeding'),
]);
}
/**
* Search string on multiple models.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function searchString(Request $request): \Illuminate\Http\JsonResponse
{
$search = $request->input('texte');
$page = $request->input('page');
$results = collect($request->models)->map(function (string $model) use ($search, $page) {
return $this->getResultFromMeilisearch($search, $model, $page);
});
return response()->json($results);
}
/**
* Search string on multiple models.
*
* @param string|null $search
* @param string $className
* @param integer $page
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
*/
public function getResultFromMeilisearch(
string|null $search,
string $className,
int $page = 1
): LengthAwarePaginator {
$models = $className::search($search)
->where('published', true)
->paginateRaw(perPage: 4, page: $page);
return $this->getViewsFromMeilisearchPagination($models, $className);
}
/**
* Search string on multiple models.
*
* @param \Illuminate\Contracts\Pagination\LengthAwarePaginator $models
* @param string $className
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
*/
public function getViewsFromMeilisearchPagination(
LengthAwarePaginator $models,
string $className
): LengthAwarePaginator {
$models['hits'] = collect($models['hits'])->map(function ($model) use ($className) {
$class = new $className();
return $class->forceFill($model);
});
$models['hits'] = CollectionHelper::getViewsFromCollection(
$models['hits'],
"fo.partials.{$this->transformClassNameToSnakeCase($className)}-card",
'model'
);
return $models;
}
/**
* Transform class name to snake case.
*
* @param string $className
* @return string
*/
public function transformClassNameToSnakeCase(string $className): string
{
return Str::lower(preg_replace(
'/(?<!^)[A-Z]/',
'-$0',
class_basename(explode('App\\Models\\', $className)[1])
));
}
}