update
This commit is contained in:
@@ -6,20 +6,14 @@ ini_set('display_errors', '1');
|
||||
ini_set('display_startup_errors', '1');
|
||||
error_reporting(E_ALL);
|
||||
|
||||
// Pick config set: first try root files, otherwise fall back to env dir (prod/staging/...)
|
||||
$appEnvFromEnv = getenv('APP_ENV') ?: 'prod';
|
||||
$envDir = rtrim(__DIR__, '/\\') . '/' . $appEnvFromEnv;
|
||||
|
||||
foreach (['domaindata.php','settings.php'] as $cfgFile) {
|
||||
// Required config files live in /config (sync copies staging/prod here)
|
||||
foreach (['domaindata.php', 'settings.php'] as $cfgFile) {
|
||||
$rootPath = __DIR__ . '/' . $cfgFile;
|
||||
$envPath = $envDir . '/' . $cfgFile;
|
||||
|
||||
if (file_exists($rootPath)) {
|
||||
require_once $rootPath;
|
||||
} elseif (file_exists($envPath)) {
|
||||
require_once $envPath;
|
||||
} else {
|
||||
throw new \RuntimeException("Missing required config file: $cfgFile (looked for $rootPath or $envPath)");
|
||||
throw new \RuntimeException("Missing required config file: $cfgFile (expected $rootPath)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,10 +28,9 @@ spl_autoload_register(function ($class) {
|
||||
// 2. Funktionen laden
|
||||
require_once __DIR__ . '/../src/App/functions.php';
|
||||
|
||||
// 3. Konfiguration laden
|
||||
// Wir simulieren hier den Sync-Prozess: Wenn config/db.php nicht da ist, nimm staging.
|
||||
$configFile = file_exists(__DIR__ . '/db.php') ? __DIR__ . '/db.php' : __DIR__ . '/staging/db.php';
|
||||
$settingsFile = file_exists(__DIR__ . '/settings.php') ? __DIR__ . '/settings.php' : __DIR__ . '/staging/settings.php';
|
||||
// 3. Konfiguration laden (nur Root-Dateien; Sync kopiert staging/prod hierher)
|
||||
$settingsFile = __DIR__ . '/settings.php';
|
||||
$configFile = __DIR__ . '/db.php';
|
||||
|
||||
if (file_exists($settingsFile)) {
|
||||
require_once $settingsFile;
|
||||
@@ -45,4 +44,4 @@ if (file_exists($configFile)) {
|
||||
// Globales Config Objekt erstellen
|
||||
global $appConfig;
|
||||
$dbEnabled = defined('APP_DB_ENABLED') ? APP_DB_ENABLED : true;
|
||||
$appConfig = new \App\Config($dbConfig, $dbEnabled);
|
||||
$appConfig = new \App\Config($dbConfig, $dbEnabled);
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-gray-800 border-t border-gray-700 mt-auto">
|
||||
<div class="max-w-7xl mx-auto py-4 px-4 sm:px-6 lg:px-8">
|
||||
<p class="text-center text-gray-500 text-xs">© <?= date('Y') ?> Nexus Control Panel. System Status: Nominal.</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,38 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de" class="h-full bg-gray-900">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Nexus Control Panel</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<style>
|
||||
/* Custom Scrollbar für Nexus-Look */
|
||||
::-webkit-scrollbar { width: 8px; }
|
||||
::-webkit-scrollbar-track { background: #111827; }
|
||||
::-webkit-scrollbar-thumb { background: #374151; border-radius: 4px; }
|
||||
::-webkit-scrollbar-thumb:hover { background: #4B5563; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="h-full text-gray-300 font-sans antialiased flex flex-col">
|
||||
|
||||
<nav class="bg-gray-800 border-b border-gray-700">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex items-center justify-between h-16">
|
||||
<div class="flex items-center">
|
||||
<div class="flex-shrink-0 text-indigo-500 font-bold text-xl tracking-wider">
|
||||
NEXUS
|
||||
</div>
|
||||
<div class="hidden md:block">
|
||||
<div class="ml-10 flex items-baseline space-x-4">
|
||||
<a href="/" class="bg-gray-900 text-white px-3 py-2 rounded-md text-sm font-medium">Dashboard</a>
|
||||
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium">DHCP Leases</a>
|
||||
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Logs</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="flex-grow">
|
||||
<div class="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
|
||||
@@ -1,22 +1,59 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\App;
|
||||
|
||||
function app(): App
|
||||
{
|
||||
return App::get();
|
||||
}
|
||||
|
||||
function t(string $key, $default = '', array $vars = []): string
|
||||
{
|
||||
return app()->i18n()->get($key, $default, $vars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt ein Template-Partial.
|
||||
*
|
||||
* @param string $name Dateiname ohne .php
|
||||
* @param string $folder Unterordner in /public/partials/
|
||||
* @param string $folder Unterordner in /partials/
|
||||
* @param array $data Daten, die im Template verfügbar sein sollen
|
||||
*/
|
||||
function tpl(string $name, string $folder = 'landing', array $data = []): void
|
||||
{
|
||||
$path = __DIR__ . '/../../public/partials/' . $folder . '/' . $name . '.php';
|
||||
if (file_exists($path)) {
|
||||
extract($data);
|
||||
require $path;
|
||||
} else {
|
||||
echo "<!-- Template not found: {$folder}/{$name} -->";
|
||||
$base = __DIR__ . '/../../partials/';
|
||||
|
||||
foreach ([$name, $folder] as $value) {
|
||||
if (preg_match('/[^a-zA-Z0-9_\-]/', $value)) {
|
||||
echo "<!-- tpl(): invalid parameter -->";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$paths = [];
|
||||
if ($folder === 'landing') {
|
||||
$paths[] = $base . 'landing/' . $name . '.php';
|
||||
$paths[] = $base . 'landing/main/' . $name . '.php';
|
||||
} else {
|
||||
$paths[] = $base . 'structure/' . $name . '.php';
|
||||
}
|
||||
|
||||
$path = null;
|
||||
foreach ($paths as $candidate) {
|
||||
if (file_exists($candidate)) {
|
||||
$path = $candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($path === null) {
|
||||
echo "<!-- Template not found: {$folder}/{$name} -->";
|
||||
return;
|
||||
}
|
||||
|
||||
extract($data);
|
||||
require $path;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -25,4 +62,71 @@ function tpl(string $name, string $folder = 'landing', array $data = []): void
|
||||
function e(?string $string): string
|
||||
{
|
||||
return htmlspecialchars($string ?? '', ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
}
|
||||
|
||||
function app_primary_domain(): string
|
||||
{
|
||||
if (defined('APP_DOMAIN_PRIMARY')) {
|
||||
return APP_DOMAIN_PRIMARY;
|
||||
}
|
||||
if (defined('APP_DOMAIN_NAME')) {
|
||||
return APP_DOMAIN_NAME;
|
||||
}
|
||||
return $_SERVER['HTTP_HOST'] ?? '';
|
||||
}
|
||||
|
||||
function app_fakecheck_domain(): string
|
||||
{
|
||||
if (defined('APP_DOMAIN_FAKECHECK')) {
|
||||
return APP_DOMAIN_FAKECHECK;
|
||||
}
|
||||
return app_primary_domain();
|
||||
}
|
||||
|
||||
function asset_styles(): void
|
||||
{
|
||||
$styles = app()->assets()->styles();
|
||||
|
||||
$order = ['early' => 0, 'normal' => 1, 'late' => 2];
|
||||
usort($styles, fn($a, $b) => ($order[$a['priority']] ?? 1) <=> ($order[$b['priority']] ?? 1));
|
||||
|
||||
foreach ($styles as $s) {
|
||||
$href = $s['href'];
|
||||
$v = $s['version'];
|
||||
if ($v !== null && $v !== '') {
|
||||
$sep = (str_contains($href, '?') ? '&' : '?');
|
||||
$href = $href . $sep . 'v=' . rawurlencode((string)$v);
|
||||
}
|
||||
echo '<link rel="stylesheet" href="' . htmlspecialchars($href, ENT_QUOTES) . '">' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
function asset_scripts(string $pos = 'footer'): void
|
||||
{
|
||||
$scripts = ($pos === 'header') ? app()->assets()->headerScripts() : app()->assets()->footerScripts();
|
||||
|
||||
foreach ($scripts as $s) {
|
||||
$src = $s['src'];
|
||||
$v = $s['version'];
|
||||
if ($v !== null && $v !== '') {
|
||||
$sep = (str_contains($src, '?') ? '&' : '?');
|
||||
$src = $src . $sep . 'v=' . rawurlencode((string)$v);
|
||||
}
|
||||
|
||||
$attrs = '';
|
||||
if (!empty($s['defer'])) {
|
||||
$attrs .= ' defer';
|
||||
}
|
||||
if (!empty($s['async'])) {
|
||||
$attrs .= ' async';
|
||||
}
|
||||
|
||||
echo '<script src="' . htmlspecialchars($src, ENT_QUOTES) . '"' . $attrs . '></script>' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
function redirect(string $path): void
|
||||
{
|
||||
header('Location: ' . $path, true, 303);
|
||||
exit;
|
||||
}
|
||||
|
||||
103
src/helpers.php
103
src/helpers.php
@@ -1,103 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\App;
|
||||
|
||||
function app(): App
|
||||
{
|
||||
return App::get();
|
||||
}
|
||||
|
||||
function t(string $key, $default = '', array $vars = []): string
|
||||
{
|
||||
return app()->i18n()->get($key, $default, $vars);
|
||||
}
|
||||
|
||||
function tpl(string $file, string $type = 'structure', string $site = 'main'): void
|
||||
{
|
||||
$base = __DIR__ . '/../partials/';
|
||||
|
||||
// very small validation
|
||||
foreach ([$file, $type, $site] as $v) {
|
||||
if (preg_match('/[^a-zA-Z0-9_\-]/', $v)) {
|
||||
echo "<!-- tpl(): invalid parameter -->";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ($type === 'landing') {
|
||||
$path = $base . "landing/$site/$file.php";
|
||||
} else {
|
||||
$path = $base . "structure/$file.php";
|
||||
}
|
||||
|
||||
if (file_exists($path)) {
|
||||
include $path;
|
||||
} else {
|
||||
echo "<!-- tpl(): not found: $path -->";
|
||||
}
|
||||
}
|
||||
|
||||
function app_primary_domain(): string
|
||||
{
|
||||
if (defined('APP_DOMAIN_PRIMARY')) {
|
||||
return APP_DOMAIN_PRIMARY;
|
||||
}
|
||||
if (defined('APP_DOMAIN_NAME')) {
|
||||
return APP_DOMAIN_NAME;
|
||||
}
|
||||
return $_SERVER['HTTP_HOST'] ?? '';
|
||||
}
|
||||
|
||||
function app_fakecheck_domain(): string
|
||||
{
|
||||
if (defined('APP_DOMAIN_FAKECHECK')) {
|
||||
return APP_DOMAIN_FAKECHECK;
|
||||
}
|
||||
return app_primary_domain();
|
||||
}
|
||||
|
||||
function asset_styles(): void
|
||||
{
|
||||
$styles = app()->assets()->styles();
|
||||
|
||||
// simple priority order
|
||||
$order = ['early' => 0, 'normal' => 1, 'late' => 2];
|
||||
usort($styles, fn($a,$b) => ($order[$a['priority']] ?? 1) <=> ($order[$b['priority']] ?? 1));
|
||||
|
||||
foreach ($styles as $s) {
|
||||
$href = $s['href'];
|
||||
$v = $s['version'];
|
||||
if ($v !== null && $v !== '') {
|
||||
$sep = (str_contains($href, '?') ? '&' : '?');
|
||||
$href = $href . $sep . 'v=' . rawurlencode((string)$v);
|
||||
}
|
||||
echo '<link rel="stylesheet" href="' . htmlspecialchars($href, ENT_QUOTES) . '">' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
function asset_scripts(string $pos = 'footer'): void
|
||||
{
|
||||
$scripts = ($pos === 'header') ? app()->assets()->headerScripts() : app()->assets()->footerScripts();
|
||||
|
||||
foreach ($scripts as $s) {
|
||||
$src = $s['src'];
|
||||
$v = $s['version'];
|
||||
if ($v !== null && $v !== '') {
|
||||
$sep = (str_contains($src, '?') ? '&' : '?');
|
||||
$src = $src . $sep . 'v=' . rawurlencode((string)$v);
|
||||
}
|
||||
|
||||
$attrs = '';
|
||||
if (!empty($s['defer'])) $attrs .= ' defer';
|
||||
if (!empty($s['async'])) $attrs .= ' async';
|
||||
|
||||
echo '<script src="' . htmlspecialchars($src, ENT_QUOTES) . '"' . $attrs . '></script>' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
function redirect(string $path): void
|
||||
{
|
||||
header('Location: ' . $path, true, 303);
|
||||
exit;
|
||||
}
|
||||
Reference in New Issue
Block a user