138
app/Actions/Channels/FetchContentFromLocalDatabase.php
Executable file
138
app/Actions/Channels/FetchContentFromLocalDatabase.php
Executable file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Channels;
|
||||
|
||||
use App\Models\Episode;
|
||||
use App\Models\Genre;
|
||||
use App\Models\Keyword;
|
||||
use App\Models\Person;
|
||||
use App\Models\ProductionCountry;
|
||||
use App\Models\Title;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class FetchContentFromLocalDatabase
|
||||
{
|
||||
public function execute(
|
||||
string $method,
|
||||
string $modelType,
|
||||
?array $filters = [],
|
||||
): Collection {
|
||||
$isSeries = $modelType === Title::SERIES_TYPE;
|
||||
if ($method === 'trendingPeople') {
|
||||
return Person::orderBy('popularity', 'desc')
|
||||
->limit(20)
|
||||
->get();
|
||||
} elseif ($method === 'mostPopular') {
|
||||
return $this->getTitleBuilder($filters)
|
||||
->orderBy('popularity', 'desc')
|
||||
->limit(20)
|
||||
->where('is_series', $isSeries)
|
||||
->get();
|
||||
} elseif ($method === 'topRated') {
|
||||
return $this->getTopRatedTitles(
|
||||
$this->getTitleBuilder($filters),
|
||||
$isSeries,
|
||||
);
|
||||
} elseif ($method === 'upcoming') {
|
||||
return $this->getMoviesReleasingBetween(
|
||||
$this->getTitleBuilder($filters),
|
||||
Carbon::now(),
|
||||
Carbon::now()->addWeek(),
|
||||
);
|
||||
} elseif ($method === 'nowPlaying') {
|
||||
return $this->getMoviesReleasingBetween(
|
||||
$this->getTitleBuilder($filters),
|
||||
Carbon::now(),
|
||||
Carbon::now()->subWeek(),
|
||||
);
|
||||
} elseif ($method === 'onTheAir') {
|
||||
$this->getSeriesAiringBetween(
|
||||
$this->getTitleBuilder($filters),
|
||||
Carbon::now(),
|
||||
Carbon::now()->addWeek(),
|
||||
);
|
||||
} elseif ($method === 'airingToday') {
|
||||
return $this->getSeriesAiringBetween(
|
||||
$this->getTitleBuilder($filters),
|
||||
Carbon::now(),
|
||||
Carbon::now()->addDay(),
|
||||
);
|
||||
} elseif ($method === 'latestVideos') {
|
||||
return $this->getTitleBuilder($filters)
|
||||
->join('videos', 'titles.id', '=', 'videos.title_id')
|
||||
->where('videos.origin', 'local')
|
||||
->where('approved', true)
|
||||
->orderBy('videos.created_at', 'desc')
|
||||
->select('titles.*')
|
||||
->distinct()
|
||||
->limit(20)
|
||||
->get();
|
||||
} elseif ($method === 'lastAdded') {
|
||||
return $this->getTitleBuilder($filters)
|
||||
::where('is_series', $isSeries)
|
||||
->orderBy('created_at', 'desc')
|
||||
->limit(20)
|
||||
->get();
|
||||
}
|
||||
}
|
||||
|
||||
private function getTopRatedTitles(mixed $builder, $isSeries): Collection
|
||||
{
|
||||
$ratingCol = config('common.site.rating_column');
|
||||
|
||||
$query = $builder->where('is_series', $isSeries);
|
||||
|
||||
if (Str::contains($ratingCol, 'tmdb_vote_average')) {
|
||||
$query->orderBy(DB::raw('tmdb_vote_count > 100'), 'desc');
|
||||
}
|
||||
|
||||
return $query
|
||||
->orderBy($ratingCol, 'desc')
|
||||
->limit(20)
|
||||
->get();
|
||||
}
|
||||
|
||||
private function getMoviesReleasingBetween(
|
||||
mixed $builder,
|
||||
$from,
|
||||
$to,
|
||||
): Collection {
|
||||
return $builder
|
||||
->whereBetween('release_date', [$from, $to])
|
||||
->orderBy('popularity', 'desc')
|
||||
->limit(20)
|
||||
->where('is_series', false)
|
||||
->get(['id', 'name']);
|
||||
}
|
||||
|
||||
private function getSeriesAiringBetween(
|
||||
mixed $builder,
|
||||
$from,
|
||||
$to,
|
||||
): Collection {
|
||||
$titleIds = Episode::whereBetween('release_date', [$from, $to])
|
||||
->limit(300)
|
||||
->get(['title_id'])
|
||||
->pluck('title_id')
|
||||
->unique()
|
||||
->slice(0, 20);
|
||||
|
||||
return $builder->whereIn('id', $titleIds)->get(['id', 'name']);
|
||||
}
|
||||
|
||||
private function getTitleBuilder(?array $filters = []): mixed
|
||||
{
|
||||
if (isset($filters['keyword'])) {
|
||||
return Keyword::findOrFail($filters['keyword'])->titles();
|
||||
} elseif (isset($filters['genre'])) {
|
||||
return Genre::findOrFail($filters['genre'])->titles();
|
||||
} elseif (isset($filters['country'])) {
|
||||
return ProductionCountry::findOrFail($filters['country'])->titles();
|
||||
} else {
|
||||
return Title::query();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user