From 8afba16905ecfdc82b3126fedcf47f4a5a8d0715 Mon Sep 17 00:00:00 2001 From: smueller Date: Fri, 22 May 2026 14:07:27 +0200 Subject: [PATCH] Enhance configuration management: Updated README.md with Windows sync instructions, refactored backend configuration files to improve loading logic, and ensured consistent function definitions. Improved error handling in bootstrap.php for better user feedback during application startup. --- README.md | 5 + backend/config/config.php | 2 +- backend/config/mail-config.php | 1 - backend/config/products-config.php | 2 +- backend/config/site-config.php | 33 +- backend/includes/functions.php | 58 ++- public/bootstrap.php | 76 ++-- public/config/config.php | 17 + public/config/mail-config.php | 197 ++++++++++ public/config/products-config.php | 556 +++++++++++++++++++++++++++++ public/config/site-config.php | 81 +++++ public/includes/footer.php | 167 +++++++++ public/includes/functions.php | 163 +++++++++ public/includes/header.php | 89 +++++ scripts/sync-backend-to-public.ps1 | 23 ++ 15 files changed, 1433 insertions(+), 37 deletions(-) create mode 100644 public/config/config.php create mode 100644 public/config/mail-config.php create mode 100644 public/config/products-config.php create mode 100644 public/config/site-config.php create mode 100644 public/includes/footer.php create mode 100644 public/includes/functions.php create mode 100644 public/includes/header.php create mode 100644 scripts/sync-backend-to-public.ps1 diff --git a/README.md b/README.md index 2449d77..c164cd8 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,11 @@ HexaHost-Frontend/ cp -r HexaHost-Backend/includes/* HexaHost-Frontend/public/includes/ ``` + Alternativ (Windows, aus diesem Repo mit `backend/`): + ```powershell + .\scripts\sync-backend-to-public.ps1 + ``` + 3. **PHP Dependencies installieren** ```bash cd HexaHost-Frontend/public diff --git a/backend/config/config.php b/backend/config/config.php index 60968a7..8edeb67 100644 --- a/backend/config/config.php +++ b/backend/config/config.php @@ -14,4 +14,4 @@ // Lade die neue Konfiguration require_once __DIR__ . '/mail-config.php'; -?> + diff --git a/backend/config/mail-config.php b/backend/config/mail-config.php index 46f0164..01f5700 100644 --- a/backend/config/mail-config.php +++ b/backend/config/mail-config.php @@ -195,4 +195,3 @@ function getHexaHostConfig($key = null) { return $config[$key] ?? null; } -?> \ No newline at end of file diff --git a/backend/config/products-config.php b/backend/config/products-config.php index faa4626..80a3040 100644 --- a/backend/config/products-config.php +++ b/backend/config/products-config.php @@ -553,4 +553,4 @@ function renderAllPackages($productId) { } return $html; } -?> + diff --git a/backend/config/site-config.php b/backend/config/site-config.php index 2dbd5e8..711eb1e 100644 --- a/backend/config/site-config.php +++ b/backend/config/site-config.php @@ -3,18 +3,25 @@ * HexaHost.de – zentrale Domain- und Umgebungskonfiguration */ -define('SITE_DOMAIN_PRODUCTION', 'hexahost.de'); -define('SITE_DOMAIN_DEVELOPMENT', 'dev.hexahost.de'); +if (!defined('SITE_DOMAIN_PRODUCTION')) { + define('SITE_DOMAIN_PRODUCTION', 'hexahost.de'); +} + +if (!defined('SITE_DOMAIN_DEVELOPMENT')) { + define('SITE_DOMAIN_DEVELOPMENT', 'dev.hexahost.de'); +} /** * Aktuellen HTTP-Host (ohne Port) ermitteln + * + * @return string */ -function getSiteHost(): string +function getSiteHost() { - $host = $_SERVER['HTTP_HOST'] ?? SITE_DOMAIN_PRODUCTION; + $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : SITE_DOMAIN_PRODUCTION; $host = strtolower($host); - if (str_contains($host, ':')) { + if (strpos($host, ':') !== false) { $host = explode(':', $host, 2)[0]; } @@ -23,16 +30,20 @@ function getSiteHost(): string /** * true, wenn die Seite unter der Dev-Domain läuft + * + * @return bool */ -function isDevelopmentSite(): bool +function isDevelopmentSite() { return getSiteHost() === SITE_DOMAIN_DEVELOPMENT; } /** * Basis-URL der aktuellen Anfrage (Schema + Host) + * + * @return string */ -function getSiteBaseUrl(): string +function getSiteBaseUrl() { $https = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (isset($_SERVER['SERVER_PORT']) && (int) $_SERVER['SERVER_PORT'] === 443); @@ -45,9 +56,9 @@ function getSiteBaseUrl(): string /** * Erlaubte CORS-Origins für AJAX (Kontaktformular) * - * @return list + * @return array */ -function getAllowedOrigins(): array +function getAllowedOrigins() { return [ 'https://' . SITE_DOMAIN_PRODUCTION, @@ -61,8 +72,10 @@ function getAllowedOrigins(): array /** * Kanonische Basis-URL für SEO (Produktion immer hexahost.de) + * + * @return string */ -function getCanonicalBaseUrl(): string +function getCanonicalBaseUrl() { return 'https://' . SITE_DOMAIN_PRODUCTION; } diff --git a/backend/includes/functions.php b/backend/includes/functions.php index 2eb5041..9ed31ce 100644 --- a/backend/includes/functions.php +++ b/backend/includes/functions.php @@ -7,7 +7,62 @@ $configDir = defined('HEXAHOST_CONFIG_DIR') ? HEXAHOST_CONFIG_DIR : __DIR__ . '/../config'; -require_once $configDir . '/site-config.php'; +$siteConfigFile = $configDir . '/site-config.php'; +if (is_file($siteConfigFile)) { + require_once $siteConfigFile; +} elseif (!function_exists('getSiteHost')) { + define('SITE_DOMAIN_PRODUCTION', 'hexahost.de'); + define('SITE_DOMAIN_DEVELOPMENT', 'dev.hexahost.de'); + + function getSiteHost() + { + $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : SITE_DOMAIN_PRODUCTION; + $host = strtolower($host); + if (strpos($host, ':') !== false) { + $host = explode(':', $host, 2)[0]; + } + return $host; + } + + function isDevelopmentSite() + { + return getSiteHost() === SITE_DOMAIN_DEVELOPMENT; + } + + function getSiteBaseUrl() + { + $https = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') + || (isset($_SERVER['SERVER_PORT']) && (int) $_SERVER['SERVER_PORT'] === 443); + return ($https ? 'https' : 'http') . '://' . getSiteHost(); + } + + function getAllowedOrigins() + { + return [ + 'https://' . SITE_DOMAIN_PRODUCTION, + 'https://www.' . SITE_DOMAIN_PRODUCTION, + 'https://' . SITE_DOMAIN_DEVELOPMENT, + 'http://localhost', + 'http://127.0.0.1', + 'http://localhost:8000', + ]; + } + + function getCanonicalBaseUrl() + { + return 'https://' . SITE_DOMAIN_PRODUCTION; + } +} + +// Fehleranzeige auf Dev/localhost für einfacheres Debugging +$hexahostHost = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ''; +if ( + (function_exists('isDevelopmentSite') && isDevelopmentSite()) + || preg_match('/^(localhost|127\.0\.0\.1)(:\d+)?$/', $hexahostHost) +) { + ini_set('display_errors', '1'); + ini_set('display_startup_errors', '1'); +} // Sichere Session-Konfiguration if (session_status() === PHP_SESSION_NONE) { @@ -106,4 +161,3 @@ function generateCSRFToken() { } return $_SESSION['csrf_token']; } -?> \ No newline at end of file diff --git a/public/bootstrap.php b/public/bootstrap.php index 400276a..0773e5a 100644 --- a/public/bootstrap.php +++ b/public/bootstrap.php @@ -1,39 +1,71 @@ __DIR__ . '/includes', - 'config' => __DIR__ . '/config', - ], - [ - 'includes' => __DIR__ . '/../backend/includes', - 'config' => __DIR__ . '/../backend/config', - ], - ]; + function hexahost_path_candidates(): array + { + $backendIncludes = dirname(__DIR__) . '/backend/includes'; + $backendConfig = dirname(__DIR__) . '/backend/config'; + $publicIncludes = __DIR__ . '/includes'; + $publicConfig = __DIR__ . '/config'; + + return [ + ['includes' => $backendIncludes, 'config' => $backendConfig], + ['includes' => $publicIncludes, 'config' => $publicConfig], + ['includes' => $publicIncludes, 'config' => $backendConfig], + ['includes' => $backendIncludes, 'config' => $publicConfig], + ]; + } + + function hexahost_is_app_root_valid(string $includesDir, string $configDir): bool + { + $required = [ + $includesDir . '/functions.php', + $includesDir . '/header.php', + $includesDir . '/footer.php', + $configDir . '/products-config.php', + ]; + + foreach ($required as $file) { + if (!is_file($file)) { + return false; + } + } + + return true; + } $resolved = false; - foreach ($pathCandidates as $paths) { - if (is_file($paths['includes'] . '/functions.php')) { - define('HEXAHOST_INCLUDES_DIR', $paths['includes']); - define('HEXAHOST_CONFIG_DIR', $paths['config']); - require_once $paths['includes'] . '/functions.php'; - $resolved = true; - break; + foreach (hexahost_path_candidates() as $paths) { + if (!hexahost_is_app_root_valid($paths['includes'], $paths['config'])) { + continue; } + + define('HEXAHOST_INCLUDES_DIR', $paths['includes']); + define('HEXAHOST_CONFIG_DIR', $paths['config']); + require_once $paths['includes'] . '/functions.php'; + $resolved = true; + break; } if (!$resolved) { http_response_code(500); - header('Content-Type: text/plain; charset=utf-8'); - echo 'HexaHost: Anwendung konnte nicht gestartet werden (includes nicht gefunden).'; + header('Content-Type: text/html; charset=utf-8'); + echo 'HexaHost'; + echo '

HexaHost: Seite konnte nicht geladen werden

'; + echo '

PHP konnte die Anwendungsdateien nicht finden.

'; + echo '

Dev-Branch: Repository mit Ordner backend/ neben public/ deployen.

'; + echo '

Produktion: Vor dem Upload scripts/sync-backend-to-public.ps1 ausführen '; + echo 'oder backend/includes und backend/config nach public/ kopieren.

'; + echo ''; exit; } diff --git a/public/config/config.php b/public/config/config.php new file mode 100644 index 0000000..8edeb67 --- /dev/null +++ b/public/config/config.php @@ -0,0 +1,17 @@ + 'HexaHost.de Contact Form', + 'X-Priority' => '3', + 'X-MSMail-Priority' => 'Normal', + 'Importance' => 'Normal', + 'X-Report-Abuse' => 'Please report abuse here: abuse@hexahost.de', + 'List-Unsubscribe' => '', + 'Precedence' => 'bulk' +]); + +// Erlaubte Domains für E-Mail-Adressen (optional) +define('ALLOWED_EMAIL_DOMAINS', [ + // Leer lassen für alle Domains zu erlauben + // 'gmail.com', + // 'outlook.com', + // 'web.de', + // 'gmx.de' +]); + +// Blacklist für E-Mail-Adressen (optional) +define('BLACKLISTED_EMAILS', [ + // 'spam@example.com', + // 'test@test.com' +]); + +// Validierung der Konfiguration +if (!defined('SMTP_HOST') || !defined('SMTP_USERNAME') || !defined('SMTP_PASSWORD')) { + die('SMTP-Konfiguration ist unvollständig. Bitte überprüfen Sie die mail-config.php'); +} + +// Überprüfung der E-Mail-Adressen +if (!filter_var(SMTP_FROM_EMAIL, FILTER_VALIDATE_EMAIL)) { + die('Ungültige SMTP_FROM_EMAIL Adresse'); +} + +if (!filter_var(SMTP_TO_EMAIL, FILTER_VALIDATE_EMAIL)) { + die('Ungültige SMTP_TO_EMAIL Adresse'); +} + +// Logging-Funktion +function logEmail($type, $data) { + if (!LOG_EMAILS) return; + + $logFile = __DIR__ . '/../logs/email.log'; + $logDir = dirname($logFile); + + if (!is_dir($logDir)) { + mkdir($logDir, 0755, true); + } + + $timestamp = date('Y-m-d H:i:s'); + $logEntry = "[$timestamp] $type: " . json_encode($data) . "\n"; + + file_put_contents($logFile, $logEntry, FILE_APPEND | LOCK_EX); +} + +// Hilfsfunktion für E-Mail-Validierung +function isValidEmail($email) { + if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + return false; + } + + // Prüfe Blacklist + if (in_array($email, BLACKLISTED_EMAILS)) { + return false; + } + + // Prüfe Domain-Whitelist (falls gesetzt) + if (!empty(ALLOWED_EMAIL_DOMAINS)) { + $domain = substr(strrchr($email, "@"), 1); + if (!in_array($domain, ALLOWED_EMAIL_DOMAINS)) { + return false; + } + } + + return true; +} + +// CSRF Token generieren (wird in functions.php verwendet) +// Hinweis: Diese Funktion existiert auch in functions.php - hier nur als Fallback +if (!function_exists('generateCSRFToken')) { + function generateCSRFToken() { + if (!isset($_SESSION['csrf_token'])) { + $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); + } + return $_SESSION['csrf_token']; + } +} + +// CSRF Token validieren +if (!function_exists('validateCSRFToken')) { + function validateCSRFToken($token) { + return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token); + } +} + +/** + * Hilfsfunktion zum Abrufen der Konfiguration als Array + * Kompatibilität mit contact-handler.php + * + * @param string|null $key Optional: einzelner Schlüssel + * @return mixed Konfigurationsarray oder einzelner Wert + */ +function getHexaHostConfig($key = null) { + $config = [ + // SMTP Server-Einstellungen + 'smtp_host' => SMTP_HOST, + 'smtp_port' => SMTP_PORT, + 'smtp_username' => SMTP_USERNAME, + 'smtp_password' => SMTP_PASSWORD, + 'smtp_encryption' => 'tls', + + // Absender/Empfänger + 'from_email' => SMTP_FROM_EMAIL, + 'from_name' => 'HexaHost.de Kontaktformular', + 'to_email' => SMTP_TO_EMAIL, + 'to_name' => 'HexaHost Support', + + // Sicherheit + 'max_requests_per_hour' => MAX_REQUESTS_PER_HOUR, + 'honeypot_field' => 'website', + + // Debug + 'debug_mode' => DEBUG_MODE, + 'log_errors' => LOG_EMAILS, + ]; + + if ($key === null) { + return $config; + } + + return $config[$key] ?? null; +} diff --git a/public/config/products-config.php b/public/config/products-config.php new file mode 100644 index 0000000..80a3040 --- /dev/null +++ b/public/config/products-config.php @@ -0,0 +1,556 @@ + 'Virtual Private Container', + 'short_name' => 'VPC', + 'description' => 'Effiziente LXC-Container auf Proxmox-Basis', + 'min_price' => '4,99', + 'hero_highlight' => 'auf Proxmox LXC', + 'hero_description' => 'Erleben Sie die Effizienz von Linux-Containern mit der Zuverlässigkeit von Proxmox. Unsere VPC-Lösungen bieten optimale Performance bei minimalem Ressourcenverbrauch.', + 'packages_title' => 'VPC Pakete', + 'packages_description' => 'Wählen Sie das perfekte Container-Paket für Ihre Anforderungen', + 'cta_title' => 'Bereit für Ihren VPC?', + 'cta_description' => 'Starten Sie noch heute mit einem Virtual Private Container', + 'page_title' => 'Virtual Private Container - Effiziente LXC Container | HexaHost.de', + 'page_description' => 'Virtual Private Container auf Proxmox LXC-Basis. Effiziente und preiswerte Container-Lösungen ab 4,99€/Monat bei HexaHost.de', + 'packages' => [ + 'starter' => [ + 'name' => 'VPC Starter', + 'price' => '4,99', + 'featured' => false, + 'specs' => [ + ['label' => 'CPU Kerne', 'value' => '1 vCore'], + ['label' => 'RAM', 'value' => '1 GB'], + ['label' => 'SSD Speicher', 'value' => '20 GB'], + ['label' => 'Traffic', 'value' => '1 TB'], + ['label' => 'IPv4 Adressen', 'value' => '1'], + ], + 'features' => [ + 'Proxmox LXC Container', + 'Root-Zugriff', + 'SSH-Zugang', + 'Backup inklusive', + '24/7 Monitoring', + ], + ], + 'business' => [ + 'name' => 'VPC Business', + 'price' => '9,99', + 'featured' => true, + 'specs' => [ + ['label' => 'CPU Kerne', 'value' => '2 vCores'], + ['label' => 'RAM', 'value' => '4 GB'], + ['label' => 'SSD Speicher', 'value' => '80 GB'], + ['label' => 'Traffic', 'value' => '3 TB'], + ['label' => 'IPv4 Adressen', 'value' => '1'], + ], + 'features' => [ + 'Proxmox LXC Container', + 'Root-Zugriff', + 'SSH-Zugang', + 'Tägliches Backup', + '24/7 Monitoring', + 'Snapshot-Funktion', + ], + ], + 'professional' => [ + 'name' => 'VPC Professional', + 'price' => '19,99', + 'featured' => false, + 'specs' => [ + ['label' => 'CPU Kerne', 'value' => '4 vCores'], + ['label' => 'RAM', 'value' => '8 GB'], + ['label' => 'SSD Speicher', 'value' => '160 GB'], + ['label' => 'Traffic', 'value' => '5 TB'], + ['label' => 'IPv4 Adressen', 'value' => '2'], + ], + 'features' => [ + 'Proxmox LXC Container', + 'Root-Zugriff', + 'SSH-Zugang', + 'Stündliches Backup', + '24/7 Monitoring', + 'Snapshot-Funktion', + 'Priority Support', + ], + ], + 'enterprise' => [ + 'name' => 'VPC Enterprise', + 'price' => '39,99', + 'featured' => false, + 'specs' => [ + ['label' => 'CPU Kerne', 'value' => '8 vCores'], + ['label' => 'RAM', 'value' => '16 GB'], + ['label' => 'SSD Speicher', 'value' => '320 GB'], + ['label' => 'Traffic', 'value' => '10 TB'], + ['label' => 'IPv4 Adressen', 'value' => '3'], + ], + 'features' => [ + 'Proxmox LXC Container', + 'Root-Zugriff', + 'SSH-Zugang', + 'Stündliches Backup', + '24/7 Monitoring', + 'Snapshot-Funktion', + 'Priority Support', + 'Individuelle Konfiguration', + ], + ], + ], +]; + +// ============================================================================ +// VIRTUAL PRIVATE SERVER (VPS) +// ============================================================================ +$PRODUCTS['vps'] = [ + 'name' => 'Virtual Private Server', + 'short_name' => 'VPS', + 'description' => 'Vollwertige KVM-Virtualisierung mit Root-Zugriff', + 'min_price' => '9,99', + 'hero_highlight' => 'auf Proxmox KVM', + 'hero_description' => 'Maximale Flexibilität und Kontrolle mit vollwertiger KVM-Virtualisierung. Installieren Sie jedes Betriebssystem und genießen Sie vollständigen Root-Zugriff.', + 'packages_title' => 'VPS Pakete', + 'packages_description' => 'Wählen Sie das perfekte VPS-Paket für Ihre Anforderungen', + 'cta_title' => 'Bereit für Ihren VPS?', + 'cta_description' => 'Starten Sie noch heute mit einem Virtual Private Server', + 'page_title' => 'Virtual Private Server - KVM Virtualisierung | HexaHost.de', + 'page_description' => 'Virtual Private Server auf Proxmox KVM-Basis. Vollwertige Virtualisierung mit Root-Zugriff ab 9,99€/Monat bei HexaHost.de', + 'packages' => [ + 'starter' => [ + 'name' => 'VPS Starter', + 'price' => '9,99', + 'featured' => false, + 'specs' => [ + ['label' => 'CPU Kerne', 'value' => '1 vCore'], + ['label' => 'RAM', 'value' => '2 GB'], + ['label' => 'SSD Speicher', 'value' => '40 GB'], + ['label' => 'Traffic', 'value' => '2 TB'], + ['label' => 'IPv4 Adressen', 'value' => '1'], + ], + 'features' => [ + 'Proxmox KVM Virtualisierung', + 'Root-Zugriff', + 'SSH-Zugang', + 'Backup inklusive', + '24/7 Monitoring', + ], + ], + 'business' => [ + 'name' => 'VPS Business', + 'price' => '19,99', + 'featured' => true, + 'specs' => [ + ['label' => 'CPU Kerne', 'value' => '2 vCores'], + ['label' => 'RAM', 'value' => '4 GB'], + ['label' => 'SSD Speicher', 'value' => '80 GB'], + ['label' => 'Traffic', 'value' => '4 TB'], + ['label' => 'IPv4 Adressen', 'value' => '1'], + ], + 'features' => [ + 'Proxmox KVM Virtualisierung', + 'Root-Zugriff', + 'SSH-Zugang', + 'Tägliches Backup', + '24/7 Monitoring', + 'Snapshot-Funktion', + ], + ], + 'professional' => [ + 'name' => 'VPS Professional', + 'price' => '39,99', + 'featured' => false, + 'specs' => [ + ['label' => 'CPU Kerne', 'value' => '4 vCores'], + ['label' => 'RAM', 'value' => '8 GB'], + ['label' => 'SSD Speicher', 'value' => '160 GB'], + ['label' => 'Traffic', 'value' => '8 TB'], + ['label' => 'IPv4 Adressen', 'value' => '2'], + ], + 'features' => [ + 'Proxmox KVM Virtualisierung', + 'Root-Zugriff', + 'SSH-Zugang', + 'Stündliches Backup', + '24/7 Monitoring', + 'Snapshot-Funktion', + 'Priority Support', + ], + ], + 'enterprise' => [ + 'name' => 'VPS Enterprise', + 'price' => '79,99', + 'featured' => false, + 'specs' => [ + ['label' => 'CPU Kerne', 'value' => '8 vCores'], + ['label' => 'RAM', 'value' => '16 GB'], + ['label' => 'SSD Speicher', 'value' => '320 GB'], + ['label' => 'Traffic', 'value' => '15 TB'], + ['label' => 'IPv4 Adressen', 'value' => '3'], + ], + 'features' => [ + 'Proxmox KVM Virtualisierung', + 'Root-Zugriff', + 'SSH-Zugang', + 'Stündliches Backup', + '24/7 Monitoring', + 'Snapshot-Funktion', + 'Priority Support', + 'Individuelle Konfiguration', + ], + ], + ], +]; + +// ============================================================================ +// MAIL GATEWAY +// ============================================================================ +$PRODUCTS['mail-gateway'] = [ + 'name' => 'Mail Gateway', + 'short_name' => 'Mail', + 'description' => 'Professioneller E-Mail-Schutz für Unternehmen', + 'min_price' => '4,99', + 'hero_highlight' => 'für Unternehmen', + 'hero_description' => 'Professionelle E-Mail-Infrastruktur mit maximalem Schutz vor Spam und Malware. Sichern Sie Ihre geschäftliche Kommunikation mit unseren Mail Gateway Lösungen.', + 'packages_title' => 'Mail Gateway Pakete', + 'packages_description' => 'Wählen Sie das passende Mail Gateway Paket für Ihr Unternehmen', + 'cta_title' => 'Bereit für professionelle E-Mail-Kommunikation?', + 'cta_description' => 'Starten Sie noch heute mit unserem Mail Gateway', + 'page_title' => 'Mail Gateway - Professionelle E-Mail-Lösungen | HexaHost.de', + 'page_description' => 'Professionelle Mail Gateway Lösungen für Unternehmen. Spam-Schutz, E-Mail-Archivierung und sichere E-Mail-Kommunikation bei HexaHost.de', + 'packages' => [ + 'starter' => [ + 'name' => 'Mail Starter', + 'price' => '4,99', + 'featured' => false, + 'specs' => [ + ['label' => 'Postfächer', 'value' => '5'], + ['label' => 'Speicher/Postfach', 'value' => '5 GB'], + ['label' => 'Domains', 'value' => '1'], + ['label' => 'E-Mails/Tag', 'value' => '500'], + ], + 'features' => [ + 'Spam-Filter', + 'Virus-Schutz', + 'Webmail', + 'IMAP/POP3', + 'SSL/TLS Verschlüsselung', + ], + ], + 'business' => [ + 'name' => 'Mail Business', + 'price' => '14,99', + 'featured' => true, + 'specs' => [ + ['label' => 'Postfächer', 'value' => '25'], + ['label' => 'Speicher/Postfach', 'value' => '10 GB'], + ['label' => 'Domains', 'value' => '3'], + ['label' => 'E-Mails/Tag', 'value' => '2.000'], + ], + 'features' => [ + 'Spam-Filter (erweitert)', + 'Virus-Schutz', + 'Webmail', + 'IMAP/POP3', + 'SSL/TLS Verschlüsselung', + ], + ], + 'professional' => [ + 'name' => 'Mail Professional', + 'price' => '29,99', + 'featured' => false, + 'specs' => [ + ['label' => 'Postfächer', 'value' => '100'], + ['label' => 'Speicher/Postfach', 'value' => '25 GB'], + ['label' => 'Domains', 'value' => '10'], + ['label' => 'E-Mails/Tag', 'value' => '10.000'], + ], + 'features' => [ + 'Spam-Filter (KI-gestützt)', + 'Virus-Schutz', + 'Webmail', + 'IMAP/POP3', + 'SSL/TLS Verschlüsselung', + ], + ], + 'enterprise' => [ + 'name' => 'Mail Enterprise', + 'price' => '59,99', + 'featured' => false, + 'specs' => [ + ['label' => 'Postfächer', 'value' => 'Unbegrenzt'], + ['label' => 'Speicher/Postfach', 'value' => '50 GB'], + ['label' => 'Domains', 'value' => 'Unbegrenzt'], + ['label' => 'E-Mails/Tag', 'value' => 'Unbegrenzt'], + ], + 'features' => [ + 'Spam-Filter (KI-gestützt)', + 'Virus-Schutz', + 'Webmail', + 'IMAP/POP3', + 'SSL/TLS Verschlüsselung', + 'Dedizierte IP', + 'Priority Support', + ], + ], + ], +]; + +// ============================================================================ +// WEBHOSTING +// ============================================================================ +$PRODUCTS['webhosting'] = [ + 'name' => 'Webhosting', + 'short_name' => 'Webhosting', + 'description' => 'Klassisches Hosting mit PHP, MySQL und SSL. WordPress-ready mit Plesk Webhosting.', + 'min_price' => '2,99', + 'hero_highlight' => 'Alles für Ihre Website', + 'hero_description' => 'Klassisches Webhosting mit allem, was Sie für eine erfolgreiche Website benötigen. PHP, MySQL, SSL-Zertifikate und E-Mail-Postfächer - alles inklusive.', + 'packages_title' => 'Webhosting Pakete', + 'packages_description' => 'Von der ersten Website bis zum professionellen Online-Shop', + 'cta_title' => 'Bereit für Ihr Webhosting?', + 'cta_description' => 'Starten Sie noch heute mit professionellem Webhosting', + 'page_title' => 'Webhosting - Klassisches Hosting für Websites - WordPress-ready | HexaHost.de', + 'page_description' => 'Webhosting mit PHP, MySQL und SSL-Zertifikaten. Klassisches Hosting für Websites - WordPress-ready ab 2,99€/Monat bei HexaHost.de', + 'packages' => [ + 'starter' => [ + 'name' => 'Webhosting Starter', + 'price' => '2,99', + 'featured' => false, + 'specs' => [ + ['label' => 'Webspace', 'value' => '10 GB'], + ['label' => 'Domains', 'value' => '1'], + ['label' => 'Subdomains', 'value' => '5'], + ['label' => 'Domain Aliase', 'value' => '2'], + ['label' => 'E-Mail-Postfächer', 'value' => '10'], + ['label' => 'Datenbanken', 'value' => '2 MySQL'], + ['label' => 'Traffic', 'value' => '100 GB'], + ], + 'features' => [ + 'Plesk Webhosting', + 'PHP 8.4', + 'Git, WP Toolkit, Composer', + 'SSL-Zertifikat', + 'E-Mail-Postfächer', + 'MySQL Datenbanken', + ], + ], + 'business' => [ + 'name' => 'Webhosting Business', + 'price' => '7,99', + 'featured' => true, + 'specs' => [ + ['label' => 'Webspace', 'value' => '30 GB'], + ['label' => 'Domains Inkl.', 'value' => '1'], + ['label' => 'Subdomains', 'value' => '10'], + ['label' => 'Domain Aliase', 'value' => '2'], + ['label' => 'E-Mail-Postfächer', 'value' => '20'], + ['label' => 'Datenbanken', 'value' => '5 MySQL'], + ['label' => 'Traffic', 'value' => '100 GB'], + ], + 'features' => [ + 'Plesk Webhosting', + 'PHP 8.4', + 'Git, WP Toolkit, Composer', + 'SSL-Zertifikat', + 'E-Mail-Postfächer', + 'MySQL Datenbanken', + 'Backup-Service', + ], + ], + 'professional' => [ + 'name' => 'Webhosting Professional', + 'price' => '13,99', + 'featured' => false, + 'specs' => [ + ['label' => 'Webspace', 'value' => '50 GB'], + ['label' => 'Domains Inkl.', 'value' => '1'], + ['label' => 'Subdomains', 'value' => 'unbegrenzt'], + ['label' => 'Domain Aliase', 'value' => 'unbegrenzt'], + ['label' => 'E-Mail-Postfächer', 'value' => '20'], + ['label' => 'Datenbanken', 'value' => '20 MySQL'], + ['label' => 'Traffic', 'value' => '100 GB'], + ], + 'features' => [ + 'Plesk Webhosting', + 'PHP 8.4', + 'Git, WP Toolkit, Composer', + 'SSL-Zertifikat', + 'E-Mail-Postfächer', + 'MySQL Datenbanken', + 'Backup-Service', + 'Priority Support', + ], + ], + 'enterprise' => [ + 'name' => 'Webhosting Enterprise', + 'price' => '19,99', + 'featured' => false, + 'specs' => [ + ['label' => 'Webspace', 'value' => '100 GB'], + ['label' => 'Domains Inkl.', 'value' => '3'], + ['label' => 'Subdomains', 'value' => 'unbegrenzt'], + ['label' => 'Domain Aliase', 'value' => 'unbegrenzt'], + ['label' => 'E-Mail-Postfächer', 'value' => '100'], + ['label' => 'Datenbanken', 'value' => 'Unbegrenzt'], + ['label' => 'Traffic', 'value' => '1 TB'], + ], + 'features' => [ + 'Plesk Webhosting', + 'PHP 8.4', + 'Git, WP Toolkit, Composer', + 'SSL-Zertifikat', + 'E-Mail-Postfächer', + 'MySQL Datenbanken', + 'Backup-Service', + 'Priority Support', + 'Individuelle Konfiguration', + ], + ], + ], +]; + +// ============================================================================ +// HILFSFUNKTIONEN +// ============================================================================ + +/** + * Alle Produkte abrufen + */ +function getAllProducts() { + global $PRODUCTS; + return $PRODUCTS; +} + +/** + * Ein Produkt abrufen + */ +function getProduct($productId) { + global $PRODUCTS; + return $PRODUCTS[$productId] ?? null; +} + +/** + * Prüft, ob ein Produkt im Shop angezeigt werden soll + */ +function isProductVisible($productId) { + global $HIDDEN_PRODUCTS; + return !in_array($productId, $HIDDEN_PRODUCTS, true); +} + +/** + * Alle Pakete eines Produkts abrufen + */ +function getProductPackages($productId) { + global $PRODUCTS; + return $PRODUCTS[$productId]['packages'] ?? []; +} + +/** + * Ein bestimmtes Paket abrufen + */ +function getPackage($productId, $packageId) { + global $PRODUCTS; + return $PRODUCTS[$productId]['packages'][$packageId] ?? null; +} + +/** + * Preis eines Pakets abrufen + */ +function getPackagePrice($productId, $packageId) { + $package = getPackage($productId, $packageId); + return $package['price'] ?? null; +} + +/** + * Minimalen Preis eines Produkts abrufen + */ +function getMinPrice($productId) { + global $PRODUCTS; + return $PRODUCTS[$productId]['min_price'] ?? null; +} + +/** + * Preis formatiert ausgeben + */ +function formatPrice($price, $withCurrency = true) { + return $withCurrency ? $price . '€' : $price; +} + +/** + * Generiert HTML für eine Paket-Karte + */ +function renderPackageCard($productId, $packageId, $package) { + $featuredClass = $package['featured'] ? ' featured' : ''; + $featuredBadge = $package['featured'] ? '' : ''; + + $specsHtml = ''; + foreach ($package['specs'] as $spec) { + $specsHtml .= sprintf( + '
%s:%s
', + htmlspecialchars($spec['label']), + htmlspecialchars($spec['value']) + ); + } + + $featuresHtml = ''; + foreach ($package['features'] as $feature) { + $featuresHtml .= sprintf('
✓ %s
', htmlspecialchars($feature)); + } + + return sprintf(' +
+ %s +
+

%s

+
+ %s€ + /Monat +
+
+
+ %s +
+
+ %s +
+ Jetzt bestellen +
', + $featuredClass, + $featuredBadge, + htmlspecialchars($package['name']), + $package['price'], + $specsHtml, + $featuresHtml, + $productId, + $packageId + ); +} + +/** + * Generiert HTML für alle Pakete eines Produkts + */ +function renderAllPackages($productId) { + $packages = getProductPackages($productId); + $html = ''; + foreach ($packages as $packageId => $package) { + $html .= renderPackageCard($productId, $packageId, $package); + } + return $html; +} + diff --git a/public/config/site-config.php b/public/config/site-config.php new file mode 100644 index 0000000..711eb1e --- /dev/null +++ b/public/config/site-config.php @@ -0,0 +1,81 @@ + + */ +function getAllowedOrigins() +{ + return [ + 'https://' . SITE_DOMAIN_PRODUCTION, + 'https://www.' . SITE_DOMAIN_PRODUCTION, + 'https://' . SITE_DOMAIN_DEVELOPMENT, + 'http://localhost', + 'http://127.0.0.1', + 'http://localhost:8000', + ]; +} + +/** + * Kanonische Basis-URL für SEO (Produktion immer hexahost.de) + * + * @return string + */ +function getCanonicalBaseUrl() +{ + return 'https://' . SITE_DOMAIN_PRODUCTION; +} diff --git a/public/includes/footer.php b/public/includes/footer.php new file mode 100644 index 0000000..b00634e --- /dev/null +++ b/public/includes/footer.php @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/includes/functions.php b/public/includes/functions.php new file mode 100644 index 0000000..9ed31ce --- /dev/null +++ b/public/includes/functions.php @@ -0,0 +1,163 @@ + 'Home', 'url' => 'index.html'], ...] + */ +function generateBreadcrumbs($breadcrumbs) { + echo ''; +} + +/** + * Generate CSRF token for form security + * + * @return string CSRF token + */ +function generateCSRFToken() { + if (!isset($_SESSION['csrf_token'])) { + $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); + } + return $_SESSION['csrf_token']; +} diff --git a/public/includes/header.php b/public/includes/header.php new file mode 100644 index 0000000..2f74089 --- /dev/null +++ b/public/includes/header.php @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + <?php echo isset($page_title) ? htmlspecialchars($page_title) : 'HexaHost.de - Zuverlässiges Hosting aus Niederbayern'; ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
\ No newline at end of file diff --git a/scripts/sync-backend-to-public.ps1 b/scripts/sync-backend-to-public.ps1 new file mode 100644 index 0000000..34e071a --- /dev/null +++ b/scripts/sync-backend-to-public.ps1 @@ -0,0 +1,23 @@ +# Kopiert Backend-Includes und -Config nach public/ (für Produktions-Deploy) +$ErrorActionPreference = 'Stop' +$root = Split-Path -Parent $PSScriptRoot + +$includesSrc = Join-Path $root 'backend\includes' +$configSrc = Join-Path $root 'backend\config' +$includesDst = Join-Path $root 'public\includes' +$configDst = Join-Path $root 'public\config' + +if (-not (Test-Path $includesSrc)) { + throw "Backend-Includes nicht gefunden: $includesSrc" +} +if (-not (Test-Path $configSrc)) { + throw "Backend-Config nicht gefunden: $configSrc" +} + +New-Item -ItemType Directory -Force -Path $includesDst | Out-Null +New-Item -ItemType Directory -Force -Path $configDst | Out-Null + +Copy-Item -Path (Join-Path $includesSrc '*') -Destination $includesDst -Recurse -Force +Copy-Item -Path (Join-Path $configSrc '*') -Destination $configDst -Recurse -Force + +Write-Host "OK: backend -> public/includes und public/config synchronisiert."