first commit
Some checks failed
Build / run (push) Has been cancelled

This commit is contained in:
maher
2025-10-29 11:42:25 +01:00
commit 703f50a09d
4595 changed files with 385164 additions and 0 deletions

59
app/Loaders/EpisodeLoader.php Executable file
View File

@@ -0,0 +1,59 @@
<?php
namespace App\Loaders;
use App\Actions\Titles\TitleCredits;
use App\Models\Title;
class EpisodeLoader
{
public function loadData(?string $loader): array
{
$pageName = request()->route('pageName');
$title = Title::with('genres')->findOrFail(request()->route('titleId'));
$season = $title->findSeason(request()->route('seasonNumber'));
$episode = $season->findEpisode(request()->route('episodeNumber'));
if (!$loader) {
$loader =
$pageName === 'full-credits'
? 'episodeCreditsPage'
: 'episodePage';
}
if (
($loader === 'episodePage' || $loader === 'episodeCreditsPage') &&
requestIsFromFrontend()
) {
$season = $season->maybeUpdateFromExternal($title);
if (!$season) {
abort(404);
}
}
$response = [
'title' => $title,
'episode' => $episode,
'loader' => $loader,
];
if ($loader === 'episodePage') {
$episode->load(['videos', 'primaryVideo']);
$response['credits'] = app(TitleCredits::class)->loadCompact(
$title,
$season,
$episode,
);
}
if ($loader === 'episodeCreditsPage') {
$response['credits'] = app(TitleCredits::class)->loadFull(
$title,
$season,
$episode,
);
}
return $response;
}
}

78
app/Loaders/ReviewsLoader.php Executable file
View File

@@ -0,0 +1,78 @@
<?php
namespace App\Loaders;
use Illuminate\Support\Arr;
class ReviewsLoader
{
public function loadData(array $params): ?array
{
$modelType = Arr::get($params, 'reviewableType');
$modelId = Arr::get($params, 'reviewableId');
if (!$modelType || !$modelId) {
return null;
}
$reviewable = app(modelTypeToNamespace($modelType))->find($modelId);
if (!$reviewable) {
return null;
}
$sharedReviewId = request('sharedReviewId');
$page = (int) ($params['page'] ?? 1);
$orderBy = $params['orderBy'] ?? 'created_at';
$orderDir = $params['orderDir'] ?? 'desc';
$response = [
'reviewable' => $reviewable,
];
$response['pagination'] = $reviewable
->reviews()
->with([
'user',
'feedback' => fn($q) => $q->where('user_id', auth()->id()),
'reports' => fn($q) => $q
->where('user_id', auth()->id())
->orWhere('user_ip', getIp()),
])
->withTextOnly()
->when(
$orderBy === 'mostHelpful',
fn($q) => $q->orderByMostHelpful(),
fn($q) => $q->orderBy($orderBy, $orderDir),
)
->paginate($params['perPage'] ?? 10)
->through(function ($review) {
if ($feedback = $review->feedback->first()) {
$review->current_user_feedback = $feedback->is_helpful;
}
if ($review->reports->first()) {
$review->current_user_reported = true;
}
$review->unsetRelation('feedback');
$review->unsetRelation('reports');
return $review;
});
$response['current_user_review'] =
$page === 1
? $reviewable
->reviews()
->where('user_id', auth()->id())
->first()
: null;
$response['shared_review'] =
$sharedReviewId && $page === 1
? $reviewable
->reviews()
->find($sharedReviewId)
?->load('user')
: null;
return $response;
}
}

67
app/Loaders/SeasonLoader.php Executable file
View File

@@ -0,0 +1,67 @@
<?php
namespace App\Loaders;
use App\Actions\Titles\Retrieve\PaginateSeasonEpisodes;
use App\Models\Title;
use App\Models\Video;
class SeasonLoader
{
public function loadData(?string $loader): array
{
if (!$loader) {
$loader = 'seasonPage';
}
$titleId = request()->route('titleId');
$seasonNumber = request()->route('seasonNumber');
$title = Title::withCount('seasons')->findOrFail($titleId);
$season = $title->findSeason($seasonNumber);
$season->loadCount('episodes');
if ($loader === 'seasonPage' && requestIsFromFrontend()) {
$season = $season->maybeUpdateFromExternal($title);
if (!$season) {
abort(404);
}
}
$response = [
'title' => $title,
'season' => $season,
'loader' => $loader,
];
if ($loader === 'seasonPage' || $loader === 'editSeasonPage') {
$response['episodes'] = app(PaginateSeasonEpisodes::class)->execute(
$title,
$seasonNumber,
request()->all(),
);
}
if ($loader === 'seasonPage') {
$primaryVideo = Video::where('title_id', $season->title_id)
->select([
'id',
'title_id',
'name',
'category',
'episode_id',
'season_num',
'episode_num',
])
->where('season_num', $season->number)
->when(settings('streaming.prefer_full'), function ($query) {
$query->where('category', 'full');
})
->applySelectedSort()
->first();
$season->primary_video = $primaryVideo;
}
return $response;
}
}

148
app/Loaders/TitleLoader.php Executable file
View File

@@ -0,0 +1,148 @@
<?php
namespace App\Loaders;
use App\Actions\Titles\Retrieve\PaginateSeasonEpisodes;
use App\Actions\Titles\Retrieve\PaginateTitleSeasons;
use App\Actions\Titles\TitleCredits;
use App\Models\Title;
use Common\Core\Values\ValueLists;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Arr;
class TitleLoader
{
public function loadData(?string $loader): array
{
$pageName = request()->route('pageName');
$titleId = request()->route('id');
if (!$loader) {
$loader =
$pageName === 'full-credits' ? 'titleCreditsPage' : 'titlePage';
}
if (is_numeric($titleId) || ctype_digit($titleId)) {
$title = Title::findOrFail($titleId);
} else {
$title = Title::firstOrCreateFromEncodedTmdbId($titleId);
}
if (
($loader === 'titlePage' || $loader === 'titleCreditsPage') &&
requestIsFromFrontend()
) {
$title = $title->maybeUpdateFromExternal();
if (!$title) {
abort(404);
}
}
$response = [
'title' => $title->loadCount('seasons'),
'loader' => $loader,
];
if ($title->language) {
$lang = Arr::first(
app(ValueLists::class)->languages(),
fn($lang) => $lang['code'] === $title->language,
);
$response['language'] = $lang['name'] ?? null;
}
if ($loader === 'titlePage') {
return $this->loadTitlePage($response);
}
if ($loader === 'titleCreditsPage') {
return $this->loadTitleCreditsPage($response);
}
if ($loader === 'editTitlePage') {
$title->load([
'images',
'genres',
'keywords',
'productionCountries',
]);
return $response;
}
return $response;
}
private function loadTitlePage(array $response): array
{
$enabledSections = settings('title_page.sections');
$title = $response['title'];
$title->load([
'images',
'genres',
'productionCountries',
'keywords',
'primaryVideo',
]);
$response = $this->loadVideos($response);
if (in_array('episodes', $enabledSections)) {
$response['episodes'] = app(PaginateSeasonEpisodes::class)->execute(
$title,
1,
request()->all(),
);
}
if (in_array('seasons', $enabledSections)) {
$response = $this->loadSeasons($response);
}
return $this->loadCompactCredits($response);
}
private function loadTitleCreditsPage(array $response): array
{
$title = $response['title'];
$title->load(['genres', 'primaryVideo']);
$response = $this->loadSeasons($response);
$response = $this->loadVideos($response);
return $this->loadCredits($response);
}
private function loadSeasons(array $response): array
{
if ($response['title']->is_series) {
$response['seasons'] = app(PaginateTitleSeasons::class)->execute(
$response['title'],
);
}
return $response;
}
private function loadVideos(array $response): array
{
$response['title']->load([
'videos' => function (HasMany $query) {
$query
->where('approved', true)
->whereNull('episode_num')
->fromConfiguredCategory();
},
]);
return $response;
}
private function loadCredits(array $response): array
{
$response['credits'] = app(TitleCredits::class)->loadFull(
$response['title'],
);
return $response;
}
private function loadCompactCredits(array $response): array
{
$response['credits'] = app(TitleCredits::class)->loadCompact(
$response['title'],
);
return $response;
}
}