HEX
Server: LiteSpeed
System: Linux da020 6.1.0-50-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.176-1 (2026-07-02) x86_64
User: nmel17aacb (1161)
PHP: 8.2.29
Disabled: exec,system,passthru,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
Upload Files
File: /home/nmel17aacb/domains/argentaclassic.be/public_html/admin/index.php
<?php
declare(strict_types=1);

session_set_cookie_params([
    'lifetime' => 0,
    'path' => '/',
    'secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'),
    'httponly' => true,
    'samesite' => 'Lax',
]);
session_start();
require_once __DIR__ . '/../inc/db.php';

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$db->set_charset('utf8');

$sections = [
    'nieuws' => [
        'label' => 'Nieuws',
        'table' => 'nieuws',
        'order' => 'datum DESC',
        'upload' => 'nieuws',
        'fields' => [
            'titel' => ['label' => 'Titel', 'type' => 'text', 'required' => true],
            'nieuws' => ['label' => 'Bericht', 'type' => 'textarea', 'required' => true, 'full' => true],
            'link' => ['label' => 'Link', 'type' => 'url'],
            'datum' => ['label' => 'Datum', 'type' => 'datetime'],
            'actief' => ['label' => 'Actief', 'type' => 'checkbox'],
            'image' => ['label' => 'Afbeelding', 'type' => 'image'],
        ],
        'list' => ['titel', 'datum', 'actief', 'image'],
    ],
    'sponsor' => [
        'label' => 'Sponsors',
        'table' => 'sponsor',
        'order' => 'volgorde ASC, titel ASC',
        'upload' => 'sponsors',
        'fields' => [
            'titel' => ['label' => 'Naam', 'type' => 'text'],
            'link' => ['label' => 'Link', 'type' => 'url'],
            'volgorde' => ['label' => 'Volgorde', 'type' => 'number'],
            'actief' => ['label' => 'Actief', 'type' => 'checkbox'],
            'image' => ['label' => 'Logo', 'type' => 'image'],
        ],
        'list' => ['titel', 'volgorde', 'actief', 'image'],
    ],
    'federaties' => [
        'label' => 'Federaties',
        'table' => 'federaties',
        'order' => 'id DESC',
        'upload' => 'federaties',
        'fields' => [
            'link' => ['label' => 'Link', 'type' => 'url'],
            'actief' => ['label' => 'Actief', 'type' => 'checkbox'],
            'image' => ['label' => 'Logo', 'type' => 'image'],
        ],
        'list' => ['link', 'actief', 'image'],
    ],
    'agenda' => [
        'label' => 'Agenda',
        'table' => 'agenda',
        'order' => 'datum DESC',
        'fields' => [
            'titel' => ['label' => 'Titel', 'type' => 'text', 'required' => true],
            'datum' => ['label' => 'Datum', 'type' => 'datetime'],
            'info' => ['label' => 'Info', 'type' => 'textarea', 'full' => true],
            'locatie' => ['label' => 'Locatie', 'type' => 'text'],
            'start_tijd' => ['label' => 'Starttijd', 'type' => 'text'],
            'stop_tijd' => ['label' => 'Eindtijd', 'type' => 'text'],
            'afstand' => ['label' => 'Afstand', 'type' => 'text'],
            'link' => ['label' => 'Link', 'type' => 'url'],
            'mail' => ['label' => 'E-mail', 'type' => 'email'],
            'actief' => ['label' => 'Actief', 'type' => 'checkbox'],
        ],
        'list' => ['titel', 'datum', 'locatie', 'actief'],
    ],
    'bestuur' => [
        'label' => 'Bestuur',
        'table' => 'bestuur',
        'order' => 'volgorde ASC',
        'upload' => 'bestuur',
        'fields' => [
            'titel' => ['label' => 'Titel', 'type' => 'text'],
            'naam' => ['label' => 'Naam', 'type' => 'text'],
            'functie' => ['label' => 'Functie/tekst', 'type' => 'textarea', 'full' => true],
            'gsm' => ['label' => 'GSM', 'type' => 'text'],
            'telefoon' => ['label' => 'Telefoon', 'type' => 'text'],
            'mail' => ['label' => 'E-mail', 'type' => 'email'],
            'volgorde' => ['label' => 'Volgorde', 'type' => 'number'],
            'actief' => ['label' => 'Actief', 'type' => 'checkbox'],
            'image' => ['label' => 'Foto', 'type' => 'image'],
        ],
        'list' => ['titel', 'naam', 'volgorde', 'actief', 'image'],
    ],
    'neven' => [
        'label' => 'Nevenactiviteiten',
        'table' => 'neven',
        'order' => 'id DESC',
        'upload' => 'sponsors',
        'fields' => [
            'regio' => ['label' => 'Regio/categorie', 'type' => 'text'],
            'titel' => ['label' => 'Titel/tekst', 'type' => 'textarea', 'full' => true],
            'link' => ['label' => 'Link', 'type' => 'url'],
            'actief' => ['label' => 'Actief', 'type' => 'checkbox'],
            'image' => ['label' => 'Afbeelding', 'type' => 'image'],
        ],
        'list' => ['regio', 'titel', 'actief', 'image'],
    ],
    'links' => [
        'label' => 'Links',
        'table' => 'links',
        'order' => 'titel ASC',
        'fields' => [
            'titel' => ['label' => 'Titel', 'type' => 'text', 'required' => true],
            'link' => ['label' => 'Link', 'type' => 'url', 'required' => true],
            'actief' => ['label' => 'Actief', 'type' => 'checkbox'],
        ],
        'list' => ['titel', 'link', 'actief'],
    ],
    'pers' => [
        'label' => 'Pers',
        'table' => 'pers',
        'order' => 'datum DESC',
        'upload' => 'pers',
        'fields' => [
            'titel' => ['label' => 'Titel', 'type' => 'text', 'required' => true],
            'bron' => ['label' => 'Bron', 'type' => 'text'],
            'tekst' => ['label' => 'Tekst', 'type' => 'textarea', 'full' => true],
            'link' => ['label' => 'Link', 'type' => 'url'],
            'datum' => ['label' => 'Datum', 'type' => 'datetime'],
            'actief' => ['label' => 'Actief', 'type' => 'checkbox'],
            'image' => ['label' => 'Afbeelding', 'type' => 'image'],
        ],
        'list' => ['titel', 'bron', 'datum', 'actief', 'image'],
    ],
];

function h(?string $value): string
{
    return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
}

function redirect_to(string $url): void
{
    header('Location: ' . $url);
    exit;
}

function bind_stmt_params(mysqli_stmt $stmt, string $types, array $params): void
{
    $refs = [];
    foreach ($params as $key => $value) {
        $refs[$key] = $value;
    }

    $bind = [$types];
    foreach ($refs as $key => &$value) {
        $bind[] = &$value;
    }

    $stmt->bind_param(...$bind);
}

function is_logged_in(): bool
{
    return isset($_SESSION['admin_user_id']);
}

function find_user(mysqli $db, string $login): ?array
{
    $stmt = $db->prepare('SELECT user_id, user_name, user_email, user_password FROM users WHERE user_email = ? OR user_name = ? LIMIT 1');
    bind_stmt_params($stmt, 'ss', [$login, $login]);
    $stmt->execute();
    $result = $stmt->get_result();
    $user = $result->fetch_assoc();
    return $user ?: null;
}

function fetch_row(mysqli $db, array $section, int $id): ?array
{
    $sql = 'SELECT * FROM `' . $section['table'] . '` WHERE id = ? LIMIT 1';
    if ($section['table'] === 'users') {
        $sql = 'SELECT * FROM `users` WHERE user_id = ? LIMIT 1';
    }
    $stmt = $db->prepare($sql);
    bind_stmt_params($stmt, 'i', [$id]);
    $stmt->execute();
    $row = $stmt->get_result()->fetch_assoc();
    return $row ?: null;
}

function upload_image(string $folder, string $field, string $current = ''): string
{
    if (!isset($_FILES[$field]) || $_FILES[$field]['error'] === UPLOAD_ERR_NO_FILE) {
        return $current;
    }

    if ($_FILES[$field]['error'] !== UPLOAD_ERR_OK) {
        throw new RuntimeException('Upload mislukt. Probeer opnieuw met een kleinere of geldige afbeelding.');
    }

    $tmp = $_FILES[$field]['tmp_name'];
    $info = @getimagesize($tmp);
    if (!$info) {
        throw new RuntimeException('Dit bestand lijkt geen geldige afbeelding.');
    }

    $allowed = [
        IMAGETYPE_JPEG => 'jpg',
        IMAGETYPE_PNG => 'png',
        IMAGETYPE_GIF => 'gif',
        IMAGETYPE_WEBP => 'webp',
        IMAGETYPE_BMP => 'bmp',
    ];

    if (!isset($allowed[$info[2]])) {
        throw new RuntimeException('Gebruik JPG, PNG, GIF, WEBP of BMP.');
    }

    $original = pathinfo($_FILES[$field]['name'], PATHINFO_FILENAME);
    $base = preg_replace('/[^a-zA-Z0-9_-]+/', '-', strtolower($original));
    $base = trim($base, '-') ?: 'afbeelding';
    $filename = $base . '-' . date('YmdHis') . '.' . $allowed[$info[2]];
    $targetDir = dirname(__DIR__) . '/files/' . $folder;

    if (!is_dir($targetDir)) {
        mkdir($targetDir, 0775, true);
    }

    $target = $targetDir . '/' . $filename;
    if (!move_uploaded_file($tmp, $target)) {
        throw new RuntimeException('De afbeelding kon niet worden opgeslagen.');
    }

    return $filename;
}

function normalize_value(array $field, string $name, array $row = []): string
{
    if (($field['type'] ?? 'text') === 'checkbox') {
        return isset($_POST[$name]) ? '1' : '0';
    }

    if (($field['type'] ?? 'text') === 'datetime') {
        $value = trim((string) ($_POST[$name] ?? ''));
        return $value === '' ? date('Y-m-d H:i:s') : str_replace('T', ' ', $value) . (strlen($value) === 16 ? ':00' : '');
    }

    if (($field['type'] ?? 'text') === 'image') {
        return (string) ($row[$name] ?? '');
    }

    return trim((string) ($_POST[$name] ?? ''));
}

if (!is_logged_in() && $_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'login') {
    $login = trim((string) ($_POST['login'] ?? ''));
    $password = (string) ($_POST['password'] ?? '');
    $user = find_user($db, $login);

    if ($user && password_verify($password, $user['user_password'])) {
        session_regenerate_id(true);
        $_SESSION['admin_user_id'] = (int) $user['user_id'];
        $_SESSION['admin_user_name'] = $user['user_name'];
        redirect_to('index.php');
    }

    $loginError = 'Ongeldige gebruikersnaam of wachtwoord.';
}

if (!is_logged_in()) {
    ?>
    <!doctype html>
    <html lang="nl">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="robots" content="noindex,nofollow">
        <title>Admin login - Argenta Classic</title>
        <link rel="stylesheet" href="assets/admin.css">
    </head>
    <body class="login-page">
        <main class="panel login-card">
            <div class="panel-header">
                <h1>Admin</h1>
            </div>
            <div class="panel-body">
                <?php if (!empty($loginError)): ?>
                    <div class="message error"><?= h($loginError) ?></div>
                <?php endif; ?>
                <form method="post">
                    <input type="hidden" name="action" value="login">
                    <div>
                        <label for="login">Gebruiker of e-mail</label>
                        <input id="login" name="login" type="text" autocomplete="username" required>
                    </div>
                    <div style="margin-top: 14px;">
                        <label for="password">Wachtwoord</label>
                        <input id="password" name="password" type="password" autocomplete="current-password" required>
                    </div>
                    <div class="actions">
                        <button class="btn btn-primary" type="submit">Inloggen</button>
                    </div>
                </form>
            </div>
        </main>
    </body>
    </html>
    <?php
    exit;
}

$sectionKey = $_GET['section'] ?? 'nieuws';
if (!isset($sections[$sectionKey])) {
    $sectionKey = 'nieuws';
}

$section = $sections[$sectionKey];
$action = $_GET['action'] ?? 'list';
$id = max(0, (int) ($_GET['id'] ?? 0));
$message = $_GET['message'] ?? '';
$error = '';
$editRow = $id ? fetch_row($db, $section, $id) : null;

if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'save') {
    try {
        $id = max(0, (int) ($_POST['id'] ?? 0));
        $currentRow = $id ? fetch_row($db, $section, $id) : [];
        $values = [];

        foreach ($section['fields'] as $name => $field) {
            $values[$name] = normalize_value($field, $name, $currentRow ?: []);
            if (($field['type'] ?? '') === 'image') {
                $values[$name] = upload_image($section['upload'] ?? '', $name, $values[$name]);
            }
            if (!empty($field['required']) && $values[$name] === '') {
                throw new RuntimeException($field['label'] . ' is verplicht.');
            }
        }

        if ($id > 0) {
            $set = implode(', ', array_map(fn($name) => '`' . $name . '` = ?', array_keys($values)));
            $sql = 'UPDATE `' . $section['table'] . '` SET ' . $set . ' WHERE id = ?';
            $stmt = $db->prepare($sql);
            $types = str_repeat('s', count($values)) . 'i';
            $params = array_values($values);
            $params[] = $id;
            bind_stmt_params($stmt, $types, $params);
            $stmt->execute();
            redirect_to('index.php?section=' . urlencode($sectionKey) . '&message=updated');
        }

        $columns = implode(', ', array_map(fn($name) => '`' . $name . '`', array_keys($values)));
        $placeholders = implode(', ', array_fill(0, count($values), '?'));
        $sql = 'INSERT INTO `' . $section['table'] . '` (' . $columns . ') VALUES (' . $placeholders . ')';
        $stmt = $db->prepare($sql);
        $types = str_repeat('s', count($values));
        $params = array_values($values);
        bind_stmt_params($stmt, $types, $params);
        $stmt->execute();
        redirect_to('index.php?section=' . urlencode($sectionKey) . '&message=created');
    } catch (Throwable $e) {
        $error = $e->getMessage();
        $action = $id > 0 ? 'edit' : 'new';
        $editRow = $_POST;
    }
}

if ($action === 'delete' && $id > 0) {
    $stmt = $db->prepare('DELETE FROM `' . $section['table'] . '` WHERE id = ? LIMIT 1');
    bind_stmt_params($stmt, 'i', [$id]);
    $stmt->execute();
    redirect_to('index.php?section=' . urlencode($sectionKey) . '&message=deleted');
}

$rows = [];
if ($action === 'list') {
    $result = $db->query('SELECT * FROM `' . $section['table'] . '` ORDER BY ' . $section['order'] . ' LIMIT 250');
    while ($row = $result->fetch_assoc()) {
        $rows[] = $row;
    }
}

$messages = [
    'created' => 'Item toegevoegd.',
    'updated' => 'Wijzigingen opgeslagen.',
    'deleted' => 'Item verwijderd.',
];

function render_value(array $row, string $name): string
{
    $value = (string) ($row[$name] ?? '');
    if ($name === 'actief') {
        return ((int) $value === 1) ? '<span class="status on">Actief</span>' : '<span class="status off">Uit</span>';
    }
    if ($name === 'datum' && $value !== '') {
        return h(date('d/m/Y H:i', strtotime($value)));
    }
    $plain = strip_tags($value);
    return h(strlen($plain) > 90 ? substr($plain, 0, 90) . '...' : $plain);
}

function image_path(string $sectionKey, array $section, string $image): string
{
    if ($image === '' || empty($section['upload'])) {
        return '';
    }
    return '../files/' . $section['upload'] . '/' . $image;
}
?>
<!doctype html>
<html lang="nl">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="robots" content="noindex,nofollow">
    <title>Admin - Argenta Classic</title>
    <link rel="stylesheet" href="assets/admin.css">
</head>
<body>
<div class="admin-shell">
    <aside class="admin-sidebar">
        <div class="admin-brand">
            <img src="../resources/logoac2e.png" alt="">
            <div>
                <strong>Argenta Classic</strong>
                <span>Beheer</span>
            </div>
        </div>
        <nav class="admin-nav">
            <?php foreach ($sections as $key => $item): ?>
                <a class="<?= $key === $sectionKey ? 'active' : '' ?>" href="?section=<?= h($key) ?>"><?= h($item['label']) ?></a>
            <?php endforeach; ?>
        </nav>
    </aside>
    <main class="admin-content">
        <div class="admin-topbar">
            <div class="admin-title">
                <h1><?= h($section['label']) ?></h1>
                <p>Ingelogd als <?= h($_SESSION['admin_user_name'] ?? 'admin') ?></p>
            </div>
            <div class="actions">
                <a class="btn btn-secondary" href="../" target="_blank">Website bekijken</a>
                <a class="btn btn-secondary" href="logout.php">Uitloggen</a>
            </div>
        </div>

        <?php if ($message && isset($messages[$message])): ?>
            <div class="message success"><?= h($messages[$message]) ?></div>
        <?php endif; ?>
        <?php if ($error): ?>
            <div class="message error"><?= h($error) ?></div>
        <?php endif; ?>

        <?php if ($action === 'new' || $action === 'edit'): ?>
            <?php $isEdit = $action === 'edit' && $editRow; ?>
            <section class="panel">
                <div class="panel-header">
                    <h2><?= $isEdit ? 'Bewerken' : 'Nieuw item' ?></h2>
                    <a class="btn btn-secondary" href="?section=<?= h($sectionKey) ?>">Terug</a>
                </div>
                <div class="panel-body">
                    <form method="post" enctype="multipart/form-data">
                        <input type="hidden" name="action" value="save">
                        <input type="hidden" name="id" value="<?= h((string) ($editRow['id'] ?? 0)) ?>">
                        <div class="admin-grid">
                            <?php foreach ($section['fields'] as $name => $field): ?>
                                <?php
                                $type = $field['type'] ?? 'text';
                                $value = (string) ($editRow[$name] ?? '');
                                if ($type === 'datetime' && $value !== '') {
                                    $value = date('Y-m-d\TH:i', strtotime($value));
                                }
                                ?>
                                <div class="<?= !empty($field['full']) || $type === 'image' ? 'field-full' : '' ?>">
                                    <?php if ($type === 'checkbox'): ?>
                                        <div class="check-field">
                                            <input id="<?= h($name) ?>" name="<?= h($name) ?>" type="checkbox" value="1" <?= (int) ($editRow[$name] ?? 1) === 1 ? 'checked' : '' ?>>
                                            <label for="<?= h($name) ?>"><?= h($field['label']) ?></label>
                                        </div>
                                    <?php elseif ($type === 'textarea'): ?>
                                        <label for="<?= h($name) ?>"><?= h($field['label']) ?></label>
                                        <textarea id="<?= h($name) ?>" name="<?= h($name) ?>" <?= !empty($field['required']) ? 'required' : '' ?>><?= h($value) ?></textarea>
                                        <div class="help">HTML zoals &lt;br&gt;, &lt;b&gt; en links mag blijven staan.</div>
                                    <?php elseif ($type === 'image'): ?>
                                        <label for="<?= h($name) ?>"><?= h($field['label']) ?></label>
                                        <?php $img = image_path($sectionKey, $section, (string) ($editRow[$name] ?? '')); ?>
                                        <?php if ($img): ?>
                                            <div class="thumb" style="margin-bottom: 10px;"><img src="<?= h($img) ?>" alt=""></div>
                                            <div class="help">Huidig bestand: <?= h((string) $editRow[$name]) ?></div>
                                        <?php endif; ?>
                                        <input id="<?= h($name) ?>" name="<?= h($name) ?>" type="file" accept="image/*">
                                    <?php else: ?>
                                        <label for="<?= h($name) ?>"><?= h($field['label']) ?></label>
                                        <input id="<?= h($name) ?>" name="<?= h($name) ?>" type="<?= h($type) ?>" value="<?= h($value) ?>" <?= !empty($field['required']) ? 'required' : '' ?>>
                                    <?php endif; ?>
                                </div>
                            <?php endforeach; ?>
                        </div>
                        <div class="actions">
                            <button class="btn btn-primary" type="submit">Opslaan</button>
                            <a class="btn btn-secondary" href="?section=<?= h($sectionKey) ?>">Annuleren</a>
                        </div>
                    </form>
                </div>
            </section>
        <?php else: ?>
            <section class="panel">
                <div class="panel-header">
                    <h2>Overzicht</h2>
                    <a class="btn btn-primary" href="?section=<?= h($sectionKey) ?>&action=new">Nieuw item</a>
                </div>
                <div class="table-wrap">
                    <table>
                        <thead>
                            <tr>
                                <?php foreach ($section['list'] as $column): ?>
                                    <th><?= h($column === 'image' ? 'Afbeelding' : ucfirst($column)) ?></th>
                                <?php endforeach; ?>
                                <th>Acties</th>
                            </tr>
                        </thead>
                        <tbody>
                            <?php if (!$rows): ?>
                                <tr><td colspan="<?= count($section['list']) + 1 ?>">Nog geen items.</td></tr>
                            <?php endif; ?>
                            <?php foreach ($rows as $row): ?>
                                <tr>
                                    <?php foreach ($section['list'] as $column): ?>
                                        <td>
                                            <?php if ($column === 'image'): ?>
                                                <?php $img = image_path($sectionKey, $section, (string) ($row[$column] ?? '')); ?>
                                                <div class="thumb">
                                                    <?php if ($img): ?><img src="<?= h($img) ?>" alt=""><?php endif; ?>
                                                </div>
                                            <?php else: ?>
                                                <?= render_value($row, $column) ?>
                                            <?php endif; ?>
                                        </td>
                                    <?php endforeach; ?>
                                    <td>
                                        <div class="actions" style="margin: 0;">
                                            <a class="btn btn-secondary" href="?section=<?= h($sectionKey) ?>&action=edit&id=<?= (int) $row['id'] ?>">Bewerken</a>
                                            <a class="btn btn-danger" href="?section=<?= h($sectionKey) ?>&action=delete&id=<?= (int) $row['id'] ?>" onclick="return confirm('Dit item verwijderen?')">Verwijderen</a>
                                        </div>
                                    </td>
                                </tr>
                            <?php endforeach; ?>
                        </tbody>
                    </table>
                </div>
            </section>
        <?php endif; ?>
    </main>
</div>
</body>
</html>