ensureCliAccess(); $this->loadEnvironment(); } private function loadEnvironment(): void { $this->postgrestUrl = $_ENV["POSTGREST_URL"] ?? getenv("POSTGREST_URL"); $this->postgrestApiKey = $_ENV["POSTGREST_API_KEY"] ?? getenv("POSTGREST_API_KEY"); $this->tmdbApiKey = $_ENV["TMDB_API_KEY"] ?? getenv("TMDB_API_KEY"); $this->tmdbImportToken = $_ENV["WATCHING_IMPORT_TOKEN"] ?? getenv("WATCHING_IMPORT_TOKEN"); } public function handleRequest(): void { $input = json_decode(file_get_contents("php://input"), true); if (!$input) $this->sendErrorResponse("Invalid or missing JSON body", 400); $providedToken = $input["token"] ?? null; if (!$providedToken || $providedToken !== $this->tmdbImportToken) $this->sendErrorResponse("Unauthorized access", 401); $tmdbId = $input["tmdb_id"] ?? null; $mediaType = $input["media_type"] ?? null; if (!$tmdbId || !$mediaType) $this->sendErrorResponse("tmdb_id and media_type are required", 400); try { $mediaData = $this->fetchTMDBData($tmdbId, $mediaType); $this->processMedia($mediaData, $mediaType); $this->sendResponse("Media imported successfully", 200); } catch (Exception $e) { $this->sendErrorResponse("Error: " . $e->getMessage(), 500); } } private function fetchTMDBData(string $tmdbId, string $mediaType): array { $client = new Client(); $url = "https://api.themoviedb.org/3/{$mediaType}/{$tmdbId}"; $response = $client->get($url, [ "query" => ["api_key" => $this->tmdbApiKey], "headers" => ["Accept" => "application/json"], ]); $data = json_decode($response->getBody(), true); if (empty($data)) throw new Exception("No data found for TMDB ID: {$tmdbId}"); return $data; } private function processMedia(array $mediaData, string $mediaType): void { $id = $mediaData["id"]; $title = $mediaType === "movie" ? $mediaData["title"] : $mediaData["name"]; $year = $mediaData["release_date"] ?? ($mediaData["first_air_date"] ?? null); $year = $year ? substr($year, 0, 4) : null; $description = $mediaData["overview"] ?? ""; $tags = array_map( fn($genre) => strtolower(trim($genre["name"])), $mediaData["genres"] ); $slug = $mediaType === "movie" ? "/watching/movies/{$id}" : "/watching/shows/{$id}"; $payload = [ "title" => $title, "year" => $year, "description" => $description, "tmdb_id" => $id, "slug" => $slug, ]; $response = $this->fetchFromPostgREST( $mediaType === "movie" ? "movies" : "shows", "", "POST", $payload ); if (empty($response["id"])) { $queryResponse = $this->fetchFromPostgREST( $mediaType === "movie" ? "movies" : "shows", "tmdb_id=eq.{$id}", "GET" ); $response = $queryResponse[0] ?? []; } if (!empty($response["id"])) { $mediaId = $response["id"]; $existingTagMap = $this->getTagIds($tags); $updatedTagMap = $this->insertMissingTags($tags, $existingTagMap); $this->associateTagsWithMedia( $mediaType, $mediaId, array_values($updatedTagMap) ); } } private function getTagIds(array $tags): array { $existingTagMap = []; foreach ($tags as $tag) { $query = "name=ilike." . urlencode($tag); $existingTags = $this->fetchFromPostgREST("tags", $query, "GET"); if (!empty($existingTags[0]["id"])) $existingTagMap[strtolower($tag)] = $existingTags[0]["id"]; } return $existingTagMap; } private function insertMissingTags(array $tags, array $existingTagMap): array { $newTags = array_diff($tags, array_keys($existingTagMap)); foreach ($newTags as $newTag) { try { $response = $this->fetchFromPostgREST("tags", "", "POST", [ "name" => $newTag, ]); if (!empty($response["id"])) $existingTagMap[$newTag] = $response["id"]; } catch (Exception $e) { $queryResponse = $this->fetchFromPostgREST( "tags", "name=eq.{$newTag}", "GET" ); if (!empty($queryResponse[0]["id"])) $existingTagMap[$newTag] = $queryResponse[0]["id"]; } } return $existingTagMap; } private function associateTagsWithMedia( string $mediaType, int $mediaId, array $tagIds ): void { $junctionTable = $mediaType === "movie" ? "movies_tags" : "shows_tags"; $mediaColumn = $mediaType === "movie" ? "movies_id" : "shows_id"; foreach ($tagIds as $tagId) { $this->fetchFromPostgREST($junctionTable, "", "POST", [ $mediaColumn => $mediaId, "tags_id" => $tagId, ]); } } } $handler = new WatchingImportHandler(); $handler->handleRequest();