= $maxRequests) { $_SESSION['voucher_create_times'] = $timestamps; return true; } $timestamps[] = $now; $_SESSION['voucher_create_times'] = $timestamps; return false; } $appTitle = $db->getSetting('app_title', 'UniFi Voucher System'); $logoUrl = $db->getSetting('logo_url', ''); $instructionHeader = $db->getSetting('instruction_header', ''); $instructionText = $db->getSetting('instruction_text', ''); $publicAccess = $db->getSetting('public_access', 0); $smtpEnabled = $db->getSetting('smtp_enabled', '0') === '1'; $printTemplate = $db->getSetting('print_template', '

{APP_TITLE}

WLAN Zugangscode

{VOUCHER_CODE}

Gültig bis: {EXPIRY_DATE} {EXPIRY_TIME}

Standort: {SITE_NAME}

Maximale Geräte: {MAX_USES}


{INSTRUCTIONS}
'); $defaultExpire = max(1, (int)$db->getSetting('default_expire_minutes', 480)); $defaultMaxUses = max(1, (int)$db->getSetting('default_max_uses', 1)); $maxUsesLimit = max(1, (int)$db->getSetting('max_uses_limit', 10)); if (!$publicAccess && !$auth->isLoggedIn()) { header('Location: login.php'); exit; } try { $templates = $db->fetchAll("SELECT * FROM voucher_templates WHERE is_active = 1 ORDER BY name"); } catch (Exception $e) { $templates = []; } $error = ''; $success = ''; $voucherCode = ''; $voucherCreated = false; $voucherData = []; $bulkVouchers = []; $bulkCreated = false; if ($auth->isLoggedIn()) { if ($auth->isAdmin()) { $sites = $db->fetchAll("SELECT * FROM sites WHERE is_active = 1 ORDER BY name"); } else { $sites = $db->fetchAll( "SELECT s.* FROM sites s INNER JOIN user_site_access usa ON s.id = usa.site_id WHERE s.is_active = 1 AND usa.user_id = ? ORDER BY s.name", [$_SESSION['user_id']] ); } } else { $sites = $db->fetchAll("SELECT * FROM sites WHERE is_active = 1 AND public_access = 1 ORDER BY name"); } $autoSelectSite = (count($sites) === 1) ? $sites[0]['id'] : 0; // Helper: create one voucher and save to DB function doCreateVoucher($db, $site, $voucherName, $maxUses, $expireMinutes, $userId, $qos = []) { $datum = date('Y-m-d'); $fullName = $datum . '_' . $voucherName; $controller = new UniFiController( $site['unifi_controller_url'], $site['unifi_username'], Crypto::decrypt($site['unifi_password']), $site['site_id'] ); $voucher = $controller->createVoucher($fullName, $maxUses, $expireMinutes, $qos); if (!is_array($voucher) || empty($voucher['formatted_code'])) { throw new Exception(__('error_voucher_invalid')); } $db->execute( "INSERT INTO vouchers (site_id, user_id, voucher_code, voucher_name, max_uses, expire_minutes, unifi_voucher_id) VALUES (?, ?, ?, ?, ?, ?, ?)", [$site['id'], $userId, $voucher['code'], $fullName, $maxUses, $expireMinutes, $voucher['unifi_id'] ?? null] ); $expiryTs = time() + ($expireMinutes * 60); return [ 'code' => $voucher['formatted_code'], 'site_name' => $site['name'], 'max_uses' => $maxUses, 'expire_min' => $expireMinutes, 'expiry_date' => date('d.m.Y', $expiryTs), 'expiry_time' => date('H:i', $expiryTs), ]; } // Single voucher if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['create_voucher'])) { if (!$publicAccess && !$auth->isLoggedIn()) { $error = __('error_login_req'); } elseif (!$auth->validateCsrfToken($_POST['csrf_token'] ?? '')) { // CSRF fuer ALLE (auch anonyme oeffentliche Erstellung) $error = __('error_csrf'); } elseif (!$auth->isLoggedIn() && isVoucherRateLimited()) { $error = 'Zu viele Anfragen. Bitte warten Sie einen Moment.'; } else { try { $siteId = (int)($_POST['site_id'] ?? 0); $voucherName = trim((string)($_POST['voucher_name'] ?? '')); $maxUses = (int)($_POST['max_uses'] ?? $defaultMaxUses); $expireMinutes = max(1, (int)($_POST['expire_minutes'] ?? $defaultExpire)); $sendEmail = isset($_POST['send_email']) && !empty($_POST['recipient_email']); $recipientEmail= trim((string)($_POST['recipient_email'] ?? '')); if (empty($voucherName)) throw new Exception(__('error_name_req')); if ($maxUses < 1 || $maxUses > $maxUsesLimit) throw new Exception(__('error_devices_range', ['max' => $maxUsesLimit])); if ($siteId <= 0) throw new Exception(__('error_site_req')); if ($sendEmail && !filter_var($recipientEmail, FILTER_VALIDATE_EMAIL)) throw new Exception(__('error_email_invalid')); if ($auth->isLoggedIn() && !$auth->hasAccessToSite($siteId)) throw new Exception(__('error_site_no_perm')); $site = $db->fetchOne("SELECT * FROM sites WHERE id = ? AND is_active = 1", [$siteId]); if (!$site) throw new Exception(__('error_site_not_found')); $userId = $auth->isLoggedIn() ? ($_SESSION['user_id'] ?? null) : null; $qos = [ 'down' => max(0, (int)($_POST['qos_down'] ?? 0)), 'up' => max(0, (int)($_POST['qos_up'] ?? 0)), 'quota_mb' => max(0, (int)($_POST['qos_quota'] ?? 0)), ]; $voucherData = doCreateVoucher($db, $site, $voucherName, $maxUses, $expireMinutes, $userId, $qos); $voucherCode = $voucherData['code']; $voucherCreated = true; Notifier::voucherCreated(1, $site['name'], $_SESSION['user_name'] ?? null); if ($sendEmail && !empty($recipientEmail)) { $mailer->sendVoucherEmail($recipientEmail, $voucherCode, $site['name'], $maxUses); $success = 'Voucher erstellt. E-Mail versendet.'; } else { $success = 'Voucher erfolgreich erstellt!'; } } catch (Exception $e) { $error = 'Fehler: ' . $e->getMessage(); } } } // Bulk voucher creation if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['create_bulk'])) { if (!$publicAccess && !$auth->isLoggedIn()) { $error = __('error_login_req'); } elseif (!$auth->validateCsrfToken($_POST['csrf_token'] ?? '')) { // CSRF fuer ALLE (auch anonyme oeffentliche Erstellung) $error = __('error_csrf'); } elseif (!$auth->isLoggedIn() && isVoucherRateLimited()) { $error = 'Zu viele Anfragen. Bitte warten Sie einen Moment.'; } else { try { $siteId = (int)($_POST['site_id'] ?? 0); $voucherName = trim((string)($_POST['voucher_name'] ?? '')); $maxUses = (int)($_POST['max_uses'] ?? $defaultMaxUses); $expireMinutes = max(1, (int)($_POST['expire_minutes'] ?? $defaultExpire)); $bulkCount = max(1, min(20, (int)($_POST['bulk_count'] ?? 1))); if (empty($voucherName)) throw new Exception(__('error_name_req')); if ($maxUses < 1 || $maxUses > $maxUsesLimit) throw new Exception(__('error_devices_range', ['max' => $maxUsesLimit])); if ($siteId <= 0) throw new Exception(__('error_site_req')); if ($auth->isLoggedIn() && !$auth->hasAccessToSite($siteId)) throw new Exception(__('error_site_no_perm')); $site = $db->fetchOne("SELECT * FROM sites WHERE id = ? AND is_active = 1", [$siteId]); if (!$site) throw new Exception(__('error_site_not_found')); $userId = $auth->isLoggedIn() ? ($_SESSION['user_id'] ?? null) : null; $qos = [ 'down' => max(0, (int)($_POST['qos_down'] ?? 0)), 'up' => max(0, (int)($_POST['qos_up'] ?? 0)), 'quota_mb' => max(0, (int)($_POST['qos_quota'] ?? 0)), ]; for ($i = 0; $i < $bulkCount; $i++) { $bulkVouchers[] = doCreateVoucher($db, $site, $voucherName . '_' . ($i + 1), $maxUses, $expireMinutes, $userId, $qos); } Notifier::voucherCreated($bulkCount, $site['name'], $_SESSION['user_name'] ?? null); $bulkCreated = true; $success = str_replace('{count}', $bulkCount, __('bulk_success')); } catch (Exception $e) { $error = 'Fehler: ' . $e->getMessage(); } } } $currentUser = $auth->isLoggedIn() ? $auth->getCurrentUser() : null; // Build print HTML for each voucher function buildPrintCard($template, $data, $instructionHeader, $instructionText, $appTitle) { $instructions = $instructionHeader || $instructionText ? htmlspecialchars($instructionHeader) . "\n" . $instructionText : ''; return str_replace( ['{VOUCHER_CODE}', '{SITE_NAME}', '{MAX_USES}', '{APP_TITLE}', '{INSTRUCTIONS}', '{EXPIRY_DATE}', '{EXPIRY_TIME}'], [$data['code'], htmlspecialchars($data['site_name']), $data['max_uses'], htmlspecialchars($appTitle), $instructions, $data['expiry_date'], $data['expiry_time']], $template ); } ?> <?= htmlspecialchars($appTitle) ?>
$label): ?>
👋 htmlspecialchars($currentUser['name'])]) ?>
isAdmin()): ?> ⚙️
🔐

$bv): ?>
$bv): ?>
#

Code anklicken zum Kopieren

📶


isAdmin()): ?>

isLoggedIn()): ?>