isLocalCacheAvailable()) { $this->cache = $cacheFactory->createLocal('GPodderSync-Podcasts'); } $this->httpClient = $httpClientService->newClient(); $this->subscriptionChangeRepository = $subscriptionChangeRepository; } public function getCachedOrFetchPodcastData(string $url, string $userId): ?PodcastData { if ($this->cache == null) { return $this->fetchPodcastData($url, $userId); } $oldData = $this->tryGetCachedPodcastData($url); if ($oldData) { return $oldData; } $newData = $this->fetchPodcastData($url, $userId); $this->trySetCachedPodcastData($url, $newData); return $newData; } private function userHasPodcast(string $url, string $userId): bool { $subscriptionChanges = $this->subscriptionChangeRepository->findByUrl($url, $userId); return $subscriptionChanges !== null; } public function fetchPodcastData(string $url, string $userId): ?PodcastData { if (!$this->userHasPodcast($url, $userId)) { return null; } $resp = $this->fetchUrl($url); $data = PodcastData::parseRssXml($resp->getBody()); $blob = $this->tryFetchImageBlob($data); if ($blob) { $data->setImageBlob($blob); } return $data; } private function tryFetchImageBlob(PodcastData $data): ?string { if (!$data->getImageUrl()) { return null; } try { $resp = $this->fetchUrl($data->getImageUrl()); $contentType = $resp->getHeader('Content-Type'); $body = $resp->getBody(); $bodyBase64 = base64_encode($body); return "data:$contentType;base64,$bodyBase64"; } catch (Exception $e) { return null; } } private function fetchUrl(string $url): IResponse { $resp = $this->httpClient->get($url); $statusCode = $resp->getStatusCode(); if ($statusCode < 200 || $statusCode >= 300) { throw new \ErrorException("Web request returned non-2xx status code: $statusCode"); } return $resp; } public function tryGetCachedPodcastData(string $url): ?PodcastData { $oldData = $this->cache->get($url); if (!$oldData) { return null; } return PodcastData::fromArray($oldData); } public function trySetCachedPodcastData(string $url, PodcastData $data): bool { return $this->cache->set($url, $data->toArray()); } }