pdo = $pdo; } public function index(Request $request, Response $response, $args) { $queryParams = $request->getQueryParams(); // Get pagination parameters $page = max(1, (int)($queryParams['page'] ?? 1)); $perPage = max(12, min(100, (int)($queryParams['per_page'] ?? 24))); // Get search parameters $search = trim($queryParams['search'] ?? ''); // Get view mode $viewMode = $queryParams['view'] ?? 'grid'; // grid, list, covers // Get movies with pagination and search $movies = Movie::getAllWithPagination($this->pdo, $page, $perPage, $search); // Get total count for pagination $totalCount = Movie::getTotalCount($this->pdo, $search); // Calculate pagination info $totalPages = ceil($totalCount / $perPage); $hasNextPage = $page < $totalPages; $hasPrevPage = $page > 1; return $this->view->render($response, 'movies/index.twig', [ 'title' => 'Movies', 'movies' => $movies, 'pagination' => [ 'current_page' => $page, 'per_page' => $perPage, 'total_pages' => $totalPages, 'total_items' => $totalCount, 'has_next' => $hasNextPage, 'has_prev' => $hasPrevPage, 'next_page' => $page + 1, 'prev_page' => $page - 1 ], 'search' => $search, 'view_mode' => $viewMode, 'view_modes' => ['grid', 'list', 'covers'] ]); } public function show(Request $request, Response $response, $args) { $movieId = (int) $args['id']; // Get movie details $stmt = $this->pdo->prepare(" SELECT m.*, s.display_name as source_name FROM movies m JOIN sources s ON m.source_id = s.id WHERE m.id = :id "); $stmt->execute(['id' => $movieId]); $movie = $stmt->fetch(\PDO::FETCH_ASSOC); if (!$movie) { return $response->withStatus(404); } // Decode metadata for display $metadata = json_decode($movie['metadata'], true); return $this->view->render($response, 'movies/show.twig', [ 'title' => $movie['title'], 'movie' => $movie, 'metadata' => $metadata ]); } }