mirror of
https://github.com/ceratic/MediaCollectorLibary.git
synced 2026-05-13 23:56:46 +02:00
...
This commit is contained in:
178
app/Models/TvEpisode.php
Normal file
178
app/Models/TvEpisode.php
Normal file
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
class TvEpisode extends Model
|
||||
{
|
||||
protected string $table = 'tv_episodes';
|
||||
protected array $fillable = [
|
||||
'title',
|
||||
'overview',
|
||||
'season_number',
|
||||
'episode_number',
|
||||
'air_date',
|
||||
'runtime_minutes',
|
||||
'rating',
|
||||
'imdb_id',
|
||||
'tmdb_id',
|
||||
'tvdb_id',
|
||||
'poster_url',
|
||||
'backdrop_url',
|
||||
'is_watched',
|
||||
'is_favorite',
|
||||
'metadata',
|
||||
'tv_show_id',
|
||||
'source_id'
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'season_number' => 'int',
|
||||
'episode_number' => 'int',
|
||||
'runtime_minutes' => 'int',
|
||||
'rating' => 'float',
|
||||
'is_watched' => 'bool',
|
||||
'is_favorite' => 'bool',
|
||||
'air_date' => 'date',
|
||||
'metadata' => 'array'
|
||||
];
|
||||
|
||||
/**
|
||||
* Get all actors associated with this TV episode
|
||||
*/
|
||||
public function actors()
|
||||
{
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT a.*
|
||||
FROM actors a
|
||||
JOIN actor_tv_episode ate ON a.id = ate.actor_id
|
||||
WHERE ate.tv_episode_id = :tv_episode_id
|
||||
ORDER BY a.name ASC
|
||||
");
|
||||
$stmt->execute(['tv_episode_id' => $this->id]);
|
||||
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the TV show this episode belongs to
|
||||
*/
|
||||
public function tvShow()
|
||||
{
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT * FROM tv_shows WHERE id = :tv_show_id
|
||||
");
|
||||
$stmt->execute(['tv_show_id' => $this->tv_show_id]);
|
||||
$showData = $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
return $showData ? new TvShow($this->pdo, $showData) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TV episode statistics
|
||||
*/
|
||||
public static function getStats(\PDO $pdo): array
|
||||
{
|
||||
$stmt = $pdo->query("
|
||||
SELECT
|
||||
COUNT(*) as total_episodes,
|
||||
COUNT(CASE WHEN is_watched = 1 THEN 1 END) as watched_episodes,
|
||||
COUNT(CASE WHEN is_favorite = 1 THEN 1 END) as favorite_episodes,
|
||||
AVG(rating) as avg_rating
|
||||
FROM tv_episodes
|
||||
");
|
||||
return $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total count with optional search
|
||||
*/
|
||||
public static function getTotalCount(\PDO $pdo, string $search = ''): int
|
||||
{
|
||||
$sql = "SELECT COUNT(*) as count FROM tv_episodes te JOIN tv_shows ts ON te.tv_show_id = ts.id JOIN sources s ON te.source_id = s.id";
|
||||
$params = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$sql .= " WHERE te.title LIKE :search OR ts.title LIKE :search";
|
||||
$params['search'] = "%{$search}%";
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
return (int) $stmt->fetch()['count'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all TV episodes with pagination and optional search
|
||||
*/
|
||||
public static function getAllWithPagination(\PDO $pdo, int $page, int $perPage, string $search = ''): array
|
||||
{
|
||||
$offset = ($page - 1) * $perPage;
|
||||
|
||||
$sql = "
|
||||
SELECT te.*, ts.title as show_title, s.display_name as source_name
|
||||
FROM tv_episodes te
|
||||
JOIN tv_shows ts ON te.tv_show_id = ts.id
|
||||
JOIN sources s ON te.source_id = s.id
|
||||
";
|
||||
$params = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$sql .= " WHERE te.title LIKE :search OR ts.title LIKE :search";
|
||||
$params['search'] = "%{$search}%";
|
||||
}
|
||||
|
||||
$sql .= " ORDER BY ts.title ASC, te.season_number ASC, te.episode_number ASC 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle watched status
|
||||
*/
|
||||
public function toggleWatched(): bool
|
||||
{
|
||||
return $this->update($this->id, [
|
||||
'is_watched' => !$this->is_watched
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle favorite status
|
||||
*/
|
||||
public function toggleFavorite(): bool
|
||||
{
|
||||
return $this->update($this->id, [
|
||||
'is_favorite' => !$this->is_favorite
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update rating
|
||||
*/
|
||||
public function updateRating(float $rating): bool
|
||||
{
|
||||
return $this->update($this->id, [
|
||||
'rating' => min(10.0, max(0.0, $rating))
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the source relationship
|
||||
*/
|
||||
public function source(): ?Source
|
||||
{
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM sources WHERE id = :source_id");
|
||||
$stmt->execute(['source_id' => $this->source_id]);
|
||||
$sourceData = $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
return $sourceData ? new Source($this->pdo, $sourceData) : null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user