cache), true); $gespeichert = is_array($gespeichert) && is_string($gespeichert['version'] ?? null) ? $gespeichert : null; if (!$frisch && null !== $gespeichert && (int) ($gespeichert['geholt'] ?? 0) > time() - self::GUELTIG) { return $gespeichert; } $neu = $this->holen(); if (null === $neu) { return $gespeichert; } @file_put_contents($this->cache, json_encode([...$neu, 'geholt' => time()])); return $neu; } /** @return array{version: string, name: string, published: string}|null */ private function holen(): ?array { if (!str_starts_with($this->api, 'https://')) { return null; } $kontext = stream_context_create([ 'http' => ['timeout' => 8, 'ignore_errors' => true, 'header' => "User-Agent: KantSites-Zentrale\r\nAccept: application/json\r\n"], 'ssl' => ['verify_peer' => true, 'verify_peer_name' => true], ]); if (function_exists('curl_init')) { $curl = curl_init(rtrim($this->api, '/').'/releases/latest'); curl_setopt_array($curl, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_PROTOCOLS => CURLPROTO_HTTPS, CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_TIMEOUT => 8, CURLOPT_USERAGENT => 'KantSites-Zentrale', ]); $antwort = curl_exec($curl); $status = (int) curl_getinfo($curl, CURLINFO_RESPONSE_CODE); curl_close($curl); $antwort = 200 === $status ? $antwort : false; } else { $antwort = @file_get_contents(rtrim($this->api, '/').'/releases/latest', false, $kontext); } $daten = is_string($antwort) ? json_decode($antwort, true) : null; if (!is_array($daten) || 1 !== preg_match('/^v(\d+\.\d+\.\d+)$/D', (string) ($daten['tag_name'] ?? ''), $treffer)) { return null; } return ['version' => $treffer[1], 'name' => (string) ($daten['name'] ?? ''), 'published' => (string) ($daten['published_at'] ?? '')]; } }