get($moduleName); $error = null; $notice = null; $testGroup = null; $dbTestMessages = []; require_admin(); if (!$module) { http_response_code(404); echo '
Modul nicht gefunden.
'; return; } $fields = (array)($module['setup']['fields'] ?? []); $fieldTypes = []; $fieldMeta = []; foreach ($fields as $field) { $fname = (string)($field['name'] ?? ''); if ($fname === '') { continue; } $fieldTypes[$fname] = (string)($field['type'] ?? 'text'); $fieldMeta[$fname] = $field; } $current = modules()->settings($moduleName); $defaults = $module['db_defaults'] ?? []; if (empty($current['db']) && is_array($defaults)) { $current['db'] = $defaults; } $metadataDefaults = $module['metadata_db_defaults'] ?? []; if (empty($current['metadata_db']) && is_array($metadataDefaults)) { $current['metadata_db'] = $metadataDefaults; } $dbDefaultsByGroup = [ 'db' => is_array($defaults) ? $defaults : [], 'metadata_db' => is_array($metadataDefaults) ? $metadataDefaults : [], ]; $setNested = function (array &$target, string $path, mixed $value): void { $parts = explode('.', $path); $last = array_pop($parts); $node = &$target; foreach ($parts as $part) { if (!isset($node[$part]) || !is_array($node[$part])) { $node[$part] = []; } $node = &$node[$part]; } if ($last !== null && $last !== '') { $node[$last] = $value; } }; $getNested = function (array $source, string $path): mixed { $node = $source; foreach (explode('.', $path) as $part) { if (!is_array($node) || !array_key_exists($part, $node)) { return null; } $node = $node[$part]; } return $node; }; $dbGroups = []; $fieldsByDbGroup = []; $generalFields = []; foreach ($fields as $field) { $name = (string)($field['name'] ?? ''); if (!str_contains($name, '.')) { continue; } [$group, $key] = explode('.', $name, 2); if ($key !== 'driver') { continue; } $label = (string)($field['label'] ?? $group); $label = trim(preg_replace('/\s+DB\s+Driver$/i', ' DB', $label) ?? $label); $label = $label !== '' ? $label : $group; $dbGroups[$group] = $label; } foreach ($fields as $field) { $name = (string)($field['name'] ?? ''); if (str_contains($name, '.')) { [$group] = explode('.', $name, 2); if (array_key_exists($group, $dbGroups)) { $fieldsByDbGroup[$group][] = $field; continue; } } $generalFields[] = $field; } $driverOptions = [ 'pgsql' => 'PostgreSQL', 'mysql' => 'MySQL / MariaDB', 'sqlite' => 'SQLite', ]; $describeDbConfig = static function (array $dbConfig): string { $driver = (string)($dbConfig['driver'] ?? ''); $host = (string)($dbConfig['host'] ?? ''); $port = (string)($dbConfig['port'] ?? ''); return 'Aktive Einstellung: Treiber ' . ($driver !== '' ? $driver : 'nicht gesetzt') . ', Host ' . ($host !== '' ? $host : 'nicht gesetzt') . ', Port ' . ($port !== '' ? $port : 'nicht gesetzt') . '.'; }; $describeDbDefaults = static function (array $dbDefaults): string { $driver = (string)($dbDefaults['driver'] ?? ''); $host = (string)($dbDefaults['host'] ?? ''); $port = (string)($dbDefaults['port'] ?? ''); if ($driver === '' && $host === '' && $port === '') { return ''; } return 'Standard: Treiber ' . ($driver !== '' ? $driver : 'nicht gesetzt') . ', Host ' . ($host !== '' ? $host : 'nicht gesetzt') . ', Port ' . ($port !== '' ? $port : 'nicht gesetzt') . '.'; }; $dbConfigWarning = static function (array $dbConfig): ?string { $driver = (string)($dbConfig['driver'] ?? ''); $port = (string)($dbConfig['port'] ?? ''); if ($driver === 'pgsql' && $port === '3306') { return 'Port 3306 ist typisch fuer MySQL/MariaDB, aber als Treiber ist PostgreSQL ausgewaehlt. Bitte den Treiber auf MySQL / MariaDB stellen.'; } if ($driver === 'mysql' && $port === '5432') { return 'Port 5432 ist typisch fuer PostgreSQL, aber als Treiber ist MySQL / MariaDB ausgewaehlt. Bitte Port oder Treiber pruefen.'; } return null; }; $dbConfigHint = static function (string $group, array $dbConfig, array $dbDefaults): ?string { if ($group !== 'metadata_db') { return null; } $driver = (string)($dbConfig['driver'] ?? ''); $host = (string)($dbConfig['host'] ?? ''); $port = (string)($dbConfig['port'] ?? ''); $defaultDriver = (string)($dbDefaults['driver'] ?? ''); $defaultHost = (string)($dbDefaults['host'] ?? ''); $defaultPort = (string)($dbDefaults['port'] ?? ''); if ($driver !== $defaultDriver || $host !== $defaultHost || $port !== $defaultPort) { return 'Diese Verbindung ist fuer Nexus-eigene DHCP-Zusatzinfos gedacht, nicht fuer die Nexus-App/Base-DB. Erwartet wird normalerweise: ' . ($defaultDriver !== '' ? $defaultDriver : 'Treiber offen') . ' auf ' . ($defaultHost !== '' ? $defaultHost : 'Host offen') . ':' . ($defaultPort !== '' ? $defaultPort : 'Port offen') . '.'; } 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; } $normalized = strtolower(trim($value)); return match ($normalized) { 'postgres', 'postgresql' => 'pgsql', 'mariadb', 'mysql/mariadb', 'mysql / mariadb' => 'mysql', default => $normalized, }; }; $renderField = function (array $field) use (&$current, $getNested, $driverOptions): void { $name = (string)($field['name'] ?? ''); if ($name === '') { return; } $label = (string)($field['label'] ?? $name); $type = (string)($field['type'] ?? 'text'); $required = !empty($field['required']); $help = (string)($field['help'] ?? $field['description'] ?? ''); $postKey = str_replace('.', '_', $name); $value = ''; if ($name === 'kea_auto_init') { $value = !empty($current[$name]) ? '1' : '0'; } elseif (str_contains($name, '.')) { $value = (string)($getNested($current, $name) ?? ''); } else { $value = (string)($current[$name] ?? ''); } ?> 'error', 'text' => 'Fuer diese Datenbank sind keine Standardwerte hinterlegt.', ]; } else { $current[$postedResetGroup] = $dbDefaultsByGroup[$postedResetGroup]; $dbTestMessages[$postedResetGroup] = [ 'type' => 'success', 'text' => 'Standardwerte geladen. Bitte pruefen und speichern.', ]; } } elseif ($postedTestGroup !== '') { $testGroup = $postedTestGroup; if (!array_key_exists($postedTestGroup, $dbGroups)) { $error = 'Unbekannte Datenbank-Konfiguration.'; } else { $dbConfig = $getNested($current, $postedTestGroup); if (!is_array($dbConfig)) { $dbTestMessages[$postedTestGroup] = [ 'type' => 'error', 'text' => 'Datenbank-Konfiguration ist unvollstaendig.', ]; } else { $warning = $dbConfigWarning($dbConfig); if ($warning !== null) { $dbTestMessages[$postedTestGroup] = [ 'type' => 'error', 'text' => $warning . ' ' . $describeDbConfig($dbConfig), ]; } else { try { $dbConfig['options'] = array_replace([ \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC, ], (array)($dbConfig['options'] ?? [])); $testPdo = \App\Database::createFromArray($dbConfig); $testPdo->query('SELECT 1')->fetchColumn(); $dbTestMessages[$postedTestGroup] = [ 'type' => 'success', 'text' => 'Verbindung erfolgreich. ' . $describeDbConfig($dbConfig), ]; } catch (\Throwable $e) { $dbTestMessages[$postedTestGroup] = [ 'type' => 'error', 'text' => 'Verbindung fehlgeschlagen. ' . $describeDbConfig($dbConfig) . ' ' . $e->getMessage(), ]; } } } } } else { modules()->saveSettings($moduleName, $payload); $notice = 'Setup gespeichert.'; $module = modules()->get($moduleName) ?: $module; } } $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) ?? ''); ?>
Setup

– Einrichtung

Trage die benötigten Informationen für das Modul ein.

Allgemein

Moduleinstellungen

Status

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

Datenbanken

Verbindungen

Jede Verbindung kann getrennt konfiguriert und getestet werden.

$label): ?>
$label): ?>
>

konfigurieren