mirror of
https://github.com/ceratic/MediaCollectorLibary.git
synced 2026-05-13 23:56:46 +02:00
Stuff i guess ?
This commit is contained in:
@@ -25,7 +25,7 @@ class AdultVideo extends Model
|
||||
'external_id'
|
||||
];
|
||||
|
||||
public static function getAllWithPagination(\PDO $pdo, int $page, int $perPage, string $search = '', array $genres = [], array $directors = []): array
|
||||
public static function getAllWithPagination(\PDO $pdo, int $page, int $perPage, string $search = '', array $genres = [], array $directors = [], string $sort = 'recent'): array
|
||||
{
|
||||
$offset = ($page - 1) * $perPage;
|
||||
|
||||
@@ -61,7 +61,24 @@ class AdultVideo extends Model
|
||||
$sql .= $whereClause . " av.director IN (" . implode(',', $placeholders) . ")";
|
||||
}
|
||||
|
||||
$sql .= " ORDER BY av.created_at DESC LIMIT :limit OFFSET :offset";
|
||||
// Add sorting
|
||||
$sortOptions = [
|
||||
'recent' => 'av.created_at DESC',
|
||||
'oldest' => 'av.created_at ASC',
|
||||
'title_asc' => 'av.title ASC',
|
||||
'title_desc' => 'av.title DESC',
|
||||
'year_asc' => 'av.release_date ASC',
|
||||
'year_desc' => 'av.release_date DESC',
|
||||
'rating_asc' => 'av.rating ASC',
|
||||
'rating_desc' => 'av.rating DESC',
|
||||
'views_asc' => 'av.watch_count ASC',
|
||||
'views_desc' => 'av.watch_count DESC',
|
||||
'runtime_asc' => 'av.runtime_minutes ASC',
|
||||
'runtime_desc' => 'av.runtime_minutes DESC',
|
||||
];
|
||||
|
||||
$sortOrder = $sortOptions[$sort] ?? $sortOptions['recent'];
|
||||
$sql .= " ORDER BY " . $sortOrder . " LIMIT :limit OFFSET :offset";
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->bindValue(':limit', $perPage, \PDO::PARAM_INT);
|
||||
@@ -143,7 +160,7 @@ class AdultVideo extends Model
|
||||
/**
|
||||
* Get all actors associated with this adult video
|
||||
*/
|
||||
public function actors()
|
||||
public function actors($args)
|
||||
{
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT a.*
|
||||
@@ -152,7 +169,7 @@ class AdultVideo extends Model
|
||||
WHERE aav.adult_video_id = :adult_video_id
|
||||
ORDER BY a.name ASC
|
||||
");
|
||||
$stmt->execute(['adult_video_id' => $this->id]);
|
||||
$stmt->execute(['adult_video_id' => $args]);
|
||||
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
@@ -200,21 +217,6 @@ class AdultVideo extends Model
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TV show statistics
|
||||
*/
|
||||
public static function getStats(\PDO $pdo): array
|
||||
{
|
||||
$stmt = $pdo->query("
|
||||
SELECT
|
||||
COUNT(*) as total_adult_videos,
|
||||
COUNT(CASE WHEN is_favorite = 1 THEN 1 END) as favorite_adult_videos,
|
||||
AVG(rating) as avg_rating
|
||||
FROM adult_videos
|
||||
");
|
||||
return $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available genres for filtering
|
||||
*/
|
||||
@@ -242,4 +244,36 @@ class AdultVideo extends Model
|
||||
");
|
||||
return $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TV show statistics
|
||||
*/
|
||||
public static function getStats(\PDO $pdo): array
|
||||
{
|
||||
$stmt = $pdo->query("
|
||||
SELECT
|
||||
COUNT(*) as total_adult_videos,
|
||||
COUNT(CASE WHEN is_favorite = 1 THEN 1 END) as favorite_adult_videos,
|
||||
AVG(rating) as avg_rating
|
||||
FROM adult_videos
|
||||
");
|
||||
return $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search actors by name
|
||||
*/
|
||||
public static function searchActors(\PDO $pdo, string $query): array
|
||||
{
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT a.*
|
||||
FROM actors a
|
||||
WHERE a.name LIKE :query
|
||||
ORDER BY a.name
|
||||
LIMIT 10
|
||||
");
|
||||
|
||||
$stmt->execute(['query' => "%{$query}%"]);
|
||||
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,9 +177,9 @@ class Game extends Model
|
||||
}
|
||||
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT g.*, s.display_name as source_name
|
||||
SELECT g.*, g.platform as source_name
|
||||
FROM games g
|
||||
JOIN sources s ON g.source_id = s.id
|
||||
|
||||
WHERE g.game_key = :game_key
|
||||
ORDER BY g.platform, g.source_id
|
||||
");
|
||||
@@ -215,9 +215,9 @@ class Game extends Model
|
||||
|
||||
// Enhance each game with platform details
|
||||
foreach ($games as &$game) {
|
||||
$game['platforms'] = array_unique(explode(',', $game['platforms']));
|
||||
$game['source_ids'] = array_unique(explode(',', $game['source_ids']));
|
||||
$game['genres'] = array_unique(array_filter(explode(',', $game['genres'])));
|
||||
$game['platforms'] = !empty($game['platforms']) ? array_unique(explode(',', $game['platforms'])) : [];
|
||||
$game['source_ids'] = !empty($game['source_ids']) ? array_unique(explode(',', $game['source_ids'])) : [];
|
||||
$game['genres'] = !empty($game['genres']) ? array_unique(array_filter(explode(',', $game['genres']))) : [];
|
||||
}
|
||||
|
||||
return $games;
|
||||
@@ -298,7 +298,7 @@ class Game extends Model
|
||||
/**
|
||||
* Get grouped games with pagination and search support
|
||||
*/
|
||||
public static function getGroupedGamesWithPagination(\PDO $pdo, int $page, int $perPage, string $search = '', array $genres = [], array $platforms = []): array
|
||||
public static function getGroupedGamesWithPagination(\PDO $pdo, int $page, int $perPage, string $search = '', array $genres = [], array $platforms = [], string $sort = 'title_asc'): array
|
||||
{
|
||||
$offset = ($page - 1) * $perPage;
|
||||
|
||||
@@ -313,7 +313,9 @@ class Game extends Model
|
||||
MAX(last_played_at) as last_played_at,
|
||||
SUM(playtime_minutes) as total_playtime,
|
||||
MAX(completion_percentage) as max_completion,
|
||||
GROUP_CONCAT(DISTINCT genre ORDER BY genre) as genres
|
||||
GROUP_CONCAT(DISTINCT genre ORDER BY genre) as genres,
|
||||
MAX(release_date) as release_date,
|
||||
MAX(added_at) as added_at
|
||||
FROM games
|
||||
WHERE game_key IS NOT NULL
|
||||
";
|
||||
@@ -343,7 +345,24 @@ class Game extends Model
|
||||
$sql .= " AND platform IN (" . implode(',', $placeholders) . ")";
|
||||
}
|
||||
|
||||
$sql .= " GROUP BY game_key, title ORDER BY last_played_at DESC, total_playtime DESC LIMIT :limit OFFSET :offset";
|
||||
// Add sorting
|
||||
$sortOptions = [
|
||||
'title_asc' => 'title ASC',
|
||||
'title_desc' => 'title DESC',
|
||||
'year_asc' => 'release_date ASC NULLS LAST',
|
||||
'year_desc' => 'release_date DESC NULLS LAST',
|
||||
'playtime_asc' => 'total_playtime ASC',
|
||||
'playtime_desc' => 'total_playtime DESC',
|
||||
'completion_asc' => 'max_completion ASC NULLS LAST',
|
||||
'completion_desc' => 'max_completion DESC NULLS LAST',
|
||||
'added_asc' => 'added_at ASC NULLS LAST',
|
||||
'added_desc' => 'added_at DESC NULLS LAST',
|
||||
'last_played_asc' => 'last_played_at ASC NULLS LAST',
|
||||
'last_played_desc' => 'last_played_at DESC NULLS LAST'
|
||||
];
|
||||
|
||||
$sortClause = $sortOptions[$sort] ?? 'title ASC';
|
||||
$sql .= " GROUP BY game_key, title ORDER BY $sortClause LIMIT :limit OFFSET :offset";
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->bindValue(':limit', $perPage, \PDO::PARAM_INT);
|
||||
@@ -358,20 +377,52 @@ class Game extends Model
|
||||
|
||||
// Enhance each game with platform details
|
||||
foreach ($games as &$game) {
|
||||
$game['platforms'] = array_unique(explode(',', $game['platforms']));
|
||||
$game['source_ids'] = array_unique(explode(',', $game['source_ids']));
|
||||
$game['genres'] = array_unique(array_filter(explode(',', $game['genres'])));
|
||||
$game['platforms'] = !empty($game['platforms']) ? array_unique(explode(',', $game['platforms'])) : [];
|
||||
$game['source_ids'] = !empty($game['source_ids']) ? array_unique(explode(',', $game['source_ids'])) : [];
|
||||
$game['genres'] = !empty($game['genres']) ? array_unique(array_filter(explode(',', $game['genres']))) : [];
|
||||
}
|
||||
|
||||
return $games;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Playnite-specific genres
|
||||
* Get all unique genres from the games table
|
||||
* Combines both Playnite JSON genres and regular genre field
|
||||
*/
|
||||
public function getGenres(): array
|
||||
{
|
||||
return $this->genres_json ?? [];
|
||||
// First get genres from the regular genre field
|
||||
$stmt = $this->pdo->query("SELECT DISTINCT genre FROM {$this->table} WHERE genre IS NOT NULL AND genre != ''");
|
||||
$genres = [];
|
||||
$results = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
// Flatten and deduplicate genres
|
||||
foreach ($results as $genreList) {
|
||||
$genreArray = array_map('trim', explode(',', $genreList));
|
||||
$genres = array_merge($genres, $genreArray);
|
||||
}
|
||||
|
||||
// Also get genres from Playnite JSON data
|
||||
$stmt = $this->pdo->query("SELECT genres_json FROM {$this->table} WHERE genres_json IS NOT NULL AND genres_json != '[]'");
|
||||
$jsonGenres = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
foreach ($jsonGenres as $json) {
|
||||
$decoded = json_decode($json, true);
|
||||
if (is_array($decoded)) {
|
||||
foreach ($decoded as $genre) {
|
||||
if (is_array($genre) && isset($genre['Name'])) {
|
||||
$genres[] = $genre['Name'];
|
||||
} elseif (is_string($genre)) {
|
||||
$genres[] = $genre;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$genres = array_unique($genres);
|
||||
sort($genres);
|
||||
|
||||
return array_values(array_filter($genres));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -397,6 +448,16 @@ class Game extends Model
|
||||
{
|
||||
return $this->tags_json ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all unique platforms from the games table
|
||||
*/
|
||||
public function getPlatforms(): array
|
||||
{
|
||||
$stmt = $this->pdo->query("SELECT DISTINCT platform FROM {$this->table} WHERE platform IS NOT NULL AND platform != '' ORDER BY platform");
|
||||
return $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Playnite-specific features
|
||||
|
||||
@@ -46,6 +46,150 @@ class Movie extends Model
|
||||
return $sourceData ? new Source($this->pdo, $sourceData) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total count of movies with optional filters
|
||||
*/
|
||||
public static function getTotalCount(\PDO $pdo, string $search = '', array $genres = [], array $directors = []): int
|
||||
{
|
||||
$where = [];
|
||||
$params = [];
|
||||
|
||||
$sql = "SELECT COUNT(*) as count FROM movies m JOIN sources s ON m.source_id = s.id";
|
||||
|
||||
if (!empty($search)) {
|
||||
$where[] = "(m.title LIKE :search OR m.overview LIKE :search)";
|
||||
$params[':search'] = "%$search%";
|
||||
}
|
||||
|
||||
if (!empty($genres)) {
|
||||
$genreConditions = [];
|
||||
foreach ($genres as $i => $genre) {
|
||||
$param = ":genre_$i";
|
||||
$genreConditions[] = "m.genre LIKE $param";
|
||||
$params[$param] = "%$genre%";
|
||||
}
|
||||
$where[] = "(" . implode(' OR ', $genreConditions) . ")";
|
||||
}
|
||||
|
||||
if (!empty($directors)) {
|
||||
$directorConditions = [];
|
||||
foreach ($directors as $i => $director) {
|
||||
$param = ":director_$i";
|
||||
$directorConditions[] = "m.director LIKE $param";
|
||||
$params[$param] = "%$director%";
|
||||
}
|
||||
$where[] = "(" . implode(' OR ', $directorConditions) . ")";
|
||||
}
|
||||
|
||||
if (!empty($where)) {
|
||||
$sql .= " WHERE " . implode(' AND ', $where);
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
|
||||
return (int)$stmt->fetchColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get paginated movies with optional filters
|
||||
*/
|
||||
public function getPaginated(
|
||||
\PDO $pdo,
|
||||
int $page = 1,
|
||||
int $perPage = 20,
|
||||
string $search = '',
|
||||
array $genres = [],
|
||||
string $sort = 'title_asc'
|
||||
): array {
|
||||
$offset = ($page - 1) * $perPage;
|
||||
$where = [];
|
||||
$params = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$where[] = "(title LIKE :search OR overview LIKE :search OR director LIKE :search OR writer LIKE :search)";
|
||||
$params[':search'] = "%$search%";
|
||||
}
|
||||
|
||||
if (!empty($genres)) {
|
||||
$genreConditions = [];
|
||||
foreach ($genres as $i => $genre) {
|
||||
$param = ":genre$i";
|
||||
$genreConditions[] = "genre LIKE $param";
|
||||
$params[$param] = "%$genre%";
|
||||
}
|
||||
$where[] = "(" . implode(' OR ', $genreConditions) . ")";
|
||||
}
|
||||
|
||||
// Determine sort order
|
||||
$orderBy = 'title ASC';
|
||||
switch ($sort) {
|
||||
case 'title_desc':
|
||||
$orderBy = 'title DESC';
|
||||
break;
|
||||
case 'release_asc':
|
||||
$orderBy = 'release_date ASC';
|
||||
break;
|
||||
case 'release_desc':
|
||||
$orderBy = 'release_date DESC';
|
||||
break;
|
||||
case 'rating_desc':
|
||||
$orderBy = 'rating DESC';
|
||||
break;
|
||||
case 'rating_asc':
|
||||
$orderBy = 'rating ASC';
|
||||
break;
|
||||
}
|
||||
|
||||
$sql = "SELECT * FROM {$this->table}";
|
||||
if (!empty($where)) {
|
||||
$sql .= " WHERE " . implode(' AND ', $where);
|
||||
}
|
||||
$sql .= " ORDER BY $orderBy LIMIT :limit OFFSET :offset";
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
|
||||
// Bind parameters
|
||||
foreach ($params as $key => $value) {
|
||||
$stmt->bindValue($key, $value);
|
||||
}
|
||||
$stmt->bindValue(':limit', $perPage, \PDO::PARAM_INT);
|
||||
$stmt->bindValue(':offset', $offset, \PDO::PARAM_INT);
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all unique genres from movies
|
||||
*/
|
||||
public function getGenres(\PDO $pdo): array
|
||||
{
|
||||
$stmt = $pdo->query("SELECT DISTINCT genre FROM {$this->table} WHERE genre IS NOT NULL AND genre != ''");
|
||||
$results = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
$genres = [];
|
||||
foreach ($results as $genreList) {
|
||||
$genreArray = array_map('trim', explode(',', $genreList));
|
||||
$genres = array_merge($genres, $genreArray);
|
||||
}
|
||||
|
||||
$genres = array_unique($genres);
|
||||
sort($genres);
|
||||
|
||||
return array_values(array_filter($genres));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all unique directors from movies
|
||||
*/
|
||||
public function getDirectors(\PDO $pdo): array
|
||||
{
|
||||
$stmt = $pdo->query("SELECT DISTINCT director FROM {$this->table} WHERE director IS NOT NULL AND director != '' ORDER BY director");
|
||||
return $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
}
|
||||
|
||||
public function markAsWatched(): bool
|
||||
{
|
||||
$this->watched = true;
|
||||
@@ -108,7 +252,7 @@ class Movie extends Model
|
||||
$stmt->execute(['limit' => $limit]);
|
||||
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/*
|
||||
public static function getTotalCount(\PDO $pdo, string $search = '', array $genres = [], array $directors = []): int
|
||||
{
|
||||
$sql = "SELECT COUNT(*) as count FROM movies m JOIN sources s ON m.source_id = s.id";
|
||||
@@ -146,8 +290,8 @@ class Movie extends Model
|
||||
$stmt->execute();
|
||||
return (int) $stmt->fetch()['count'];
|
||||
}
|
||||
|
||||
public static function getAllWithPagination(\PDO $pdo, int $page, int $perPage, string $search = '', array $genres = [], array $directors = []): array
|
||||
*/
|
||||
public static function getAllWithPagination(\PDO $pdo, int $page, int $perPage, string $search = '', array $genres = [], array $directors = [], string $sort = 'title_asc'): array
|
||||
{
|
||||
$offset = ($page - 1) * $perPage;
|
||||
|
||||
@@ -170,20 +314,47 @@ class Movie extends Model
|
||||
$params["genre_{$index}"] = $genre;
|
||||
}
|
||||
$whereClause = !empty($search) ? " AND" : " WHERE";
|
||||
$sql .= $whereClause . " m.genre IN (" . implode(',', $placeholders) . ")";
|
||||
$sql .= $whereClause . " (";
|
||||
foreach ($placeholders as $i => $placeholder) {
|
||||
if ($i > 0) $sql .= " OR ";
|
||||
$sql .= "m.genre LIKE $placeholder";
|
||||
}
|
||||
$sql .= ")";
|
||||
}
|
||||
|
||||
if (!empty($directors)) {
|
||||
$placeholders = [];
|
||||
foreach ($directors as $index => $director) {
|
||||
$placeholders[] = ":director_{$index}";
|
||||
$params["director_{$index}"] = $director;
|
||||
$params["director_{$index}"] = "%$director%";
|
||||
}
|
||||
$whereClause = (!empty($search) || !empty($genres)) ? " AND" : " WHERE";
|
||||
$sql .= $whereClause . " m.director IN (" . implode(',', $placeholders) . ")";
|
||||
$sql .= $whereClause . " (";
|
||||
foreach ($placeholders as $i => $placeholder) {
|
||||
if ($i > 0) $sql .= " OR ";
|
||||
$sql .= "m.director LIKE $placeholder";
|
||||
}
|
||||
$sql .= ")";
|
||||
}
|
||||
|
||||
$sql .= " ORDER BY m.title ASC LIMIT :limit OFFSET :offset";
|
||||
// Add sorting
|
||||
$sortOptions = [
|
||||
'title_asc' => 'm.title ASC',
|
||||
'title_desc' => 'm.title DESC',
|
||||
'year_asc' => 'm.release_date ASC',
|
||||
'year_desc' => 'm.release_date DESC',
|
||||
'rating_asc' => 'm.rating ASC NULLS LAST',
|
||||
'rating_desc' => 'm.rating DESC NULLS LAST',
|
||||
'views_asc' => 'm.watch_count ASC',
|
||||
'views_desc' => 'm.watch_count DESC',
|
||||
'added_asc' => 'm.created_at ASC',
|
||||
'added_desc' => 'm.created_at DESC',
|
||||
'last_watched_asc' => 'm.last_watched_at ASC NULLS LAST',
|
||||
'last_watched_desc' => 'm.last_watched_at DESC NULLS LAST'
|
||||
];
|
||||
|
||||
$sortClause = $sortOptions[$sort] ?? 'm.title ASC';
|
||||
$sql .= " ORDER BY $sortClause LIMIT :limit OFFSET :offset";
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->bindValue(':limit', $perPage, \PDO::PARAM_INT);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user