PIMS/app/Modules/Movies/Services/Browse/ListMoviesService.php

99 lines
3.4 KiB
PHP
Raw Normal View History

2025-12-07 03:49:26 +00:00
<?php
namespace App\Modules\Movies\Services\Browse;
use App\Modules\Movies\Models\Movie;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use App\Modules\Movies\Services\Contracts\ListMoviesServiceInterface;
class ListMoviesService implements ListMoviesServiceInterface
{
/**
* Return a paginated list of movies with optional search, filters, and sort.
*
* @param array{
* q?: string|null,
* per_page?: int|null,
* sort?: string|null,
* genre?: string|null,
* rating?: string|null,
* year_min?: int|null,
* year_max?: int|null,
* actor?: string|null,
* director?: string|null,
* studio?: string|null,
* } $params
*/
public function list(array $params = []): LengthAwarePaginator
{
$perPage = (int) ($params['per_page'] ?? 20);
$q = isset($params['q']) ? trim((string) $params['q']) : '';
$sort = isset($params['sort']) ? trim((string) $params['sort']) : 'title_asc';
$genre = isset($params['genre']) ? trim((string) $params['genre']) : '';
$rating = isset($params['rating']) ? trim((string) $params['rating']) : '';
$yearMin = isset($params['year_min']) ? (int) $params['year_min'] : null;
$yearMax = isset($params['year_max']) ? (int) $params['year_max'] : null;
$actor = isset($params['actor']) ? trim((string) $params['actor']) : '';
$director = isset($params['director']) ? trim((string) $params['director']) : '';
$studio = isset($params['studio']) ? trim((string) $params['studio']) : '';
$query = Movie::query()->with(['genres', 'actors', 'directors']);
if ($q !== '') {
$query->where('title', 'like', "%{$q}%");
}
if ($genre !== '') {
$ln = mb_strtolower($genre);
$query->whereHas('genres', fn($q2) => $q2->whereRaw('lower(name) = ?', [$ln]));
}
if ($rating !== '') {
$query->where('rating', $rating);
}
if ($yearMin !== null) {
$query->where('year', '>=', $yearMin);
}
if ($yearMax !== null) {
$query->where('year', '<=', $yearMax);
}
if ($actor !== '') {
$ln = mb_strtolower($actor);
$query->whereHas('actors', fn($q2) => $q2->whereRaw('lower(name) = ?', [$ln]));
}
if ($director !== '') {
$ln = mb_strtolower($director);
$query->whereHas('directors', fn($q2) => $q2->whereRaw('lower(name) = ?', [$ln]));
}
if ($studio !== '') {
$ln = mb_strtolower($studio);
$query->whereHas('studios', fn($q2) => $q2->whereRaw('lower(name) = ?', [$ln]));
}
// Sorting
switch ($sort) {
case 'title_desc':
$query->orderBy('title', 'desc');
break;
case 'newest':
$query->orderBy('created_at', 'desc');
break;
case 'oldest':
$query->orderBy('created_at', 'asc');
break;
case 'year_asc':
$query->orderBy('year', 'asc');
break;
case 'year_desc':
$query->orderBy('year', 'desc');
break;
case 'title_asc':
default:
$query->orderBy('title', 'asc');
break;
}
return $query->paginate($perPage);
}
}