requireAdmin(); I18n::init(); $db = Database::getInstance(); $appTitle = $db->getSetting('app_title', 'UniFi Voucher System'); $defaultExpire = max(1, (int)$db->getSetting('default_expire_minutes', 480)); $defaultMaxUses = max(1, (int)$db->getSetting('default_max_uses', 1)); $error = ''; $success = ''; $results = []; if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['do_import'])) { if (!$auth->validateCsrfToken($_POST['csrf_token'] ?? '')) { $error = __('error_csrf'); } else { try { $siteId = (int)($_POST['site_id'] ?? 0); $site = $db->fetchOne("SELECT * FROM sites WHERE id=? AND is_active=1", [$siteId]); if (!$site) throw new Exception('Site nicht gefunden'); // CSV-Quelle: Datei bevorzugt, sonst Textarea $raw = ''; if (!empty($_FILES['csv']['tmp_name'])) { $raw = file_get_contents($_FILES['csv']['tmp_name']); } else { $raw = (string)($_POST['csv_text'] ?? ''); } $lines = preg_split('/\r\n|\r|\n/', trim($raw)); if (count($lines) > 200) throw new Exception('Maximal 200 Zeilen pro Import.'); $controller = new UniFiController( $site['unifi_controller_url'], $site['unifi_username'], Crypto::decrypt($site['unifi_password']), $site['site_id'] ); $created = 0; foreach ($lines as $i => $line) { $line = trim($line); if ($line === '') continue; $cols = str_getcsv($line); $name = trim((string)($cols[0] ?? '')); if ($name === '' || strtolower($name) === 'name') continue; // Header/leer überspringen $maxUses = isset($cols[1]) && $cols[1] !== '' ? max(1, (int)$cols[1]) : $defaultMaxUses; $expire = isset($cols[2]) && $cols[2] !== '' ? max(1, (int)$cols[2]) : $defaultExpire; try { $v = $controller->createVoucher(date('Y-m-d') . '_' . $name, $maxUses, $expire); if (!is_array($v) || empty($v['formatted_code'])) throw new Exception('ungültige Antwort'); $db->execute( "INSERT INTO vouchers (site_id, user_id, voucher_code, voucher_name, max_uses, expire_minutes, unifi_voucher_id) VALUES (?, ?, ?, ?, ?, ?, ?)", [$siteId, $_SESSION['user_id'], $v['code'], date('Y-m-d') . '_' . $name, $maxUses, $expire, $v['unifi_id'] ?? null] ); $results[] = ['name' => $name, 'code' => $v['formatted_code'], 'ok' => true]; $created++; } catch (Exception $e) { $results[] = ['name' => $name, 'code' => $e->getMessage(), 'ok' => false]; } } if ($created > 0) { Notifier::voucherCreated($created, $site['name'], $_SESSION['user_name'] ?? null); $auth->writeAuditLog($_SESSION['user_id'], 'voucher_import', 'site', $siteId, "$created Voucher importiert"); } $success = "$created Voucher erstellt."; } catch (Exception $e) { $error = $e->getMessage(); } } } $sites = $db->fetchAll("SELECT * FROM sites WHERE is_active=1 ORDER BY name"); $csrf = $auth->getCsrfToken(); $currentPage = 'import'; $adminBase = ''; ?>
Eine Zeile pro Voucher: Name,MaxGeräte,Minuten – MaxGeräte und Minuten sind optional (Standardwerte greifen). Max. 200 Zeilen. Beispiel:
Gast Müller,1,480 · Konferenzraum A,5,240 · Tagespass
| Name | Code / Fehler | Status |
|---|---|---|
| = htmlspecialchars($r['name']) ?> | = htmlspecialchars($r['code']) ?> | = $r['ok'] ? '✅' : '❌' ?> |