162 lines
7.7 KiB
PHP
162 lines
7.7 KiB
PHP
<?php
|
|
/**
|
|
* MariaDB PDO Databaseverbinding & Automatische Tabellencontrole
|
|
*/
|
|
|
|
// Blokkeer directe HTTP toegang (Pen Test Beveiliging)
|
|
if (basename($_SERVER['SCRIPT_FILENAME'] ?? '') === 'database.php') {
|
|
http_response_code(403);
|
|
exit('Toegang geweigerd.');
|
|
}
|
|
|
|
require_once __DIR__ . '/config.php';
|
|
|
|
function get_db_connection(): PDO {
|
|
static $pdo = null;
|
|
|
|
if ($pdo !== null) {
|
|
return $pdo;
|
|
}
|
|
|
|
// 1. Controleer of de PDO MySQL/MariaDB driver aanwezig is in PHP
|
|
$availableDrivers = PDO::getAvailableDrivers();
|
|
if (!in_array('mysql', $availableDrivers)) {
|
|
error_log("PDO MySQL driver (pdo_mysql) ontbreekt in PHP.");
|
|
die("
|
|
<div style='font-family: sans-serif; background: #0c0f17; color: #f1f5f9; min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 20px;'>
|
|
<div style='max-width: 580px; background: #111827; border: 1px solid #ef4444; border-radius: 16px; padding: 30px;'>
|
|
<h2 style='color: #ef4444; margin-top: 0;'>⚠️ Database Driver Ontbreekt</h2>
|
|
<p style='color: #94a3b8; font-size: 14px;'>De extensie <strong>pdo_mysql</strong> is niet actief in deze PHP-omgeving.</p>
|
|
</div>
|
|
</div>
|
|
");
|
|
}
|
|
|
|
$options = [
|
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
|
PDO::ATTR_EMULATE_PREPARES => false,
|
|
PDO::ATTR_TIMEOUT => 5,
|
|
];
|
|
if (defined('PDO::MYSQL_ATTR_MULTI_STATEMENTS')) {
|
|
$options[PDO::MYSQL_ATTR_MULTI_STATEMENTS] = true;
|
|
}
|
|
|
|
$dsnWithDb = sprintf(
|
|
'mysql:host=%s;port=%s;dbname=%s;charset=%s',
|
|
DB_HOST,
|
|
DB_PORT,
|
|
DB_NAME,
|
|
DB_CHARSET
|
|
);
|
|
|
|
// 2. CHECK: Bestaat de database al?
|
|
try {
|
|
$pdo = new PDO($dsnWithDb, DB_USER, DB_PASS, $options);
|
|
ensure_tables_exist($pdo);
|
|
return $pdo;
|
|
|
|
} catch (PDOException $e) {
|
|
error_log("MariaDB Verbindingsfout [{$e->getCode()}]: {$e->getMessage()}");
|
|
|
|
// Foutcode 1049 betekent: Database 'DB_NAME' bestaat nog NIET op de MariaDB server
|
|
if ($e->getCode() == 1049 || str_contains($e->getMessage(), 'Unknown database')) {
|
|
try {
|
|
$serverDsn = sprintf('mysql:host=%s;port=%s;charset=%s', DB_HOST, DB_PORT, DB_CHARSET);
|
|
$serverPdo = new PDO($serverDsn, DB_USER, DB_PASS, $options);
|
|
$serverPdo->exec(sprintf(
|
|
'CREATE DATABASE IF NOT EXISTS `%s` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci',
|
|
DB_NAME
|
|
));
|
|
|
|
$pdo = new PDO($dsnWithDb, DB_USER, DB_PASS, $options);
|
|
ensure_tables_exist($pdo);
|
|
return $pdo;
|
|
|
|
} catch (PDOException $createEx) {
|
|
error_log("Kan database " . DB_NAME . " niet automatisch aanmaken: " . $createEx->getMessage());
|
|
}
|
|
}
|
|
|
|
// Pen Test beveiliging: in live omgeving geen interne IP's of database-details tonen!
|
|
if (defined('APP_ENV') && APP_ENV === 'live') {
|
|
die("
|
|
<div style='font-family: sans-serif; background: #0c0f17; color: #fff; padding: 40px; text-align: center; min-height: 100vh; display: flex; align-items: center; justify-content: center;'>
|
|
<div style='max-width: 480px; background: #111827; border: 1px solid #334155; border-radius: 16px; padding: 30px; text-align: center;'>
|
|
<div style='width: 48px; height: 48px; margin: 0 auto 16px; border-radius: 12px; background: rgba(239, 68, 68, 0.1); border: 1px solid rgba(239, 68, 68, 0.3); display: flex; align-items: center; justify-content: center; color: #f87171; font-weight: bold;'>⚠️</div>
|
|
<h2 style='color: #f87171; margin-top: 0; font-size: 18px;'>Database Tijdelijk Niet Bereikbaar</h2>
|
|
<p style='color: #94a3b8; font-size: 13px; line-height: 1.6;'>
|
|
Er kon geen veilige verbinding tot stand worden gebracht met de database. Probeer het over enkele ogenblikken opnieuw.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
");
|
|
} else {
|
|
die("
|
|
<div style='font-family: sans-serif; background: #0c0f17; color: #fff; padding: 40px; text-align: center; min-height: 100vh; display: flex; align-items: center; justify-content: center;'>
|
|
<div style='max-width: 520px; background: #111827; border: 1px solid #ef4444; border-radius: 16px; padding: 30px; text-align: left;'>
|
|
<h2 style='color: #ef4444; margin-top: 0;'>MariaDB Verbindingsfout (" . htmlspecialchars((string)$e->getCode()) . ")</h2>
|
|
<p style='color: #cbd5e1; font-size: 14px;'>" . htmlspecialchars($e->getMessage()) . "</p>
|
|
<div style='background: #0b0f17; border: 1px solid #1f2937; padding: 15px; border-radius: 10px; font-size: 13px; margin-top: 15px;'>
|
|
Host: <strong>" . htmlspecialchars(DB_HOST) . "</strong><br>
|
|
Poort: <strong>" . htmlspecialchars(DB_PORT) . "</strong><br>
|
|
Database: <strong>" . htmlspecialchars(DB_NAME) . "</strong><br>
|
|
Gebruiker: <strong>" . htmlspecialchars(DB_USER) . "</strong>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
");
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Zorgt ervoor dat ALLE benodigde tabellen en kolommen uit schema.sql aanwezig zijn in MariaDB
|
|
* Voert elke tabel individueel uit zodat ontbrekende tabellen direct aangemaakt worden.
|
|
*/
|
|
function ensure_tables_exist(PDO $pdo): void {
|
|
static $tablesChecked = false;
|
|
if ($tablesChecked) return;
|
|
$tablesChecked = true;
|
|
|
|
try {
|
|
$schemaFile = file_exists(__DIR__ . '/schema.sql') ? (__DIR__ . '/schema.sql') : (__DIR__ . '/../schema.sql');
|
|
if (file_exists($schemaFile)) {
|
|
$sql = file_get_contents($schemaFile);
|
|
$statements = array_filter(array_map('trim', explode(';', $sql)));
|
|
foreach ($statements as $stmt) {
|
|
$stmtClean = preg_replace('/^--.*$/m', '', $stmt);
|
|
$stmtClean = trim($stmtClean);
|
|
if (!empty($stmtClean)) {
|
|
try {
|
|
$pdo->exec($stmtClean);
|
|
} catch (Throwable $t) {
|
|
// Stil negeren indien tabel of relatie al bestaat
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Zorg ervoor dat alle kolommen en upgrades aanwezig zijn
|
|
$colUpgrades = [
|
|
"ALTER TABLE tasks MODIFY external_id VARCHAR(255) NULL",
|
|
"ALTER TABLE tasks ADD COLUMN external_url TEXT NULL AFTER external_id",
|
|
"ALTER TABLE users ADD COLUMN remember_token VARCHAR(64) NULL AFTER backup_codes",
|
|
"ALTER TABLE users ADD COLUMN remember_token_expires_at DATETIME NULL AFTER remember_token",
|
|
"ALTER TABLE users ADD COLUMN notification_settings TEXT NULL AFTER remember_token_expires_at",
|
|
"ALTER TABLE users ADD COLUMN theme VARCHAR(20) NOT NULL DEFAULT 'dark' AFTER notification_settings",
|
|
"ALTER TABLE users ADD COLUMN avatar_url VARCHAR(255) NULL AFTER theme",
|
|
"ALTER TABLE users ADD COLUMN backup_codes TEXT NULL AFTER two_factor_enabled",
|
|
];
|
|
foreach ($colUpgrades as $sql) {
|
|
try {
|
|
$pdo->exec($sql);
|
|
} catch (Throwable $t) {
|
|
// Stil negeren indien kolom al bestaat
|
|
}
|
|
}
|
|
} catch (Throwable $e) {
|
|
error_log("Fout bij controleren tabellen: " . $e->getMessage());
|
|
}
|
|
}
|