apiBase, rawurlencode($owner), rawurlencode($repo), rawurlencode($state), $page, self::PER_PAGE ); $pageIssues = $this->fetch($url); if ($pageIssues === []) { break; } foreach ($pageIssues as $issue) { $issues[] = [ 'number' => (int) $issue['number'], 'title' => (string) $issue['title'], 'body' => isset($issue['body']) ? (string) $issue['body'] : null, 'labels' => array_map( static fn (array $label): array => [ 'name' => (string) $label['name'], 'color' => (string) $label['color'], ], $issue['labels'] ?? [] ), ]; } if (count($pageIssues) < self::PER_PAGE) { break; } } return $issues; } /** @return array> */ private function fetch(string $url): array { $headers = ['Accept: application/json']; if ($this->token !== null && $this->token !== '') { $headers[] = 'Authorization: token ' . $this->token; } $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => $headers, CURLOPT_TIMEOUT => 15, ]); $body = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); $error = curl_error($ch); curl_close($ch); if ($body === false) { throw new RuntimeException('Codeberg-API nicht erreichbar: ' . $error); } if ($status >= 400) { throw new RuntimeException('Codeberg-API-Fehler (HTTP ' . $status . '): ' . $body); } $decoded = json_decode((string) $body, true); return is_array($decoded) ? $decoded : []; } }