start
This commit is contained in:
39
config/config.php
Normal file
39
config/config.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
// Basic error reporting (keep strict in dev)
|
||||
ini_set('display_errors', '1');
|
||||
ini_set('display_startup_errors', '1');
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/settings.php';
|
||||
require_once __DIR__ . '/domaindata.php';
|
||||
|
||||
|
||||
// Environment: staging|prod|local (example)
|
||||
if (!defined('APP_ENV')) {
|
||||
define('APP_ENV', 'local');
|
||||
}
|
||||
|
||||
// Asset versioning
|
||||
if (!defined('ASSET_VERSION')) {
|
||||
define('ASSET_VERSION', 'dev-' . date('Ymd-His'));
|
||||
}
|
||||
|
||||
// Primary domain + URL
|
||||
if (!defined('APP_DOMAIN_PRIMARY')) {
|
||||
define('APP_DOMAIN_PRIMARY', APP_DOMAIN_NAME);
|
||||
}
|
||||
if (!defined('APP_URL_PRIMARY')) {
|
||||
define('APP_URL_PRIMARY', 'https://' . APP_DOMAIN_PRIMARY);
|
||||
}
|
||||
|
||||
// API base (example)
|
||||
if (!defined('APP_API_BASE')) {
|
||||
define('APP_API_BASE', 'https://api.' . APP_DOMAIN_PRIMARY);
|
||||
}
|
||||
|
||||
// Feature toggles
|
||||
if (!defined('APP_DB_ENABLED')) {
|
||||
define('APP_DB_ENABLED', false); // set true to enable DB connection
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
<?php
|
||||
|
||||
define('APP_DOMAIN_NAME', 'usbcheck.it');
|
||||
define('APP_PREFIX', 'usbcheck');
|
||||
@@ -1,121 +1,41 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// 0) Umgebung / Domains / Error-Level laden
|
||||
// → Diese Datei DEFINIERT die Konstanten wie
|
||||
// APP_COOKIE_PREFIX, APP_COOKIE_DOMAIN, APP_ENV etc.
|
||||
// -----------------------------------------------------------
|
||||
require_once __DIR__ . "/config.php";
|
||||
// 1) Load config (constants, env, domains)
|
||||
require_once __DIR__ . '/config.php';
|
||||
|
||||
|
||||
// Diese Werte später ins Template schieben:
|
||||
$GLOBALS['app_env'] = APP_ENV;
|
||||
$GLOBALS['app_base_url'] = APP_URL_PRIMARY;
|
||||
$GLOBALS['app_api_base'] = $apiBaseUrl;
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// set cookie / session parameters
|
||||
// -----------------------------------------------------------
|
||||
|
||||
|
||||
if (!defined('CUSTOM_PREFIX')) {
|
||||
define('CUSTOM_PREFIX', APP_PREFIX);
|
||||
}
|
||||
|
||||
if(!defined('APP_COOKIE_PREFIX')) {
|
||||
if(APP_ENV==="staging"){
|
||||
define('APP_COOKIE_PREFIX', APP_PREFIX.'_stg'.'_');
|
||||
} else
|
||||
{
|
||||
define('APP_COOKIE_PREFIX', APP_PREFIX.'_');
|
||||
}
|
||||
}
|
||||
|
||||
if (!defined('APP_COOKIE_DOMAIN')) {
|
||||
// Fallback: aktuelle Domain des Hosts
|
||||
define('APP_COOKIE_DOMAIN', '.'.APP_DOMAIN_PRIMARY);
|
||||
define('APP_PRIMARY_DOMAIN', APP_DOMAIN_PRIMARY);
|
||||
}
|
||||
if (!defined('APP_CLIENT_COOKIE_LIFETIME')) {
|
||||
define('APP_CLIENT_COOKIE_LIFETIME', 365 * 24 * 60 * 60); // 1 Jahr
|
||||
}
|
||||
|
||||
|
||||
// Einheitliche Cookie-Namen (projektübergreifend steuerbar)
|
||||
$sessionCookieName = APP_COOKIE_PREFIX . 'session';
|
||||
$clientCookieName = APP_COOKIE_PREFIX . 'client';
|
||||
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// 1) PHP-Session starten
|
||||
// -----------------------------------------------------------
|
||||
if (php_sapi_name() !== 'cli') {
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
|
||||
session_name($sessionCookieName);
|
||||
|
||||
session_set_cookie_params([
|
||||
'lifetime' => 0,
|
||||
'path' => '/',
|
||||
'domain' => APP_COOKIE_DOMAIN ?: '',
|
||||
'secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'),
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax',
|
||||
]);
|
||||
|
||||
session_start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// 2) Persistente Client-ID (für Tracking über Besuche hinweg)
|
||||
// -----------------------------------------------------------
|
||||
if (php_sapi_name() !== 'cli') {
|
||||
$clientId = $_COOKIE[$clientCookieName] ?? null;
|
||||
|
||||
// Erwartet wird: 64 Hex-Zeichen (32 Bytes)
|
||||
if (
|
||||
!is_string($clientId) ||
|
||||
$clientId === '' ||
|
||||
!preg_match('/^[a-f0-9]{64}$/', $clientId)
|
||||
) {
|
||||
// neue ID erzeugen
|
||||
try {
|
||||
$clientId = bin2hex(random_bytes(32)); // 32 bytes → 64 hex
|
||||
} catch (Throwable $e) {
|
||||
$clientId = bin2hex(openssl_random_pseudo_bytes(32));
|
||||
// 2) Composer Autoloader (falls vorhanden)
|
||||
$composerAutoload = __DIR__ . '/../vendor/autoload.php';
|
||||
if (file_exists($composerAutoload)) {
|
||||
require_once $composerAutoload;
|
||||
} else {
|
||||
// 2b) Fallback: minimaler Autoloader
|
||||
spl_autoload_register(function (string $class): void {
|
||||
$prefix = 'App\\';
|
||||
if (!str_starts_with($class, $prefix)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cookieOpts = [
|
||||
'expires' => time() + APP_CLIENT_COOKIE_LIFETIME,
|
||||
'path' => '/',
|
||||
'secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'),
|
||||
'httponly' => false, // JS darf es lesen, wenn erwünscht
|
||||
'samesite' => 'Lax',
|
||||
];
|
||||
$rel = substr($class, strlen($prefix));
|
||||
$path = __DIR__ . '/../src/' . str_replace('\\', '/', $rel) . '.php';
|
||||
|
||||
if (!empty(APP_COOKIE_DOMAIN)) {
|
||||
$cookieOpts['domain'] = APP_COOKIE_DOMAIN;
|
||||
if (file_exists($path)) {
|
||||
require_once $path;
|
||||
}
|
||||
|
||||
setcookie($clientCookieName, $clientId, $cookieOpts);
|
||||
$_COOKIE[$clientCookieName] = $clientId;
|
||||
}
|
||||
|
||||
// global verfügbar machen (NEUER NAME!)
|
||||
$GLOBALS['cookie_client_id'] = $clientId;
|
||||
});
|
||||
}
|
||||
|
||||
// 3) Global helper functions (tpl(), t(), asset_*())
|
||||
require_once __DIR__ . '/../src/helpers.php';
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// 3) Sprachlogik laden (bleibt sinnvoll zentral)
|
||||
// -----------------------------------------------------------
|
||||
require_once __DIR__ . '/i18n.php';
|
||||
// 4) Initialize App (services)
|
||||
$config = \App\Config::fromPhpConstants(__DIR__ . '/../config');
|
||||
\App\App::init($config);
|
||||
|
||||
// 5) Start session + create client-id cookie
|
||||
$app = \App\App::get();
|
||||
$app->session()->start();
|
||||
$clientId = $app->session()->ensureClientId();
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// 4) Rest des Systems laden (DB, Funktionen, Hilfs-Libs)
|
||||
// -----------------------------------------------------------
|
||||
require_once __DIR__ . "/db.php";
|
||||
require_once __DIR__ . '/../src/functions.php';
|
||||
// Optionally expose a single global for templates if desired
|
||||
$GLOBALS['client_id'] = $clientId;
|
||||
|
||||
397
config/i18n.php
397
config/i18n.php
@@ -1,397 +0,0 @@
|
||||
<?php
|
||||
// config/i18n.php
|
||||
// Zentrale Sprachlogik für das gesamte Projekt
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) {
|
||||
@session_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest die meta-Infos einer Sprachdatei.
|
||||
* Erwartet Struktur:
|
||||
* {
|
||||
* "meta": { "code": "de", "label": "Deutsch", "flag": "🇩🇪", "enabled": true },
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* Gibt NULL zurück, wenn:
|
||||
* - Datei nicht lesbar
|
||||
* - JSON ungültig
|
||||
* - kein meta vorhanden
|
||||
* - meta.enabled existiert und NICHT true ist
|
||||
*/
|
||||
function app_i18n_load_language_meta_from_file(string $file): ?array
|
||||
{
|
||||
$json = @file_get_contents($file);
|
||||
if ($json === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = json_decode($json, true);
|
||||
if (!is_array($data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$meta = $data['meta'] ?? null;
|
||||
if (!is_array($meta)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Nur aktive Sprachen (enabled === true)
|
||||
if (array_key_exists('enabled', $meta) && !$meta['enabled']) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Code aus meta, Fallback: Dateiname
|
||||
$code = '';
|
||||
if (!empty($meta['code'])) {
|
||||
$code = strtolower(substr((string)$meta['code'], 0, 5));
|
||||
} else {
|
||||
$base = basename($file, '.json');
|
||||
$code = strtolower($base);
|
||||
}
|
||||
|
||||
// Auf 2-Buchstaben-Codes normalisieren (de-DE → de)
|
||||
if (strlen($code) > 2) {
|
||||
$code = substr($code, 0, 2);
|
||||
}
|
||||
|
||||
if ($code === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$label = isset($meta['label']) && $meta['label'] !== ''
|
||||
? (string)$meta['label']
|
||||
: strtoupper($code);
|
||||
|
||||
$flag = isset($meta['flag']) ? (string)$meta['flag'] : '';
|
||||
|
||||
return [
|
||||
'code' => $code,
|
||||
'label' => $label,
|
||||
'flag' => $flag,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Alle verfügbaren Sprachen aus /public/assets/i18n/*.json ermitteln.
|
||||
* Verfügbar = JSON mit meta.enabled === true.
|
||||
* EN wird garantiert hinzugefügt (Fallback), falls nicht gefunden.
|
||||
*/
|
||||
function app_i18n_detect_available_languages(): array
|
||||
{
|
||||
$baseDir = realpath(__DIR__ . '/../public/assets/i18n');
|
||||
if ($baseDir === false) {
|
||||
// Wenn gar kein Verzeichnis da ist: minimaler EN-Fallback
|
||||
return [
|
||||
'en' => [
|
||||
'code' => 'en',
|
||||
'label' => 'English',
|
||||
'flag' => '',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
$files = glob($baseDir . '/*.json') ?: [];
|
||||
$langs = [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
$meta = app_i18n_load_language_meta_from_file($file);
|
||||
if ($meta === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$code = $meta['code'];
|
||||
|
||||
// Erste gültige Definition pro Code gewinnt
|
||||
if (!isset($langs[$code])) {
|
||||
$langs[$code] = $meta;
|
||||
}
|
||||
}
|
||||
|
||||
// EN muss immer vorhanden sein (laut deiner Vorgabe)
|
||||
if (!isset($langs['en'])) {
|
||||
// Versuch: gibt es eine en.json, auch wenn enabled=false?
|
||||
foreach ($files as $file) {
|
||||
$base = strtolower(basename($file, '.json'));
|
||||
if ($base === 'en') {
|
||||
$json = @file_get_contents($file);
|
||||
$data = json_decode($json, true);
|
||||
$meta = is_array($data['meta'] ?? null) ? $data['meta'] : [];
|
||||
|
||||
$label = isset($meta['label']) && $meta['label'] !== ''
|
||||
? (string)$meta['label']
|
||||
: 'English';
|
||||
$flag = isset($meta['flag']) ? (string)$meta['flag'] : '';
|
||||
|
||||
$langs['en'] = [
|
||||
'code' => 'en',
|
||||
'label' => $label,
|
||||
'flag' => $flag,
|
||||
];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wenn immer noch kein EN → minimaler Stub
|
||||
if (!isset($langs['en'])) {
|
||||
$langs['en'] = [
|
||||
'code' => 'en',
|
||||
'label' => 'English',
|
||||
'flag' => '',
|
||||
];
|
||||
}
|
||||
|
||||
ksort($langs);
|
||||
|
||||
return $langs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Browsersprache aus HTTP_ACCEPT_LANGUAGE extrahieren (2-Buchstaben),
|
||||
* aber nur, wenn sie in $available existiert.
|
||||
*/
|
||||
function app_i18n_detect_browser_lang(array $available): ?string
|
||||
{
|
||||
$header = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '';
|
||||
if ($header === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parts = explode(',', $header);
|
||||
foreach ($parts as $part) {
|
||||
$part = trim($part);
|
||||
if ($part === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$code = strtolower(substr($part, 0, 2)); // "de-DE" → "de"
|
||||
if (isset($available[$code])) {
|
||||
return $code;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Aktuelle Sprache bestimmen:
|
||||
* 1) ?lang=xx (wenn in $available)
|
||||
* 2) Browsersprache (wenn in $available)
|
||||
* 3) Fallback "en"
|
||||
*/
|
||||
function app_i18n_resolve_current_lang(array $available): string
|
||||
{
|
||||
// 1) URL-Parameter ?lang=xx
|
||||
if (!empty($_GET['lang'])) {
|
||||
$param = strtolower(substr($_GET['lang'], 0, 2));
|
||||
if (isset($available[$param])) {
|
||||
return $param;
|
||||
}
|
||||
}
|
||||
|
||||
// 2) Browsersprache
|
||||
$browser = app_i18n_detect_browser_lang($available);
|
||||
if ($browser !== null) {
|
||||
return $browser;
|
||||
}
|
||||
|
||||
// 3) Standard EN
|
||||
if (isset($available['en'])) {
|
||||
return 'en';
|
||||
}
|
||||
|
||||
// Sicherheitsfallback: erste verfügbare Sprache
|
||||
$keys = array_keys($available);
|
||||
return $keys[0] ?? 'en';
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Bootstrap ausführen
|
||||
// -----------------------------------------------------
|
||||
|
||||
$availableLangs = app_i18n_detect_available_languages();
|
||||
$currentLang = app_i18n_resolve_current_lang($availableLangs);
|
||||
|
||||
// Global bereitstellen
|
||||
$GLOBALS['availableLangs'] = $availableLangs;
|
||||
$GLOBALS['lang'] = $currentLang;
|
||||
|
||||
// Optional in Session merken (muss nicht, schadet aber auch nicht)
|
||||
$_SESSION['lang'] = $currentLang;
|
||||
|
||||
/**
|
||||
* Frontend-Config für JS (usbConfig.i18n)
|
||||
* → benutzt direkt die Meta-Daten aus den JSONs (code, label, flag)
|
||||
*/
|
||||
function app_i18n_get_frontend_config(): array
|
||||
{
|
||||
return [
|
||||
'current' => $GLOBALS['lang'] ?? 'en',
|
||||
'available' => $GLOBALS['availableLangs'] ?? [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Komplette JSON-Struktur für eine Sprache laden.
|
||||
* Nutzt einfachen Request-Cache, damit pro Sprache nur einmal von Platte gelesen wird.
|
||||
*/
|
||||
function app_i18n_load_lang_json(string $lang): array
|
||||
{
|
||||
static $cache = [];
|
||||
|
||||
$lang = strtolower(substr($lang, 0, 5));
|
||||
|
||||
if (isset($cache[$lang])) {
|
||||
return $cache[$lang];
|
||||
}
|
||||
|
||||
$baseDir = realpath(__DIR__ . '/../public/assets/i18n');
|
||||
if ($baseDir === false) {
|
||||
$cache[$lang] = [];
|
||||
return $cache[$lang];
|
||||
}
|
||||
|
||||
$path = $baseDir . '/' . $lang . '.json';
|
||||
if (!is_file($path)) {
|
||||
// Fallback: en.json, falls vorhanden
|
||||
$fallback = $baseDir . '/en.json';
|
||||
if (is_file($fallback)) {
|
||||
$json = @file_get_contents($fallback);
|
||||
$data = json_decode($json, true);
|
||||
$cache[$lang] = is_array($data) ? $data : [];
|
||||
return $cache[$lang];
|
||||
}
|
||||
|
||||
$cache[$lang] = [];
|
||||
return $cache[$lang];
|
||||
}
|
||||
|
||||
$json = @file_get_contents($path);
|
||||
$data = json_decode($json, true);
|
||||
$cache[$lang] = is_array($data) ? $data : [];
|
||||
|
||||
return $cache[$lang];
|
||||
}
|
||||
|
||||
/**
|
||||
* Aus einem Label einen stabilen i18n-Key für Nav-Anker bauen.
|
||||
* Beispiel: "So funktioniert USBCheck!" -> "nav_so_funktioniert_usbcheck"
|
||||
*/
|
||||
function app_i18n_make_anchor_key(string $label): string
|
||||
{
|
||||
// HTML-Entities entfernen (z. B. &)
|
||||
$decoded = html_entity_decode($label, ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
||||
|
||||
// Kleinbuchstaben
|
||||
$decoded = mb_strtolower($decoded, 'UTF-8');
|
||||
|
||||
// Alles, was kein a-z oder 0-9 ist, durch Unterstrich ersetzen
|
||||
$key = preg_replace('/[^a-z0-9]+/u', '_', $decoded);
|
||||
|
||||
// Mehrfache Unterstriche trimmen
|
||||
$key = trim($key, '_');
|
||||
|
||||
if ($key === '') {
|
||||
$key = 'item';
|
||||
}
|
||||
|
||||
// Prefix, damit klar ist, dass es Navigationskeys sind
|
||||
return 'nav_' . $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nav-Anker für eine Seite aus der Sprachdatei holen.
|
||||
*
|
||||
* Haupt-Variante im JSON:
|
||||
*
|
||||
* "pages": {
|
||||
* "landing": {
|
||||
* "anchors": {
|
||||
* "how": "So funktioniert USBCheck",
|
||||
* "problem": "Warum gefälschte USB-Sticks gefährlich sind",
|
||||
* "features": "Funktionen",
|
||||
* "security": "Sicherheit",
|
||||
* "faq": "FAQ"
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* Optional explizit:
|
||||
* "anchors": {
|
||||
* "how": { "label": "So funktioniert USBCheck", "i18n": "nav_how" },
|
||||
* "faq": { "i18n": "nav_faq" }
|
||||
* }
|
||||
*
|
||||
* Rückgabe-Format:
|
||||
* [
|
||||
* [ 'href' => '#how', 'label' => 'So funktioniert USBCheck', 'i18n' => 'nav_so_funktioniert_usbcheck' ],
|
||||
* [ 'href' => '#faq', 'label' => '', 'i18n' => 'nav_faq' ],
|
||||
* ]
|
||||
*/
|
||||
function app_get_nav_anchors(string $pageKey): array
|
||||
{
|
||||
$lang = $GLOBALS['lang'] ?? 'en';
|
||||
$data = app_i18n_load_lang_json($lang);
|
||||
|
||||
$cfg = $data['pages'][$pageKey]['anchors'] ?? null;
|
||||
if (!is_array($cfg)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$anchors = [];
|
||||
|
||||
foreach ($cfg as $id => $value) {
|
||||
$id = trim((string)$id);
|
||||
if ($id === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$href = '#' . $id;
|
||||
$label = '';
|
||||
$i18n = '';
|
||||
|
||||
if (is_string($value)) {
|
||||
// String IMMER als Label übernehmen
|
||||
$labelTrim = trim($value);
|
||||
if ($labelTrim === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$label = $labelTrim;
|
||||
// i18n-Key automatisch aus dem Label ableiten
|
||||
$i18n = app_i18n_make_anchor_key($labelTrim);
|
||||
|
||||
} elseif (is_array($value)) {
|
||||
// Explizite Variante:
|
||||
// "how": { "label": "...", "i18n": "nav_how" }
|
||||
if (!empty($value['label'])) {
|
||||
$label = trim((string)$value['label']);
|
||||
}
|
||||
if (!empty($value['i18n'])) {
|
||||
$i18n = trim((string)$value['i18n']);
|
||||
}
|
||||
|
||||
if ($label === '' && $i18n === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Wenn Label gesetzt, aber kein i18n: automatisch generieren
|
||||
if ($label !== '' && $i18n === '') {
|
||||
$i18n = app_i18n_make_anchor_key($label);
|
||||
}
|
||||
} else {
|
||||
// Weder String noch Array → ignorieren
|
||||
continue;
|
||||
}
|
||||
|
||||
$anchors[] = [
|
||||
'href' => $href,
|
||||
'label' => $label,
|
||||
'i18n' => $i18n,
|
||||
];
|
||||
}
|
||||
|
||||
return $anchors;
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . "/domaindata.php";
|
||||
|
||||
// Umgebung (optional, aber hilfreich für Debugging / Logik)
|
||||
define('APP_ENV', 'prod'); // oder 'prod', 'local', ...
|
||||
if (!defined('ASSET_VERSION')) {
|
||||
define('ASSET_VERSION', '2024-11-22'); // oder deine aktuelle Version
|
||||
}
|
||||
// Domain-Konfiguration (kann pro Umgebung angepasst werden)
|
||||
if (!defined('APP_DOMAIN_PRIMARY')) {
|
||||
define('APP_DOMAIN_PRIMARY', APP_DOMAIN_NAME);
|
||||
}
|
||||
if (!defined('APP_URL_PRIMARY')) {
|
||||
define('APP_URL_PRIMARY', 'https://' . APP_DOMAIN_PRIMARY);
|
||||
}
|
||||
if (!defined('APP_DOMAIN_FAKECHECK')) {
|
||||
define('APP_DOMAIN_FAKECHECK', 'ismyusbfake.com');
|
||||
}
|
||||
if (!defined('APP_URL_FAKECHECK')) {
|
||||
define('APP_URL_FAKECHECK', 'https://' . APP_DOMAIN_FAKECHECK);
|
||||
}
|
||||
|
||||
// Matomo Einstellungen
|
||||
define('MATOMO_URL', 'https://matomo.my-statistics.info/');
|
||||
define('MATOMO_ENABLED', true);
|
||||
define('MATOMO_SITE_ID', 7);
|
||||
$env = 'prod';
|
||||
$baseUrl = 'https://'.APP_DOMAIN_NAME;
|
||||
$apiBaseUrl = 'https://api.'.APP_DOMAIN_NAME;
|
||||
|
||||
@@ -1,28 +1,93 @@
|
||||
<?php
|
||||
// config/db.php
|
||||
declare(strict_types=1);
|
||||
|
||||
$DB_HOST = 'localhost';
|
||||
$DB_NAME = 'd0444c21';
|
||||
$DB_USER = 'd0444c21';
|
||||
$DB_PASS = 'Rnßü7ROxFTxmOazLNhz/'; // anpassen
|
||||
/**
|
||||
* config/db.php
|
||||
*
|
||||
* - Choose ONE driver below (others stay commented).
|
||||
* - Each driver has its own config section.
|
||||
* - The file returns ONE normalized array used by Database::createPdo().
|
||||
*/
|
||||
|
||||
$options = [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
// ------------------------------------------------------------
|
||||
// 1) Driver selection (choose one)
|
||||
// ------------------------------------------------------------
|
||||
$driver = 'pgsql';
|
||||
// $driver = 'mysql';
|
||||
// $driver = 'sqlite';
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 2) Driver-specific configuration sections
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// ---- PostgreSQL (PDO driver: pgsql) -------------------------
|
||||
$pgsql = [
|
||||
'driver' => 'pgsql',
|
||||
'host' => 'localhost',
|
||||
'port' => 5432,
|
||||
'dbname' => 'mydb',
|
||||
|
||||
// optional: schema/search_path (commonly "public")
|
||||
'schema' => 'public',
|
||||
|
||||
'user' => 'myuser',
|
||||
'password' => 'secret',
|
||||
|
||||
'options' => [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
],
|
||||
];
|
||||
|
||||
try {
|
||||
$pdo = new PDO(
|
||||
"mysql:host={$DB_HOST};dbname={$DB_NAME};charset=utf8mb4",
|
||||
$DB_USER,
|
||||
$DB_PASS,
|
||||
$options
|
||||
);
|
||||
} catch (PDOException $e) {
|
||||
// In Produktion Logging, keine Details ausgeben
|
||||
http_response_code(500);
|
||||
echo 'Database connection error.';
|
||||
exit;
|
||||
// ---- MySQL / MariaDB (PDO driver: mysql) -------------------
|
||||
$mysql = [
|
||||
'driver' => 'mysql',
|
||||
'host' => 'localhost',
|
||||
'port' => 3306,
|
||||
'dbname' => 'mydb',
|
||||
'charset' => 'utf8mb4',
|
||||
|
||||
// Alternative to host/port:
|
||||
// 'unix_socket' => '/var/run/mysqld/mysqld.sock',
|
||||
|
||||
'user' => 'myuser',
|
||||
'password' => 'secret',
|
||||
|
||||
'options' => [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
],
|
||||
];
|
||||
|
||||
// ---- SQLite (PDO driver: sqlite) ---------------------------
|
||||
$sqlite = [
|
||||
'driver' => 'sqlite',
|
||||
|
||||
// Use an absolute path in production, e.g. /var/app/data/app.sqlite
|
||||
// For demo/dev you can use a relative path.
|
||||
'path' => __DIR__ . '/../var/app.sqlite',
|
||||
|
||||
// SQLite ignores host/port/user/pass
|
||||
'options' => [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
],
|
||||
];
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 3) Select and return config
|
||||
// ------------------------------------------------------------
|
||||
switch ($driver) {
|
||||
case 'pgsql':
|
||||
return $pgsql;
|
||||
|
||||
case 'mysql':
|
||||
return $mysql;
|
||||
|
||||
case 'sqlite':
|
||||
return $sqlite;
|
||||
|
||||
default:
|
||||
throw new RuntimeException('Unsupported DB driver in config/db.php: ' . $driver);
|
||||
}
|
||||
|
||||
12
config/prod/domaindata.php
Normal file
12
config/prod/domaindata.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
// Example: a single "brand" domain name.
|
||||
// In real deployments you might derive this from ENV or hostnames.
|
||||
if (!defined('APP_DOMAIN_NAME')) {
|
||||
define('APP_DOMAIN_NAME', 'papa-kind-treff.info');
|
||||
}
|
||||
|
||||
if (!defined('APP_PREFIX')) {
|
||||
define('APP_PREFIX', 'miniapp');
|
||||
}
|
||||
8
config/prod/settings.php
Normal file
8
config/prod/settings.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
define('APP_ENV', 'local');
|
||||
define('ASSET_VERSION', 'dev-' . date('Ymd-His'));
|
||||
define('APP_DOMAIN_PRIMARY', APP_DOMAIN_NAME);
|
||||
define('APP_URL_PRIMARY', 'https://' . APP_DOMAIN_PRIMARY);
|
||||
define('APP_API_BASE', 'https://api.' . APP_DOMAIN_PRIMARY);
|
||||
define('APP_DB_ENABLED', false); // set true to enable DB connection
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . "/domaindata.php";
|
||||
|
||||
// Umgebung (optional, aber hilfreich für Debugging / Logik)
|
||||
define('APP_ENV', 'staging'); // oder 'prod', 'local', ...
|
||||
|
||||
|
||||
if (!defined('ASSET_VERSION')) {
|
||||
define('ASSET_VERSION', time()); // oder deine aktuelle Version
|
||||
}
|
||||
|
||||
// Domain-Konfiguration (kann pro Umgebung angepasst werden)
|
||||
if (!defined('APP_DOMAIN_PRIMARY')) {
|
||||
define('APP_DOMAIN_PRIMARY', 'staging.'.APP_DOMAIN_NAME);
|
||||
}
|
||||
if (!defined('APP_URL_PRIMARY')) {
|
||||
define('APP_URL_PRIMARY', 'https://' . APP_DOMAIN_PRIMARY);
|
||||
}
|
||||
if (!defined('APP_DOMAIN_FAKECHECK')) {
|
||||
define('APP_DOMAIN_FAKECHECK', 'staging.ismyusbfake.com');
|
||||
}
|
||||
if (!defined('APP_URL_FAKECHECK')) {
|
||||
define('APP_URL_FAKECHECK', 'https://' . APP_DOMAIN_FAKECHECK);
|
||||
}
|
||||
|
||||
// Matomo Einstellungen
|
||||
define('MATOMO_URL', 'https://matomo.my-statistics.info/');
|
||||
define('MATOMO_ENABLED', false);
|
||||
define('MATOMO_SITE_ID', 8);
|
||||
$baseUrl = 'https://'.APP_DOMAIN_PRIMARY;
|
||||
$apiBaseUrl = 'https://api.'.APP_DOMAIN_PRIMARY;
|
||||
|
||||
@@ -1,28 +1,93 @@
|
||||
<?php
|
||||
// config/db.php
|
||||
declare(strict_types=1);
|
||||
|
||||
$DB_HOST = 'localhost';
|
||||
$DB_NAME = 'd0444c25';
|
||||
$DB_USER = 'd0444c25';
|
||||
$DB_PASS = '/7ü9+§ÄfkiQvGPr§2Op7'; // anpassen
|
||||
/**
|
||||
* config/db.php
|
||||
*
|
||||
* - Choose ONE driver below (others stay commented).
|
||||
* - Each driver has its own config section.
|
||||
* - The file returns ONE normalized array used by Database::createPdo().
|
||||
*/
|
||||
|
||||
$options = [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
// ------------------------------------------------------------
|
||||
// 1) Driver selection (choose one)
|
||||
// ------------------------------------------------------------
|
||||
$driver = 'pgsql';
|
||||
// $driver = 'mysql';
|
||||
// $driver = 'sqlite';
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 2) Driver-specific configuration sections
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// ---- PostgreSQL (PDO driver: pgsql) -------------------------
|
||||
$pgsql = [
|
||||
'driver' => 'pgsql',
|
||||
'host' => 'localhost',
|
||||
'port' => 5432,
|
||||
'dbname' => 'mydb',
|
||||
|
||||
// optional: schema/search_path (commonly "public")
|
||||
'schema' => 'public',
|
||||
|
||||
'user' => 'myuser',
|
||||
'password' => 'secret',
|
||||
|
||||
'options' => [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
],
|
||||
];
|
||||
|
||||
try {
|
||||
$pdo = new PDO(
|
||||
"mysql:host={$DB_HOST};dbname={$DB_NAME};charset=utf8mb4",
|
||||
$DB_USER,
|
||||
$DB_PASS,
|
||||
$options
|
||||
);
|
||||
} catch (PDOException $e) {
|
||||
// In Produktion Logging, keine Details ausgeben
|
||||
http_response_code(500);
|
||||
echo 'Database connection error.';
|
||||
exit;
|
||||
// ---- MySQL / MariaDB (PDO driver: mysql) -------------------
|
||||
$mysql = [
|
||||
'driver' => 'mysql',
|
||||
'host' => 'localhost',
|
||||
'port' => 3306,
|
||||
'dbname' => 'mydb',
|
||||
'charset' => 'utf8mb4',
|
||||
|
||||
// Alternative to host/port:
|
||||
// 'unix_socket' => '/var/run/mysqld/mysqld.sock',
|
||||
|
||||
'user' => 'myuser',
|
||||
'password' => 'secret',
|
||||
|
||||
'options' => [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
],
|
||||
];
|
||||
|
||||
// ---- SQLite (PDO driver: sqlite) ---------------------------
|
||||
$sqlite = [
|
||||
'driver' => 'sqlite',
|
||||
|
||||
// Use an absolute path in production, e.g. /var/app/data/app.sqlite
|
||||
// For demo/dev you can use a relative path.
|
||||
'path' => __DIR__ . '/../var/app.sqlite',
|
||||
|
||||
// SQLite ignores host/port/user/pass
|
||||
'options' => [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
],
|
||||
];
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 3) Select and return config
|
||||
// ------------------------------------------------------------
|
||||
switch ($driver) {
|
||||
case 'pgsql':
|
||||
return $pgsql;
|
||||
|
||||
case 'mysql':
|
||||
return $mysql;
|
||||
|
||||
case 'sqlite':
|
||||
return $sqlite;
|
||||
|
||||
default:
|
||||
throw new RuntimeException('Unsupported DB driver in config/db.php: ' . $driver);
|
||||
}
|
||||
|
||||
12
config/staging/domaindata.php
Normal file
12
config/staging/domaindata.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
// Example: a single "brand" domain name.
|
||||
// In real deployments you might derive this from ENV or hostnames.
|
||||
if (!defined('APP_DOMAIN_NAME')) {
|
||||
define('APP_DOMAIN_NAME', 'staging.papa-kind-treff.info');
|
||||
}
|
||||
|
||||
if (!defined('APP_PREFIX')) {
|
||||
define('APP_PREFIX', 'miniapp');
|
||||
}
|
||||
8
config/staging/settings.php
Normal file
8
config/staging/settings.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
define('APP_ENV', 'local');
|
||||
define('ASSET_VERSION', 'dev-' . date('Ymd-His'));
|
||||
define('APP_DOMAIN_PRIMARY', APP_DOMAIN_NAME);
|
||||
define('APP_URL_PRIMARY', 'https://' . APP_DOMAIN_PRIMARY);
|
||||
define('APP_API_BASE', 'https://api.' . APP_DOMAIN_PRIMARY);
|
||||
define('APP_DB_ENABLED', false); // set true to enable DB connection
|
||||
|
||||
Reference in New Issue
Block a user