T.ME/BIBIL_0DAY
CasperSecurity


Server : Apache/2
System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64
User : gositeme ( 1004)
PHP Version : 8.2.29
Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Directory :  /home/gositeme/domains/soundstudiopro.com/private_html/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/private_html/generate_ticket_qr.php
<?php
session_start();
require_once 'config/database.php';
require_once 'includes/event_permissions.php';

$ticket_code = $_GET['code'] ?? null;

if (!$ticket_code) {
    http_response_code(400);
    die('Ticket code required');
}

$pdo = getDBConnection();
$user_id = $_SESSION['user_id'] ?? null;

ensureEventManagersTable($pdo);

// Get ticket information with creator + check-in details
$stmt = $pdo->prepare("
    SELECT 
        et.*,
        e.id as event_id,
        e.title as event_title,
        e.start_date,
        e.end_date,
        e.location,
        e.venue_name,
        e.creator_id,
        e.banner_image,
        e.cover_image,
        u.name as user_name,
        u.email as user_email,
        manager.name as checked_in_by_name
    FROM event_tickets et
    JOIN events e ON et.event_id = e.id
    JOIN users u ON et.user_id = u.id
    LEFT JOIN users manager ON et.checked_in_by = manager.id
    WHERE et.ticket_code = ?
");

$stmt->execute([$ticket_code]);
$ticket = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$ticket) {
    http_response_code(404);
    die('Ticket not found');
}

$can_manage = userCanManageEvent($pdo, $user_id, (int)$ticket['event_id']);
$isCheckedIn = $ticket['status'] === 'used';
$statusLabel = ucfirst($ticket['status']);
$statusClass = 'status-neutral';
switch ($ticket['status']) {
    case 'used':
        $statusClass = 'status-used';
        break;
    case 'confirmed':
        $statusClass = 'status-confirmed';
        break;
    case 'pending':
        $statusClass = 'status-pending';
        break;
    case 'cancelled':
        $statusClass = 'status-cancelled';
        break;
}

$checkedInMeta = null;
if ($isCheckedIn && !empty($ticket['checked_in_at'])) {
    $checkedInMeta = [
        'time' => date('M j, Y g:i A', strtotime($ticket['checked_in_at'])),
        'by' => $ticket['checked_in_by_name'] ?: 'Door staff'
    ];
}

// Generate QR code using API (client fetch)
$baseUrl = rtrim((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https://' : 'http://') . ($_SERVER['HTTP_HOST'] ?? 'soundstudiopro.com'), '/');
$qr_link = sprintf(
    '%s/event_checkin_console.php?event_id=%d&ticket=%s',
    $baseUrl,
    $ticket['event_id'],
    rawurlencode($ticket_code)
);
$qr_url = 'https://api.qrserver.com/v1/create-qr-code/?size=420x420&data=' . urlencode($qr_link);

?><!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Ticket QR - <?= htmlspecialchars($ticket['event_title']) ?></title>
    <style>
        body {
            margin: 0;
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
            background: radial-gradient(circle at top, #0f1730, #05060a 70%);
            color: #f7fafc;
            font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
            padding: 2rem;
        }
        .ticket-wrapper {
            background: rgba(12, 16, 34, 0.85);
            border: 1px solid rgba(103, 126, 234, 0.3);
            border-radius: 26px;
            padding: 2.8rem;
            width: min(520px, 100%);
            text-align: center;
            backdrop-filter: blur(14px);
            box-shadow: 0 25px 60px rgba(0,0,0,0.45);
            position: relative;
        }
        h1 {
            font-size: 2rem;
            margin-bottom: 0.5rem;
        }
        p {
            color: #a0aec0;
            margin: 0.3rem 0;
        }
        img {
            margin: 2rem auto;
            border-radius: 20px;
            background: #fff;
            padding: 1rem;
            box-shadow: 0 10px 35px rgba(79, 172, 254, 0.3);
            max-width: 100%;
            height: auto;
        }
        .ticket-meta {
            font-size: 0.95rem;
            color: #cbd5f5;
            line-height: 1.6;
        }
.ticket-meta strong {
    color: #f7fafc;
    font-size: 1.1rem;
    letter-spacing: 0.05em;
}
        .info-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
            gap: 1rem;
            margin-top: 1.5rem;
            text-align: left;
        }
        .info-card {
            background: rgba(255, 255, 255, 0.04);
            border: 1px solid rgba(255,255,255,0.08);
            border-radius: 16px;
            padding: 1rem 1.2rem;
        }
        .info-card h4 {
            margin: 0 0 0.4rem;
            font-size: 0.95rem;
            text-transform: uppercase;
            letter-spacing: 0.08em;
            color: #94a6ff;
        }
        .info-card p {
            margin: 0.15rem 0;
            font-size: 0.95rem;
            color: #f7fafc;
        }
.info-card span {
    color: #a0aec0;
    font-size: 0.95rem;
    letter-spacing: 0.06em;
    font-weight: 500;
}
.status-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0.9rem;
    border-radius: 999px;
    font-weight: 600;
    margin-top: 0.2rem;
    border: 1px solid rgba(255,255,255,0.1);
    box-shadow: 0 10px 25px rgba(0,0,0,0.25);
}
.status-badge i {
    font-size: 0.95rem;
}
.status-badge.status-used {
    color: #fed7d7;
    background: rgba(245, 101, 101, 0.25);
    border-color: rgba(245, 101, 101, 0.4);
    text-transform: uppercase;
    letter-spacing: 0.2em;
    animation: usedPulse 1.6s infinite;
}
.status-badge.status-confirmed {
    color: #c6f6d5;
    background: rgba(72, 187, 120, 0.25);
    border-color: rgba(72, 187, 120, 0.4);
}
.status-badge.status-pending {
    color: #fefcbf;
    background: rgba(237, 137, 54, 0.25);
    border-color: rgba(237, 137, 54, 0.4);
}
.status-badge.status-cancelled {
    color: #feb2b2;
    background: rgba(229, 62, 62, 0.25);
    border-color: rgba(229, 62, 62, 0.4);
}
@keyframes usedPulse {
    0% { box-shadow: 0 0 0 0 rgba(229, 62, 62, 0.35); transform: translateY(0); }
    70% { box-shadow: 0 0 35px 10px rgba(229, 62, 62, 0); transform: translateY(-1px); }
    100% { box-shadow: 0 0 0 0 rgba(229, 62, 62, 0); transform: translateY(0); }
}
        .admin-panel {
            margin-top: 1.8rem;
            text-align: left;
            background: rgba(21, 25, 52, 0.9);
            border: 1px solid rgba(102, 126, 234, 0.4);
            border-radius: 18px;
            padding: 1.5rem;
            box-shadow: 0 10px 30px rgba(102, 126, 234, 0.25);
        }
        .admin-panel h3 {
            margin: 0 0 0.8rem;
            font-size: 1.1rem;
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }
        .status-chip {
            display: inline-flex;
            align-items: center;
            gap: 0.4rem;
            padding: 0.35rem 0.9rem;
            border-radius: 999px;
            font-size: 0.88rem;
            font-weight: 600;
            text-transform: capitalize;
        }
        .status-chip.confirmed {
            background: rgba(72, 187, 120, 0.15);
            color: #68d391;
            border: 1px solid rgba(72, 187, 120, 0.4);
        }
        .status-chip.used {
            background: rgba(236, 201, 75, 0.15);
            color: #f6ad55;
            border: 1px solid rgba(236, 201, 75, 0.4);
        }
        .status-chip.cancelled {
            background: rgba(245, 101, 101, 0.15);
            color: #fc8181;
            border: 1px solid rgba(245, 101, 101, 0.4);
        }
        .admin-meta {
            margin-top: 1rem;
            font-size: 0.9rem;
            color: #cbd5f5;
            line-height: 1.5;
        }
        .admin-actions {
            margin-top: 1.2rem;
            display: flex;
            flex-wrap: wrap;
            gap: 0.8rem;
        }
        .admin-actions button {
            flex: 1;
            min-width: 180px;
        }
        .actions {
            margin-top: 1.5rem;
            display: flex;
            flex-direction: column;
            gap: 0.8rem;
        }
        .btn {
            display: inline-flex;
            justify-content: center;
            align-items: center;
            gap: 0.4rem;
            padding: 0.9rem 1.2rem;
            border-radius: 10px;
            font-weight: 600;
            text-decoration: none;
            border: none;
        }
        .btn-primary {
            background: linear-gradient(135deg, #667eea, #764ba2);
            color: #fff;
        }
        .btn-secondary {
            background: rgba(255,255,255,0.08);
            color: #e2e8f0;
            border: 1px solid rgba(255,255,255,0.15);
        }
        .btn:hover {
            transform: translateY(-1px);
            box-shadow: 0 12px 28px rgba(102, 126, 234, 0.35);
        }
        @media (max-width: 640px) {
            .ticket-wrapper {
                padding: 2rem 1.4rem;
                border-radius: 20px;
            }
            .info-grid {
                grid-template-columns: 1fr;
            }
            .admin-actions {
                flex-direction: column;
            }
        }
    </style>
</head>
<?php
$eventDate = '';
if (!empty($ticket['start_date'])) {
    $eventDate = date('M j, Y g:i A', strtotime($ticket['start_date']));
}
$purchaseDate = date('M j, Y g:i A', strtotime($ticket['purchase_date']));
?>
<body>
    <div class="ticket-wrapper">
        <h1><?= htmlspecialchars($ticket['event_title']) ?></h1>
        <?php if ($eventDate): ?><p><?= $eventDate ?></p><?php endif; ?>
        <p><?= htmlspecialchars($ticket['user_name']) ?> &middot; <?= htmlspecialchars($ticket['user_email']) ?></p>
        
        <div class="info-grid">
            <div class="info-card">
                <h4>Ticket</h4>
                <p><span>Code</span><br><strong><?= htmlspecialchars($ticket_code) ?></strong></p>
                <p><span>Status</span><br>
                    <span class="status-badge <?= $statusClass ?>" id="ticketStatusBadge">
                        <i class="fas <?= $isCheckedIn ? 'fa-ban' : 'fa-check' ?>"></i>
                        <span id="ticketStatusLabel"><?= $statusLabel ?></span>
                    </span>
                </p>
            </div>
            <div class="info-card">
                <h4>Attendee</h4>
                <p><span>Name</span><br><?= htmlspecialchars($ticket['user_name']) ?></p>
                <p><span>Email</span><br><?= htmlspecialchars($ticket['user_email']) ?></p>
            </div>
        </div>
        
        <?php if ($can_manage): ?>
        <div class="admin-panel" id="managerPanel">
            <h3><i class="fas fa-shield-alt"></i> Door Access</h3>
            <div class="status-chip <?= strtolower($ticket['status']) ?>" id="ticketStatusChip">
                <i class="fas fa-ticket-alt"></i>
                <span id="ticketStatusChipText"><?= $statusLabel ?></span>
            </div>
            <div class="admin-meta" id="ticketCheckInMeta">
                <?php if ($checkedInMeta): ?>
                    Checked in <?= htmlspecialchars($checkedInMeta['time']) ?> by <?= htmlspecialchars($checkedInMeta['by']) ?>
                <?php else: ?>
                    Ticket ready for check-in. Confirm guest identity before proceeding.
                <?php endif; ?>
            </div>
            <div class="admin-actions">
                <?php if (!$isCheckedIn): ?>
                    <button class="btn btn-primary" id="checkInBtn">
                        <i class="fas fa-check-circle"></i> Check In Guest
                    </button>
                <?php endif; ?>
                <?php if ($isCheckedIn): ?>
                    <button class="btn btn-secondary" id="undoCheckInBtn">
                        <i class="fas fa-undo"></i> Undo Check-In
                    </button>
                <?php endif; ?>
            </div>
        </div>
        <?php endif; ?>

        <img src="<?= $qr_url ?>" alt="Ticket QR Code" loading="lazy">

        <div class="ticket-meta">
            <strong>Ticket Code:</strong> <?= htmlspecialchars($ticket_code) ?><br>
            <strong>Status:</strong> <?= ucfirst($ticket['status']) ?><br>
            <strong>Purchased:</strong> <?= $purchaseDate ?>
        </div>

        <div class="actions">
            <a class="btn btn-primary" href="<?= $qr_url ?>" download="ticket-<?= htmlspecialchars($ticket_code) ?>.png">
                Download PNG
            </a>
            <a class="btn btn-secondary" href="/tickets.php">
                Back to My Tickets
            </a>
        </div>
    </div>
    
    <?php if ($can_manage): ?>
    <script>
        (function() {
            const checkInBtn = document.getElementById('checkInBtn');
            const undoBtn = document.getElementById('undoCheckInBtn');
            const statusLabel = document.getElementById('ticketStatusLabel');
            const statusChip = document.getElementById('ticketStatusChip');
            const statusChipText = document.getElementById('ticketStatusChipText');
            const meta = document.getElementById('ticketCheckInMeta');
            const ticketCode = <?= json_encode($ticket_code) ?>;
            
            async function performAction(action) {
                const btn = action === 'check_in' ? checkInBtn : undoBtn;
                if (!btn) return;
                
                btn.disabled = true;
                btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Processing...';
                
                try {
                    const response = await fetch('/api/ticket_checkin.php', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ ticket_code: ticketCode, action })
                    });
                    
                    const result = await response.json();
                    if (!response.ok || !result.success) {
                        throw new Error(result.error || 'Failed to update ticket');
                    }
                    
                    statusLabel.textContent = result.ticket.status_label;
                    statusChipText.textContent = result.ticket.status_label;
                    statusChip.className = 'status-chip ' + result.ticket.status;
                    meta.textContent = result.ticket.meta;
                    
                    if (result.ticket.status === 'used') {
                        if (!undoBtn) {
                            location.reload();
                            return;
                        }
                        if (checkInBtn) {
                            checkInBtn.remove();
                        }
                        undoBtn.disabled = false;
                        undoBtn.innerHTML = '<i class="fas fa-undo"></i> Undo Check-In';
                    } else {
                        if (!checkInBtn) {
                            location.reload();
                            return;
                        }
                        if (undoBtn) {
                            undoBtn.remove();
                        }
                        checkInBtn.disabled = false;
                        checkInBtn.innerHTML = '<i class="fas fa-check-circle"></i> Check In Guest';
                    }
                } catch (error) {
                    console.error(error);
                    alert(error.message || 'Unable to update ticket right now.');
                    if (btn) {
                        btn.disabled = false;
                        btn.innerHTML = action === 'check_in'
                            ? '<i class="fas fa-check-circle"></i> Check In Guest'
                            : '<i class="fas fa-undo"></i> Undo Check-In';
                    }
                }
            }
            
            checkInBtn?.addEventListener('click', () => performAction('check_in'));
            undoBtn?.addEventListener('click', () => performAction('revert'));
        })();
    </script>
    <?php endif; ?>
</body>
</html>

CasperSecurity Mini