99 lines
3.4 KiB
PHP
99 lines
3.4 KiB
PHP
<?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);
|
|
}
|
|
}
|