commit
This commit is contained in:
232
inc/OUTDATED bootstrap.php
Normal file
232
inc/OUTDATED bootstrap.php
Normal file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
// =================================================================
|
||||
// 🚨 KRITISCHE STARTSEQUENZ / BOOTSTRAP (VERSION MIT FUNKTIONEN) 🚨
|
||||
// Alle Helfer sind jetzt reguläre, globale Funktionen, um Scope-Probleme zu vermeiden.
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
// 1. Composer Autoload
|
||||
$composerAutoload = __DIR__ . '/../../vendor/autoload.php';
|
||||
if (is_file($composerAutoload)) {
|
||||
require_once $composerAutoload;
|
||||
}
|
||||
|
||||
// 2. Session Start (Muss VOR dem Senden des Session-Cookies/Headers erfolgen)
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
|
||||
// --- Globale Helferfunktionen (Die in api.php aufgerufen werden) ---
|
||||
|
||||
function respond($data, int $code = 200): void {
|
||||
http_response_code($code);
|
||||
echo is_string($data) ? $data : json_encode($data, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
|
||||
exit;
|
||||
}
|
||||
|
||||
function fail(string $msg, $detail = null, int $code = 400): void {
|
||||
respond(['ok'=>false,'error'=>$msg,'detail'=>$detail], $code);
|
||||
}
|
||||
|
||||
// RESTLICHE HELFER (MÜSSEN KEINE GLOBALS VERWENDEN)
|
||||
function load_config(): array {
|
||||
$paths = [
|
||||
__DIR__ . '/config.php',
|
||||
__DIR__ . '/../config.php',
|
||||
__DIR__ . '/../../config.php',
|
||||
];
|
||||
|
||||
foreach ($paths as $p) {
|
||||
if (is_file($p)) {
|
||||
$conf = @include $p;
|
||||
if (is_array($conf)) return $conf;
|
||||
}
|
||||
}
|
||||
fail('Invalid config.php', 'config.php not found or not returning array', 500);
|
||||
}
|
||||
|
||||
function cors(array $conf): void {
|
||||
$cors = $conf['cors'] ?? '*';
|
||||
if ($cors) {
|
||||
header('Access-Control-Allow-Origin: ' . $cors);
|
||||
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
|
||||
header('Access-Control-Allow-Headers: Content-Type, Authorization');
|
||||
header('Access-Control-Allow-Credentials: true');
|
||||
}
|
||||
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'OPTIONS') respond(['ok'=>true]);
|
||||
}
|
||||
|
||||
function get_input(): array {
|
||||
$data = [];
|
||||
$ct = $_SERVER['CONTENT_TYPE'] ?? '';
|
||||
if (stripos($ct, 'application/json') !== false) {
|
||||
$raw = file_get_contents('php://input');
|
||||
if ($raw !== false && $raw !== '') {
|
||||
$js = json_decode($raw, true);
|
||||
if (is_array($js)) $data = $js;
|
||||
}
|
||||
}
|
||||
foreach ($_POST as $k=>$v) $data[$k]=$v;
|
||||
foreach ($_GET as $k=>$v) if (!array_key_exists($k,$data)) $data[$k]=$v;
|
||||
return $data;
|
||||
}
|
||||
|
||||
function val(array $in, $keys, $default=null) {
|
||||
if (!is_array($keys)) $keys = [$keys];
|
||||
foreach ($keys as $k) if (array_key_exists($k,$in)) return $in[$k];
|
||||
return $default;
|
||||
}
|
||||
|
||||
function first_existing(array $columns, array $candidates): ?string {
|
||||
foreach ($candidates as $c) if (in_array($c, $columns, true)) return $c;
|
||||
return null;
|
||||
}
|
||||
|
||||
function pdo_templates(array $conf): PDO {
|
||||
if (!isset($conf['templates']) || !is_array($conf['templates'])) {
|
||||
fail('Missing templates DB config', null, 500);
|
||||
}
|
||||
$c = $conf['templates'];
|
||||
$host = $c['db_host'] ?? 'localhost';
|
||||
$db = $c['db_name'] ?? ($c['database'] ?? '');
|
||||
$user = $c['db_user'] ?? ($c['username'] ?? '');
|
||||
$pass = $c['db_pass'] ?? ($c['password'] ?? '');
|
||||
$charset = $c['db_charset'] ?? 'utf8mb4';
|
||||
$port = $c['db_port'] ?? 3306;
|
||||
$dsn = "mysql:host=$host;port=$port;dbname=$db;charset=$charset";
|
||||
$opt = [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
];
|
||||
return new PDO($dsn, $user, $pass, $opt);
|
||||
}
|
||||
|
||||
function verify_password(string $input, string $stored, array $authDbConf): bool {
|
||||
if (preg_match('~^\$2[aby]\$~', $stored) || strpos($stored, '$argon2') === 0) return password_verify($input, $stored);
|
||||
$legacy = strtolower($authDbConf['legacy'] ?? '');
|
||||
if ($legacy === 'md5') return hash_equals($stored, md5($input));
|
||||
if ($legacy === 'sha1') return hash_equals($stored, sha1($input));
|
||||
if (password_get_info($stored)['algo'] !== 0) return password_verify($input, $stored);
|
||||
return hash_equals($stored, $input);
|
||||
}
|
||||
|
||||
function table_columns(PDO $pdo, string $table): array {
|
||||
$cols = [];
|
||||
$stmt = $pdo->query("SHOW COLUMNS FROM `$table`");
|
||||
foreach ($stmt->fetchAll() as $r) $cols[] = $r['Field'];
|
||||
return $cols;
|
||||
}
|
||||
|
||||
function primary_key(PDO $pdo, string $table): ?string {
|
||||
$stmt = $pdo->prepare("SHOW KEYS FROM `$table` WHERE Key_name = 'PRIMARY'");
|
||||
$stmt->execute();
|
||||
$row = $stmt->fetch();
|
||||
return $row['Column_name'] ?? null;
|
||||
}
|
||||
|
||||
|
||||
// --- Neue, reguläre Funktionen (ersetzen Closures) ---
|
||||
|
||||
function requireAuth(): array {
|
||||
// Muss auf globale $_SESSION zugreifen
|
||||
if (empty($_SESSION['auth'])) fail('Not authenticated', null, 401);
|
||||
return $_SESSION['auth'];
|
||||
}
|
||||
|
||||
function pullId(array $src) {
|
||||
$aliases = ['id','item_id','template_id','tpl_id','section_id','sec_id','block_id','blk_id','snippet_id','snip_id'];
|
||||
foreach ($aliases as $a) if (isset($src[$a]) && $src[$a] !== '') return $src[$a];
|
||||
return null;
|
||||
}
|
||||
|
||||
function tenantWhere(array $session): array {
|
||||
// Muss auf globale $conf zugreifen, um $tenantCol und $mapSess zu erhalten
|
||||
global $conf;
|
||||
$multi = $conf['multi'] ?? [];
|
||||
$tenantCol = $multi['tenant_col'] ?? null;
|
||||
$mapSess = $multi['map_session_to'] ?? 'id';
|
||||
|
||||
if (!$tenantCol) return ['', []];
|
||||
if (!$session) return [' AND 1=0 ', []];
|
||||
$val = $session[$mapSess] ?? null;
|
||||
if ($val===null || $val==='') return [' AND 1=0 ', []];
|
||||
return [" AND `$tenantCol` = :__tenant", [':__tenant'=>$val]];
|
||||
}
|
||||
|
||||
function tenantAssign(array $session, array $columns): array {
|
||||
// Muss auf globale $conf zugreifen
|
||||
global $conf;
|
||||
$multi = $conf['multi'] ?? [];
|
||||
$tenantCol = $multi['tenant_col'] ?? null;
|
||||
$mapSess = $multi['map_session_to'] ?? 'id';
|
||||
|
||||
if (!$tenantCol || !in_array($tenantCol, $columns, true)) return [];
|
||||
$val = $session[$mapSess] ?? null;
|
||||
return ($val===null || $val==='') ? [] : [$tenantCol => $val];
|
||||
}
|
||||
|
||||
function resolveIdCol(string $kind): array {
|
||||
// Muss auf globale $conf, $pdo, und $tableMap zugreifen
|
||||
global $conf, $pdo, $tableMap;
|
||||
|
||||
$t = $tableMap[$kind];
|
||||
$cfg = $conf['columns'][$kind] ?? [];
|
||||
$cols = table_columns($pdo, $t);
|
||||
$idCol = $cfg['id'] ?? (in_array('id', $cols, true) ? 'id' : primary_key($pdo, $t));
|
||||
if (!$idCol) $idCol = 'id';
|
||||
return [$idCol, $cols];
|
||||
}
|
||||
|
||||
// --- Haupt-Setup-Logik (Setzt die globalen Variablen) ---
|
||||
|
||||
try {
|
||||
// Deklariere alle Variablen, die im Router von api.php benötigt werden, als global
|
||||
global $conf, $pdo, $in, $action, $tableMap;
|
||||
|
||||
// 1. Globale Konfiguration und CORS
|
||||
$conf = load_config();
|
||||
cors($conf);
|
||||
|
||||
// 2. Cookie-Parameter setzen
|
||||
if (!empty($conf['auth']['cookie'])) {
|
||||
$c = $conf['auth']['cookie'];
|
||||
$params = session_get_cookie_params();
|
||||
$params['lifetime'] = $c['lifetime'] ?? $params['lifetime'];
|
||||
$params['path'] = $c['path'] ?? $params['path'];
|
||||
$params['domain'] = $c['domain'] ?? $params['domain'];
|
||||
$params['secure'] = $c['secure'] ?? $params['secure'];
|
||||
$params['httponly'] = $c['httponly'] ?? $params['httponly'];
|
||||
if (isset($c['samesite'])) $params['samesite'] = $c['samesite'];
|
||||
session_set_cookie_params($params);
|
||||
}
|
||||
|
||||
// 3. Input-Daten abrufen
|
||||
$in = get_input();
|
||||
|
||||
// 4. Datenbankverbindung herstellen
|
||||
$pdo = pdo_templates($conf);
|
||||
|
||||
// 5. Action / Resource auflösen
|
||||
$action = val($in, 'action', '');
|
||||
$resource = val($in, 'resource', null);
|
||||
$allowedResources = ['templates','sections','blocks','snippets'];
|
||||
if ($resource && in_array($resource, $allowedResources, true) && strpos((string)$action, '.') === false) {
|
||||
$verb = strtolower((string)$action);
|
||||
if (in_array($verb, ['list','get','create','update','delete'], true)) $action = $resource.'.'.$verb;
|
||||
}
|
||||
|
||||
// 6. Tabellenzuweisungen
|
||||
$tables = $conf['tables'] ?? [];
|
||||
$tableMap = [
|
||||
'templates' => $tables['templates'] ?? 'emailtemplate_templates',
|
||||
'sections' => $tables['sections'] ?? 'emailtemplate_sections',
|
||||
'blocks' => $tables['blocks'] ?? 'emailtemplate_blocks',
|
||||
'snippets' => $tables['snippets'] ?? 'emailtemplate_snippets',
|
||||
];
|
||||
|
||||
} catch (Throwable $e) {
|
||||
// Fehler während der Initialisierung abfangen
|
||||
fail('Initialization error', get_class($e).': '.$e->getMessage(), 500);
|
||||
}
|
||||
Reference in New Issue
Block a user