Stuff i guess ?

This commit is contained in:
Lars Behrends
2025-10-31 00:24:17 +01:00
parent db0fd4e728
commit 04140786a7
40 changed files with 5411 additions and 525 deletions

View File

@@ -51,20 +51,6 @@ class TvShow extends Model
]);
}
/**
* Update the cast field with actor names
*/
public function updateCastField(): bool
{
$actors = $this->actors();
$actorNames = array_column($actors, 'name');
$castString = implode(', ', $actorNames);
return $this->update($this->id, [
'cast' => $castString
]);
}
/**
* Get TV show statistics
*/
@@ -81,44 +67,64 @@ class TvShow extends Model
}
/**
* Get total count with optional search
* Get total count with optional search and filters
*/
public static function getTotalCount(\PDO $pdo, string $search = '', array $genres = [], array $years = []): int
{
public static function getTotalCount(
\PDO $pdo,
string $search = '',
array $genres = [],
array $networks = [],
array $statuses = []
): int {
$sql = "SELECT COUNT(*) as count FROM tv_shows t JOIN sources s ON t.source_id = s.id";
$params = [];
$whereClauses = [];
if (!empty($search)) {
$sql .= " WHERE t.title LIKE :search";
$whereClauses[] = "(t.title LIKE :search OR t.overview LIKE :search)";
$params['search'] = "%{$search}%";
}
if (!empty($genres)) {
$placeholders = [];
foreach ($genres as $index => $genre) {
$placeholders[] = ":genre_{$index}";
$params["genre_{$index}"] = $genre;
$genreConditions = [];
foreach ($genres as $i => $genre) {
$param = ":genre_{$i}";
$genreConditions[] = "FIND_IN_SET({$param}, t.genre) > 0";
$params["genre_{$i}"] = $genre;
}
$whereClause = !empty($search) ? " AND" : " WHERE";
$sql .= $whereClause . " t.genre IN (" . implode(',', $placeholders) . ")";
$whereClauses[] = '(' . implode(' OR ', $genreConditions) . ')';
}
if (!empty($years)) {
$placeholders = [];
foreach ($years as $index => $year) {
$placeholders[] = ":year_{$index}";
$params["year_{$index}"] = $year;
if (!empty($networks)) {
$networkConditions = [];
foreach ($networks as $i => $network) {
$param = ":network_{$i}";
$networkConditions[] = "t.networks LIKE {$param}";
$params["network_{$i}"] = "%\"name\":\"{$network}\"%";
}
$whereClause = (!empty($search) || !empty($genres)) ? " AND" : " WHERE";
$sql .= $whereClause . " YEAR(first_air_date) IN (" . implode(',', $placeholders) . ")";
$whereClauses[] = '(' . implode(' OR ', $networkConditions) . ')';
}
if (!empty($statuses)) {
$statusConditions = [];
foreach ($statuses as $i => $status) {
$param = ":status_{$i}";
$statusConditions[] = "t.status = {$param}";
$params["status_{$i}"] = $status;
}
$whereClauses[] = '(' . implode(' OR ', $statusConditions) . ')';
}
if (!empty($whereClauses)) {
$sql .= ' WHERE ' . implode(' AND ', $whereClauses);
}
$stmt = $pdo->prepare($sql);
foreach ($params as $key => $value) {
$stmt->bindValue(":{$key}", $value);
$stmt->bindValue($key, $value);
}
$stmt->execute();
return (int) $stmt->fetch()['count'];
return (int) $stmt->fetch(\PDO::FETCH_COLUMN);
}
/**
@@ -206,6 +212,135 @@ class TvShow extends Model
return $sourceData ? new Source($this->pdo, $sourceData) : null;
}
/**
* Get paginated TV shows with filters
*/
public static function getPaginated(
\PDO $pdo,
int $page,
int $perPage,
string $search = '',
array $genres = [],
array $networks = [],
array $statuses = [],
string $sort = 'title_asc'
): array {
$offset = ($page - 1) * $perPage;
$sql = "
SELECT t.*, s.display_name as source_name
FROM tv_shows t
JOIN sources s ON t.source_id = s.id
";
$params = [];
$whereClauses = [];
if (!empty($search)) {
$whereClauses[] = "(t.title LIKE :search OR t.overview LIKE :search)";
$params['search'] = "%{$search}%";
}
if (!empty($genres)) {
$genreConditions = [];
foreach ($genres as $i => $genre) {
$param = ":genre_{$i}";
$genreConditions[] = "FIND_IN_SET({$param}, t.genre) > 0";
$params["genre_{$i}"] = $genre;
}
$whereClauses[] = '(' . implode(' OR ', $genreConditions) . ')';
}
if (!empty($networks)) {
$networkConditions = [];
foreach ($networks as $i => $network) {
$param = ":network_{$i}";
$networkConditions[] = "t.networks LIKE {$param}";
$params["network_{$i}"] = "%\"name\":\"{$network}\"%";
}
$whereClauses[] = '(' . implode(' OR ', $networkConditions) . ')';
}
if (!empty($statuses)) {
$statusConditions = [];
foreach ($statuses as $i => $status) {
$param = ":status_{$i}";
$statusConditions[] = "t.status = {$param}";
$params["status_{$i}"] = $status;
}
$whereClauses[] = '(' . implode(' OR ', $statusConditions) . ')';
}
if (!empty($whereClauses)) {
$sql .= ' WHERE ' . implode(' AND ', $whereClauses);
}
// Add sorting
$sortMap = [
'title_asc' => 't.title ASC',
'title_desc' => 't.title DESC',
'rating_desc' => 't.vote_average DESC NULLS LAST',
'rating_asc' => 't.vote_average ASC NULLS LAST',
'newest' => 't.first_air_date DESC NULLS LAST',
'oldest' => 't.first_air_date ASC NULLS LAST',
];
$sortClause = $sortMap[$sort] ?? 't.title ASC';
$sql .= " ORDER BY {$sortClause} LIMIT :limit OFFSET :offset";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':limit', $perPage, \PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, \PDO::PARAM_INT);
foreach ($params as $key => $value) {
$stmt->bindValue($key, $value);
}
$stmt->execute();
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
}
/**
* Get all available genres from TV shows
*/
public static function getGenres(\PDO $pdo): array
{
$stmt = $pdo->query("
SELECT DISTINCT TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(t.genre, ',', n.n), ',', -1)) as genre
FROM tv_shows t
JOIN (
SELECT 1 as n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL
SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6
) n
WHERE n.n <= LENGTH(t.genre) - LENGTH(REPLACE(t.genre, ',', '')) + 1
AND t.genre IS NOT NULL AND t.genre != ''
ORDER BY genre
");
$genres = $stmt->fetchAll(\PDO::FETCH_COLUMN);
return array_values(array_filter(array_unique($genres)));
}
/**
* Get all available networks from TV shows
*/
public static function getNetworks(\PDO $pdo): array
{
$stmt = $pdo->query("SELECT DISTINCT networks FROM tv_shows WHERE networks IS NOT NULL AND networks != ''");
$networks = [];
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
$showNetworks = json_decode($row['networks'], true) ?: [];
foreach ($showNetworks as $network) {
if (isset($network['name'])) {
$networks[$network['name']] = $network['name'];
}
}
}
sort($networks);
return array_values($networks);
}
public function getSeasonsWithEpisodes(): array
{
// Get all episodes for this TV show, grouped by season