Files
MediaCollectorLibary/app/Models/Actor.php
Lars Behrends 5d86fcfda9 actor merging!
2025-11-06 18:45:20 +01:00

308 lines
9.4 KiB
PHP

<?php
namespace App\Models;
class Actor extends Model
{
protected string $table = 'actors';
protected array $fillable = [
'name',
'thumbnail_path',
'metadata'
];
protected array $casts = [
'metadata' => 'array'
];
/**
* Get all movies this actor is associated with
*/
public function movies()
{
$stmt = $this->pdo->prepare("
SELECT m.*, s.display_name as source_name
FROM movies m
JOIN sources s ON m.source_id = s.id
JOIN actor_movie am ON m.id = am.movie_id
WHERE am.actor_id = :actor_id
ORDER BY m.release_date DESC, m.title ASC
");
$stmt->execute(['actor_id' => $this->id]);
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
}
/**
* Get all TV shows this actor is associated with
*/
public function tvShows()
{
$stmt = $this->pdo->prepare("
SELECT ts.*, s.display_name as source_name
FROM tv_shows ts
JOIN sources s ON ts.source_id = s.id
JOIN actor_tv_show ats ON ts.id = ats.tv_show_id
WHERE ats.actor_id = :actor_id
ORDER BY ts.first_air_date DESC, ts.title ASC
");
$stmt->execute(['actor_id' => $this->id]);
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
}
/**
* Get all adult videos this actor is associated with
*/
public function adultVideos()
{
$stmt = $this->pdo->prepare("
SELECT av.*, s.display_name as source_name
FROM adult_videos av
JOIN sources s ON av.source_id = s.id
JOIN actor_adult_video aav ON av.id = aav.adult_video_id
WHERE aav.actor_id = :actor_id
ORDER BY av.release_date DESC, av.title ASC
");
$stmt->execute(['actor_id' => $this->id]);
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
}
/**
* Get actor statistics
*/
public function getStats(): array
{
$stmt = $this->pdo->prepare("
SELECT
COUNT(DISTINCT am.movie_id) as movie_count,
COUNT(DISTINCT ats.tv_show_id) as tv_show_count,
COUNT(DISTINCT aav.adult_video_id) as adult_video_count,
COUNT(DISTINCT am.movie_id) + COUNT(DISTINCT ats.tv_show_id) + COUNT(DISTINCT aav.adult_video_id) as total_media_count
FROM actors a
LEFT JOIN actor_movie am ON a.id = am.actor_id
LEFT JOIN actor_tv_show ats ON a.id = ats.actor_id
LEFT JOIN actor_adult_video aav ON a.id = aav.actor_id
WHERE a.id = :actor_id
");
$stmt->execute(['actor_id' => $this->id]);
return $stmt->fetch(\PDO::FETCH_ASSOC);
}
/**
* Link actor to a movie
*/
public function linkToMovie(int $movieId): bool
{
$stmt = $this->pdo->prepare("
INSERT IGNORE INTO actor_movie (actor_id, movie_id)
VALUES (:actor_id, :movie_id)
");
return $stmt->execute([
'actor_id' => $this->id,
'movie_id' => $movieId
]);
}
/**
* Link actor to a TV show
*/
public function linkToTvShow(int $tvShowId): bool
{
$stmt = $this->pdo->prepare("
INSERT IGNORE INTO actor_tv_show (actor_id, tv_show_id)
VALUES (:actor_id, :tv_show_id)
");
return $stmt->execute([
'actor_id' => $this->id,
'tv_show_id' => $tvShowId
]);
}
/**
* Link actor to an adult video
*/
public function linkToAdultVideo(int $adultVideoId): bool
{
$stmt = $this->pdo->prepare("
INSERT IGNORE INTO actor_adult_video (actor_id, adult_video_id)
VALUES (:actor_id, :adult_video_id)
");
return $stmt->execute([
'actor_id' => $this->id,
'adult_video_id' => $adultVideoId
]);
}
/**
* Unlink actor from a movie
*/
public function unlinkFromMovie(int $movieId): bool
{
$stmt = $this->pdo->prepare("
DELETE FROM actor_movie
WHERE actor_id = :actor_id AND movie_id = :movie_id
");
return $stmt->execute([
'actor_id' => $this->id,
'movie_id' => $movieId
]);
}
/**
* Unlink actor from a TV show
*/
public function unlinkFromTvShow(int $tvShowId): bool
{
$stmt = $this->pdo->prepare("
DELETE FROM actor_tv_show
WHERE actor_id = :actor_id AND tv_show_id = :tv_show_id
");
return $stmt->execute([
'actor_id' => $this->id,
'tv_show_id' => $tvShowId
]);
}
/**
* Unlink actor from an adult video
*/
public function unlinkFromAdultVideo(int $adultVideoId): bool
{
$stmt = $this->pdo->prepare("
DELETE FROM actor_adult_video
WHERE actor_id = :actor_id AND adult_video_id = :adult_video_id
");
return $stmt->execute([
'actor_id' => $this->id,
'adult_video_id' => $adultVideoId
]);
}
/**
* Get paginated actors with optional search and sorting
*/
public function getPaginated(\PDO $pdo, int $page = 1, int $perPage = 20, string $search = '', string $sort = 'name_asc'): array
{
$offset = ($page - 1) * $perPage;
// Build WHERE clause for search
$whereClause = '';
$params = [];
if (!empty($search)) {
$whereClause = 'WHERE name LIKE :search';
$params['search'] = '%' . $search . '%';
}
// Build ORDER BY clause
$orderBy = match ($sort) {
'name_desc' => 'name DESC',
'media_desc' => '(SELECT COUNT(*) FROM actor_movie WHERE actor_id = actors.id) + (SELECT COUNT(*) FROM actor_tv_show WHERE actor_id = actors.id) + (SELECT COUNT(*) FROM actor_adult_video WHERE actor_id = actors.id) DESC',
'media_asc' => '(SELECT COUNT(*) FROM actor_movie WHERE actor_id = actors.id) + (SELECT COUNT(*) FROM actor_tv_show WHERE actor_id = actors.id) + (SELECT COUNT(*) FROM actor_adult_video WHERE actor_id = actors.id) ASC',
default => 'name ASC'
};
// Get actors with their media counts
$stmt = $pdo->prepare("
SELECT
a.*,
(SELECT COUNT(*) FROM actor_movie WHERE actor_id = a.id) as movie_count,
(SELECT COUNT(*) FROM actor_tv_show WHERE actor_id = a.id) as tv_show_count,
(SELECT COUNT(*) FROM actor_adult_video WHERE actor_id = a.id) as adult_video_count
FROM actors a
{$whereClause}
ORDER BY {$orderBy}
LIMIT :limit OFFSET :offset
");
$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();
$actors = $stmt->fetchAll(\PDO::FETCH_ASSOC);
// Add relationships data for each actor
foreach ($actors as &$actor) {
$actor['movies'] = $this->getActorMovies($actor['id']);
$actor['tvShows'] = $this->getActorTvShows($actor['id']);
$actor['adultVideos'] = $this->getActorAdultVideos($actor['id']);
}
return $actors;
}
/**
* Get total count of actors with optional search
*/
public function getTotalCount(\PDO $pdo, string $search = ''): int
{
$whereClause = '';
$params = [];
if (!empty($search)) {
$whereClause = 'WHERE name LIKE :search';
$params['search'] = '%' . $search . '%';
}
$stmt = $pdo->prepare("SELECT COUNT(*) as count FROM actors {$whereClause}");
foreach ($params as $key => $value) {
$stmt->bindValue(':' . $key, $value);
}
$stmt->execute();
return (int)$stmt->fetch(\PDO::FETCH_ASSOC)['count'];
}
/**
* Get movies for a specific actor (helper method)
*/
private function getActorMovies(int $actorId): array
{
$stmt = $this->pdo->prepare("
SELECT m.id, m.title
FROM movies m
JOIN actor_movie am ON m.id = am.movie_id
WHERE am.actor_id = ?
ORDER BY m.title
");
$stmt->execute([$actorId]);
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
}
/**
* Get TV shows for a specific actor (helper method)
*/
private function getActorTvShows(int $actorId): array
{
$stmt = $this->pdo->prepare("
SELECT ts.id, ts.title
FROM tv_shows ts
JOIN actor_tv_show ats ON ts.id = ats.tv_show_id
WHERE ats.actor_id = ?
ORDER BY ts.title
");
$stmt->execute([$actorId]);
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
}
/**
* Get adult videos for a specific actor (helper method)
*/
private function getActorAdultVideos(int $actorId): array
{
$stmt = $this->pdo->prepare("
SELECT av.id, av.title
FROM adult_videos av
JOIN actor_adult_video aav ON av.id = aav.adult_video_id
WHERE aav.actor_id = ?
ORDER BY av.title
");
$stmt->execute([$actorId]);
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
}
}