* @return array */ private function getReleasesFromGithub(): array { $versionParser = new VersionParser(); $opts = [ 'http' => [ 'method' => 'GET', 'header' => [ 'User-Agent: ' . Constants::SOFTWARE . ' ' . Constants::VERSION . ' Update-Check (PHP)', ], ], ]; $context = stream_context_create($opts); $releases = file_get_contents('https://api.github.com/repos/' . Constants::GITHUB_REPO . '/releases', false, $context); $releases = json_decode($releases); if (!isset($releases[0])) { throw new \Exception('API error - no release found at GitHub repository: ' . Constants::GITHUB_REPO); } $parsed = []; foreach ($releases as $release) { if ($release->draft || $release->prerelease) { continue; } try { $normalized = $versionParser->normalize($release->tag_name); } catch (\UnexpectedValueException $e) { continue; } if (VersionParser::parseStability($normalized) !== 'stable') { continue; } $date = $release->published_at; try { $date = new \DateTimeImmutable($date); } catch (\Exception $ex) { // can be ignored, we return a string } $parsed[$normalized] = [ 'version' => $release->tag_name, 'date' => $date, 'url' => $release->html_url, 'download' => $release->zipball_url, 'content' => $release->body, ]; } $versions = Semver::rsort(array_keys($parsed)); $releases = []; foreach ($versions as $version) { $releases[$version] = $parsed[$version]; } return $releases; } /** * Returns an array with the keys: * - version (string, tag name) * - date (string, release date) * - url (string, web address) * - download (string, ZIP URL) * - content (string, release notes) * * @param bool $compatible * @return array{'version': string, 'date': \DateTimeInterface, 'url': string, 'download': string, 'content': string}|null * @throws \Exception */ public function getLatestReleaseFromGithub(bool $compatible): ?array { foreach ($this->getReleasesFromGithub() as $release) { $releaseVersion = $release['version']; if ($compatible && !$this->satisfiesMajorVersionConstraint($releaseVersion)) { continue; } return $release; } return null; } private function satisfiesMajorVersionConstraint(string $releaseVersion): bool { if (preg_match('/^v?(\d+)/', Constants::VERSION, $matches)) { return Semver::satisfies($releaseVersion, '^' . $matches[1]); } return false; } }