Current directory: /home/klas4s23/domains/585455.klas4s23.mid-ica.nl/public_html/Gastenboek/uploads
<?php
require_once __DIR__ . '/../config/config.php';
function db(): PDO {
static $pdo = null;
if ($pdo === null) {
$dsn = 'mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8mb4';
$pdo = new PDO($dsn, DB_USER, DB_PASS, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
}
return $pdo;
}
function h(string $v): string {
return htmlspecialchars($v, ENT_QUOTES, 'UTF-8');
}
function redirect(string $path) {
if (strpos($path, 'http') !== 0) {
$path = $path[0] === '/' ? $path : '/' . $path;
$path = BASE_URL . $path;
}
header('Location: ' . $path);
exit;
}
function start_session() {
if (session_status() !== PHP_SESSION_ACTIVE) {
session_start();
}
}
function csrf_token(): string {
start_session();
if (empty($_SESSION['csrf'])) {
$_SESSION['csrf'] = bin2hex(random_bytes(32));
}
return $_SESSION['csrf'];
}
function csrf_field(): string {
return '<input type="hidden" name="csrf" value="' . h(csrf_token()) . '">';
}
function verify_csrf(): bool {
start_session();
return isset($_POST['csrf']) && hash_equals($_SESSION['csrf'] ?? '', $_POST['csrf']);
}
function flash_set(string $type, string $msg) {
start_session();
$_SESSION['flash'][] = ['type' => $type, 'msg' => $msg];
}
function flash_show(): string {
start_session();
$out = '';
if (!empty($_SESSION['flash'])) {
foreach ($_SESSION['flash'] as $f) {
$cls = $f['type'] === 'error' ? 'alert error' : 'alert success';
$out .= '<div class="' . $cls . '">' . h($f['msg']) . '</div>';
}
unset($_SESSION['flash']);
}
return $out;
}
function ensure_default_admin() {
// Create default superadmin (admin/admin) if not present
$pdo = db();
$stmt = $pdo->prepare("SELECT id FROM users WHERE username = 'admin' LIMIT 1");
$stmt->execute();
if (!$stmt->fetch()) {
$hash = password_hash('admin', PASSWORD_DEFAULT);
$pdo->prepare("INSERT INTO users (username, password_hash, role) VALUES ('admin', :hash, 'superadmin')")
->execute([':hash' => $hash]);
}
}
function count_table(string $table): int {
$pdo = db();
return (int) $pdo->query("SELECT COUNT(*) FROM {$table}")->fetchColumn();
}
function save_logo(array $file): ?string {
if (empty($file['name']) || $file['error'] === UPLOAD_ERR_NO_FILE) {
return null;
}
if ($file['error'] !== UPLOAD_ERR_OK) {
throw new RuntimeException('Upload mislukt.');
}
if ($file['size'] > 2 * 1024 * 1024) {
throw new RuntimeException('Bestand te groot (max 2MB).');
}
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
$allowed = ['image/png' => 'png', 'image/jpeg' => 'jpg', 'image/jpg' => 'jpg'];
if (!isset($allowed[$mime])) {
throw new RuntimeException('Alleen PNG en JPG zijn toegestaan.');
}
if (!is_dir(UPLOAD_DIR)) {
@mkdir(UPLOAD_DIR, 0775, true);
}
$name = bin2hex(random_bytes(8)) . '.' . $allowed[$mime];
$dest = UPLOAD_DIR . DIRECTORY_SEPARATOR . $name;
if (!move_uploaded_file($file['tmp_name'], $dest)) {
throw new RuntimeException('Kon bestand niet opslaan.');
}
// Web path
return 'assets/uploads/' . $name;
}
/**
* Check if a table contains a specific column (MySQL only).
*/
function table_has_column(string $table, string $column): bool {
try {
$pdo = db();
$stmt = $pdo->prepare("SHOW COLUMNS FROM `" . str_replace("`", "``", $table) . "` LIKE :col");
$stmt->execute([':col' => $column]);
return (bool)$stmt->fetch();
} catch (Throwable $e) {
return false;
}
}
function party_position(int $partyId, int $questionId): ?string {
$pdo = db();
$stmt = $pdo->prepare("SELECT position FROM party_positions WHERE party_id = :p AND question_id = :q");
$stmt->execute([':p' => $partyId, ':q' => $questionId]);
$row = $stmt->fetch();
return $row['position'] ?? null;
}
function set_party_position(int $partyId, int $questionId, string $pos): void {
$pdo = db();
$pos = in_array($pos, ['pro', 'neutral', 'contra'], true) ? $pos : 'neutral';
$pdo->prepare("
INSERT INTO party_positions (party_id, question_id, position)
VALUES (:p, :q, :pos)
ON DUPLICATE KEY UPDATE position = VALUES(position)
")->execute([':p' => $partyId, ':q' => $questionId, ':pos' => $pos]);
}