179 lines
5.4 KiB
PHP
179 lines
5.4 KiB
PHP
|
|
<?php
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create MySQL Views
|
||
|
|
* - Loads DB settings from ../xml/settings.xml
|
||
|
|
* - Scans current dir for files named view_*.php
|
||
|
|
* - Each view file should set: $SQL = "CREATE VIEW ...";
|
||
|
|
* - Drops view if exists, then creates it
|
||
|
|
*/
|
||
|
|
define('INITIALIZATION_FILE_NAME', __DIR__ . '/../xml/settings.xml');
|
||
|
|
|
||
|
|
$logs = [];
|
||
|
|
|
||
|
|
function logLine(array &$logs, string $msg): void {
|
||
|
|
$logs[] = $msg;
|
||
|
|
}
|
||
|
|
|
||
|
|
function renderPage(array $logs, bool $ok): void {
|
||
|
|
$status = $ok ? "✅ Done." : "❌ Stopped due to an error.";
|
||
|
|
?>
|
||
|
|
<!DOCTYPE html>
|
||
|
|
<html>
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<title>Create Views</title>
|
||
|
|
<style>
|
||
|
|
body {
|
||
|
|
background-color:#333333;
|
||
|
|
color:#fff;
|
||
|
|
font-family:sans-serif;
|
||
|
|
padding:1em;
|
||
|
|
}
|
||
|
|
.log {
|
||
|
|
margin-bottom: .5em;
|
||
|
|
}
|
||
|
|
.done {
|
||
|
|
margin-top: 1em;
|
||
|
|
font-weight: bold;
|
||
|
|
}
|
||
|
|
code {
|
||
|
|
background: rgba(255,255,255,.08);
|
||
|
|
padding: .15em .35em;
|
||
|
|
border-radius: 6px;
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<?php foreach ($logs as $line): ?>
|
||
|
|
<div class="log"><?= $line ?></div>
|
||
|
|
<?php endforeach; ?>
|
||
|
|
<div class="done"><?= $status ?></div>
|
||
|
|
</body>
|
||
|
|
</html>
|
||
|
|
<?php
|
||
|
|
}
|
||
|
|
|
||
|
|
function fail(array &$logs, string $msg, int $exitCode = 1): void {
|
||
|
|
logLine($logs, "❌ {$msg}");
|
||
|
|
renderPage($logs, false);
|
||
|
|
exit($exitCode);
|
||
|
|
}
|
||
|
|
|
||
|
|
function runSQL(PDO $db, ?string $sql, string $context, array &$logs): void {
|
||
|
|
if ($sql === null || trim($sql) === '') {
|
||
|
|
logLine($logs, "⚠️ <strong>{$context}</strong>: empty SQL. Skipping.");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
$db->exec($sql);
|
||
|
|
} catch (PDOException $e) {
|
||
|
|
fail($logs, "{$context}: " . htmlspecialchars($e->getMessage(), ENT_QUOTES));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// -----------------
|
||
|
|
// Load App Settings
|
||
|
|
// -----------------
|
||
|
|
|
||
|
|
if (!file_exists(INITIALIZATION_FILE_NAME)) {
|
||
|
|
fail($logs, "Initialization file not found: <code>" . htmlspecialchars(INITIALIZATION_FILE_NAME, ENT_QUOTES) . "</code>");
|
||
|
|
}
|
||
|
|
|
||
|
|
$applicationSettings = @simplexml_load_file(INITIALIZATION_FILE_NAME);
|
||
|
|
if (!$applicationSettings) {
|
||
|
|
fail($logs, "Unable to load Application Settings from <code>" . htmlspecialchars(INITIALIZATION_FILE_NAME, ENT_QUOTES) . "</code>.");
|
||
|
|
}
|
||
|
|
|
||
|
|
// -------------
|
||
|
|
// Connect to DB
|
||
|
|
// -------------
|
||
|
|
|
||
|
|
$host = (string) ($applicationSettings->DatabaseServer ?? '');
|
||
|
|
$database = (string) ($applicationSettings->DatabaseName ?? '');
|
||
|
|
$user = (string) ($applicationSettings->DatabaseUser ?? '');
|
||
|
|
$pass = (string) ($applicationSettings->DatabasePassword ?? '');
|
||
|
|
|
||
|
|
if ($host === '' || $database === '' || $user === '') {
|
||
|
|
fail($logs, "Missing DB settings in settings.xml (DatabaseServer/DatabaseName/DatabaseUser).");
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
$dsn = "mysql:host={$host};dbname={$database};charset=utf8mb4";
|
||
|
|
$db = new PDO($dsn, $user, $pass, [
|
||
|
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||
|
|
PDO::ATTR_EMULATE_PREPARES => false,
|
||
|
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||
|
|
]);
|
||
|
|
} catch (Throwable $e) {
|
||
|
|
fail($logs, "Unable to connect to the database: " . htmlspecialchars($e->getMessage(), ENT_QUOTES));
|
||
|
|
}
|
||
|
|
|
||
|
|
// ---------------------
|
||
|
|
// Find view_*.php files
|
||
|
|
// ---------------------
|
||
|
|
|
||
|
|
$dirFiles = scandir(__DIR__) ?: [];
|
||
|
|
$viewFiles = array_values(array_filter($dirFiles, function ($f) {
|
||
|
|
if (pathinfo($f, PATHINFO_EXTENSION) !== 'php')
|
||
|
|
return false;
|
||
|
|
if (strpos($f, 'view_') !== 0)
|
||
|
|
return false;
|
||
|
|
return is_file(__DIR__ . '/' . $f);
|
||
|
|
}));
|
||
|
|
|
||
|
|
if (!$viewFiles) {
|
||
|
|
logLine($logs, "⚠️ No view definition files found (expected <code>view_*.php</code>). Nothing to do.");
|
||
|
|
renderPage($logs, true);
|
||
|
|
exit(0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// ------------
|
||
|
|
// Create views
|
||
|
|
// ------------
|
||
|
|
|
||
|
|
$created = 0;
|
||
|
|
$failed = 0;
|
||
|
|
|
||
|
|
foreach ($viewFiles as $file) {
|
||
|
|
$viewName = pathinfo($file, PATHINFO_FILENAME);
|
||
|
|
logLine($logs, "Processing <strong>" . htmlspecialchars($viewName, ENT_QUOTES) . "</strong>...");
|
||
|
|
|
||
|
|
$SQL = null;
|
||
|
|
|
||
|
|
try {
|
||
|
|
$result = include __DIR__ . '/' . $file;
|
||
|
|
if ($result === false) {
|
||
|
|
$failed++;
|
||
|
|
logLine($logs, "❌ Failed to include <code>" . htmlspecialchars($file, ENT_QUOTES) . "</code>. Skipping.");
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
} catch (Throwable $e) {
|
||
|
|
$failed++;
|
||
|
|
logLine($logs, "❌ Exception including <code>" . htmlspecialchars($file, ENT_QUOTES) . "</code>: " . htmlspecialchars($e->getMessage(), ENT_QUOTES));
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Drop then create
|
||
|
|
try {
|
||
|
|
$db->exec("DROP VIEW IF EXISTS `{$viewName}`");
|
||
|
|
} catch (PDOException $e) {
|
||
|
|
// Non-fatal; keep going
|
||
|
|
logLine($logs, "⚠️ Could not drop <code>{$viewName}</code>: " . htmlspecialchars($e->getMessage(), ENT_QUOTES));
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
runSQL($db, $SQL, $viewName, $logs);
|
||
|
|
$created++;
|
||
|
|
logLine($logs, "✅ <code>{$viewName}</code> was created.");
|
||
|
|
} catch (Throwable $e) {
|
||
|
|
$failed++;
|
||
|
|
logLine($logs, "❌ Error creating <code>{$viewName}</code>: " . htmlspecialchars($e->getMessage(), ENT_QUOTES));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
logLine($logs, "<br/><strong>{$created}</strong> views created. <strong>{$failed}</strong> failed.");
|
||
|
|
renderPage($logs, $failed === 0);
|