pdo = $pdo; } public function show(Request $request, Response $response, $args) { $actorId = $args['id']; // Get actor details with counts from all media types $stmt = $this->pdo->prepare(" SELECT a.*, 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 GROUP BY a.id "); $stmt->execute(['actor_id' => $actorId]); $actor = $stmt->fetch(PDO::FETCH_ASSOC); if (!$actor) { return $response->withStatus(404)->withHeader('Content-Type', 'text/html'); } // Get actor's adult videos (scenes) $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' => $actorId]); $scenes = $stmt->fetchAll(PDO::FETCH_ASSOC); // Get actor's 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' => $actorId]); $movies = $stmt->fetchAll(PDO::FETCH_ASSOC); // Get actor's TV shows $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' => $actorId]); $tvShows = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($scenes as &$scene) { if (!empty($scene['metadata'])) { $metadata = json_decode($scene['metadata'], true); // Use local cover path if available, otherwise fall back to original URL if (!empty($metadata['local_cover_path'])) { $scene['poster_url'] = $metadata['local_cover_path']; } elseif (!empty($metadata['cover_url'])) { $scene['poster_url'] = $metadata['cover_url']; } // Add actors data if available if (!empty($metadata['actors'])) { $scene['actors'] = $metadata['actors']; } } } return $this->view->render($response, 'actor/show.twig', [ 'title' => $actor['name'], 'actor' => $actor, 'scenes' => $scenes, 'movies' => $movies, 'tv_shows' => $tvShows ]); } public function index(Request $request, Response $response, $args) { // Get all actors with their media counts from all types $stmt = $this->pdo->prepare(" SELECT a.*, COUNT(DISTINCT aav.adult_video_id) as adult_video_count, COUNT(DISTINCT am.movie_id) as movie_count, COUNT(DISTINCT ats.tv_show_id) as tv_show_count, (COUNT(DISTINCT aav.adult_video_id) + COUNT(DISTINCT am.movie_id) + COUNT(DISTINCT ats.tv_show_id)) as total_media_count, MAX(COALESCE(av.release_date, m.release_date, ts.first_air_date)) as latest_media_date FROM actors a LEFT JOIN actor_adult_video aav ON a.id = aav.actor_id LEFT JOIN adult_videos av ON aav.adult_video_id = av.id LEFT JOIN actor_movie am ON a.id = am.actor_id LEFT JOIN movies m ON am.movie_id = m.id LEFT JOIN actor_tv_show ats ON a.id = ats.actor_id LEFT JOIN tv_shows ts ON ats.tv_show_id = ts.id GROUP BY a.id ORDER BY total_media_count DESC, a.name ASC LIMIT 50 "); $stmt->execute(); $actors = $stmt->fetchAll(PDO::FETCH_ASSOC); return $this->view->render($response, 'actor/index.twig', [ 'title' => 'Actors & Performers', 'actors' => $actors ]); } }