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."