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

View File

@@ -0,0 +1,164 @@
<?php
namespace App\Actions\Titles;
use App\Models\Episode;
use App\Models\Person;
use App\Models\Season;
use App\Models\Title;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
class TitleCredits
{
public function loadCompact(
Title $title,
Season $season = null,
Episode $episode = null,
): Collection {
$builder = $this->getBaseQuery($title, $season, $episode)
->whereIn('creditables.department', [
'actors',
'writing',
'directing',
'creators',
])
->limit(50);
$credits = $this->groupByDepartment($builder);
if (isset($credits['actors'])) {
$credits['actors'] = $credits['actors']->take(15)->values();
}
if (isset($credits['writing'])) {
$credits['writing'] = $credits['writing']->take(3)->values();
}
if (isset($credits['directing'])) {
$credits['directing'] = $credits['directing']
->filter(fn($c) => $c['pivot']['job'] === 'director')
->take(3)
->values();
}
if (isset($credits['creators'])) {
$credits['creators'] = $credits['creators']->take(3)->values();
}
return $credits;
}
public function loadFull(
Title $title,
Season $season = null,
Episode $episode = null,
): Collection {
$builder = $this->getBaseQuery($title, $season, $episode);
return $this->groupByDepartment($builder);
}
protected function getBaseQuery(
Title $title = null,
Season $season = null,
Episode $episode = null,
): Builder {
$prefix = DB::getTablePrefix();
$builder = Person::join(
'creditables',
'people.id',
'=',
'creditables.person_id',
)
->select([
'people.id',
'people.name',
'people.poster',
DB::raw("{$prefix}creditables.id as pivot_id"),
DB::raw(
"{$prefix}creditables.creditable_id as pivot_creditable_id",
),
DB::raw(
"{$prefix}creditables.creditable_type as pivot_creditable_type",
),
DB::raw("{$prefix}creditables.job as pivot_job"),
DB::raw("{$prefix}creditables.department as pivot_department"),
DB::raw("{$prefix}creditables.order as pivot_order"),
DB::raw("{$prefix}creditables.character as pivot_character"),
])
// Need to keep same person in different departments (as actor and producer for example)
// while still removing duplicates when loading credits for title, season and episode
->groupBy(['people.id', 'creditables.department']);
$builder->where(function ($q) use ($title, $season, $episode) {
if ($title) {
$q->orWhere(
fn($q) => $q
->where('creditables.creditable_id', $title->id)
->where(
'creditables.creditable_type',
$title->getMorphClass(),
),
);
}
if ($episode) {
$q->orWhere(
fn($q) => $q
->where('creditables.creditable_id', $episode->id)
->where(
'creditables.creditable_type',
$episode->getMorphClass(),
),
);
}
if ($season) {
$q->orWhere(
fn($q) => $q
->where('creditables.creditable_id', $season->id)
->where(
'creditables.creditable_type',
$season->getMorphClass(),
),
);
}
});
// order by department first, so we always get director,
// writers and creators, even if limit is applied to this query
$prefix = DB::getTablePrefix();
return $builder
->orderBy(
DB::raw(
"FIELD(department, 'directing', 'creators', 'writing', 'actors')",
),
)
// should be "desc" and not "asc" because "minus" is added which will reverse order
->orderBy(DB::raw("-{$prefix}creditables.order"), 'desc');
}
protected function groupByDepartment(Builder $builder): Collection
{
$credits = $builder->get()->map(function ($credit) {
$credit->pivot = [
'id' => $credit->pivot_id,
'job' => $credit->pivot_job,
'department' => $credit->pivot_department,
'character' => $credit->pivot_character,
];
unset(
$credit->pivot_id,
$credit->pivot_creditable_id,
$credit->pivot_creditable_type,
$credit->pivot_job,
$credit->pivot_department,
$credit->pivot_order,
$credit->pivot_character,
);
return $credit;
});
return $credits->groupBy('pivot.department');
}
}