diff --git a/partials/landingpages/modules/setup.php b/partials/landingpages/modules/setup.php index adc2072..8fa80a1 100644 --- a/partials/landingpages/modules/setup.php +++ b/partials/landingpages/modules/setup.php @@ -168,6 +168,76 @@ $dbConfigHint = static function (string $group, array $dbConfig, array $dbDefaul return null; }; +$fetchJsonWithApiKey = static function (string $url, string $apiKey, int $timeout = 10): array { + $headers = [ + 'Accept: application/json', + 'x-api-key: ' . $apiKey, + ]; + + $responseBody = null; + $httpCode = 0; + $curlError = ''; + + if (function_exists('curl_init')) { + $ch = curl_init($url); + if ($ch !== false) { + curl_setopt_array($ch, [ + CURLOPT_RETURNTRANSFER => true, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_TIMEOUT => $timeout, + CURLOPT_CONNECTTIMEOUT => min(5, $timeout), + CURLOPT_HTTPHEADER => $headers, + ]); + $responseBody = curl_exec($ch); + $curlError = curl_error($ch); + $httpCode = (int) curl_getinfo($ch, CURLINFO_RESPONSE_CODE); + curl_close($ch); + } + } + + if (!is_string($responseBody) || $responseBody === '') { + $context = stream_context_create([ + 'http' => [ + 'method' => 'GET', + 'timeout' => $timeout, + 'header' => implode("\r\n", $headers) . "\r\n", + ], + ]); + $responseBody = @file_get_contents($url, false, $context); + } + + if (!is_string($responseBody) || $responseBody === '') { + return [ + 'ok' => false, + 'message' => 'Abruf fehlgeschlagen.' + . ($curlError !== '' ? ' ' . $curlError : '') + . ($httpCode > 0 ? ' HTTP ' . $httpCode : ''), + ]; + } + + $decoded = json_decode($responseBody, true); + if (!is_array($decoded)) { + return [ + 'ok' => false, + 'message' => 'Antwort ist kein gueltiges JSON.', + ]; + } + + foreach (['error', 'message', 'detail'] as $errorKey) { + if (isset($decoded[$errorKey]) && is_string($decoded[$errorKey]) && trim($decoded[$errorKey]) !== '') { + return [ + 'ok' => false, + 'message' => trim((string) $decoded[$errorKey]), + ]; + } + } + + return [ + 'ok' => true, + 'data' => $decoded, + ]; +}; + $normalizeDriver = static function (mixed $value): mixed { if (!is_string($value)) { return $value; @@ -327,6 +397,46 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { } } +$moduleStatusPanel = null; +if ($moduleName === 'boersenchecker') { + $quotaApiKey = trim((string) ($current['bavest_api_key'] ?? '')); + if ($quotaApiKey === '') { + $moduleStatusPanel = [ + 'title' => 'Bavest Quota', + 'type' => 'hint', + 'text' => 'Kein Bavest API Key hinterlegt. Nach dem Speichern wird hier die aktuelle Quota automatisch angezeigt.', + 'stats' => [], + ]; + } else { + $quotaTimeout = (int) ($current['bavest_timeout_sec'] ?? 10); + $quotaTimeout = $quotaTimeout > 0 ? $quotaTimeout : 10; + $quotaResult = $fetchJsonWithApiKey('https://api.bavest.co/v2/account/quota', $quotaApiKey, $quotaTimeout); + + if (!empty($quotaResult['ok'])) { + $quotaData = is_array($quotaResult['data']['data'] ?? null) ? $quotaResult['data']['data'] : []; + $moduleStatusPanel = [ + 'title' => 'Bavest Quota', + 'type' => 'success', + 'text' => 'Quota erfolgreich geprueft.', + 'stats' => [ + ['label' => 'Periode', 'value' => (string) ($quotaData['period'] ?? '-')], + ['label' => 'Verbrauch', 'value' => (string) ($quotaData['usage'] ?? '0')], + ['label' => 'Limit', 'value' => ($quotaData['limit'] ?? null) !== null ? (string) $quotaData['limit'] : 'unbegrenzt'], + ['label' => 'Verbleibend', 'value' => ($quotaData['remaining'] ?? null) !== null ? (string) $quotaData['remaining'] : 'unbegrenzt'], + ['label' => 'API-Key ID', 'value' => (string) ($quotaData['apiKey'] ?? '-')], + ], + ]; + } else { + $moduleStatusPanel = [ + 'title' => 'Bavest Quota', + 'type' => 'error', + 'text' => 'Quota konnte nicht geprueft werden: ' . (string) ($quotaResult['message'] ?? 'Unbekannter Fehler'), + 'stats' => [], + ]; + } + } +} + $activeDbGroup = $testGroup !== null && array_key_exists($testGroup, $dbGroups) ? $testGroup : (array_key_first($dbGroups) ?? ''); @@ -363,6 +473,31 @@ $activeDbGroup = $testGroup !== null && array_key_exists($testGroup, $dbGroups) + +
+
+
+ Status +

+

Der Status wird beim Aufruf der Setup-Seite automatisch geprueft.

+
+
+
+ +
+ +
+ + + +
+ +
+ +