<?php
declare(strict_types=1);
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
$texts=[
'de'=>['title'=>'TripTale installieren','intro'=>'Diese Seite richtet eine neue, leere TripTale-Installation ein.','database'=>'Datenbank','host'=>'Host','database_name'=>'Datenbankname','username'=>'Benutzername','password'=>'Passwort','prefix'=>'Tabellenpräfix','app_admin'=>'Anwendung und Hauptadministrator','url'=>'Adresse der Anwendung','first'=>'Vorname','last'=>'Nachname','email'=>'E-Mail','admin_password'=>'Passwort für Hauptadmin','start'=>'Installation starten','done'=>'Installation abgeschlossen.','delete'=>'Du kannst dich jetzt anmelden. Lösche anschließend unbedingt setup.php, installer.php und installer-ui.php vom Server.','login'=>'Zur Anmeldung','error_data'=>'Bitte Datenbankangaben und die vollständige Adresse der Anwendung eintragen.','error_admin'=>'Bitte vollständige Hauptadmin-Daten angeben. Das Passwort benötigt mindestens 12 Zeichen.','error_prefix'=>'Das Tabellenpräfix darf nur Buchstaben, Zahlen und Unterstriche enthalten und muss mit einem Buchstaben beginnen.','exists'=>'Für dieses Präfix existieren bereits Tabellen. Bitte ein anderes Präfix verwenden.','missing'=>'Installationsdatei fehlt: '],
'en'=>['title'=>'Install TripTale','intro'=>'This page creates a new, empty TripTale installation.','database'=>'Database','host'=>'Host','database_name'=>'Database name','username'=>'Username','password'=>'Password','prefix'=>'Table prefix','app_admin'=>'Application and main administrator','url'=>'Application address','first'=>'First name','last'=>'Last name','email'=>'Email','admin_password'=>'Main administrator password','start'=>'Start installation','done'=>'Installation complete.','delete'=>'You can now sign in. Then delete setup.php, installer.php and installer-ui.php from the server.','login'=>'Go to sign in','error_data'=>'Please enter the database details and the complete application address.','error_admin'=>'Please enter the complete main administrator details. The password must have at least 12 characters.','error_prefix'=>'The table prefix may contain only letters, numbers and underscores and must begin with a letter.','exists'=>'Tables already exist for this prefix. Please use a different prefix.','missing'=>'Installation file is missing: '],
'fr'=>['title'=>'Installer TripTale','intro'=>'Cette page crée une nouvelle installation TripTale vide.','database'=>'Base de données','host'=>'Hôte','database_name'=>'Nom de la base de données','username'=>'Nom d’utilisateur','password'=>'Mot de passe','prefix'=>'Préfixe des tables','app_admin'=>'Application et administrateur principal','url'=>'Adresse de l’application','first'=>'Prénom','last'=>'Nom','email'=>'E-mail','admin_password'=>'Mot de passe de l’administrateur principal','start'=>'Lancer l’installation','done'=>'Installation terminée.','delete'=>'Vous pouvez maintenant vous connecter. Supprimez ensuite setup.php, installer.php et installer-ui.php du serveur.','login'=>'Se connecter','error_data'=>'Veuillez saisir les données de la base et l’adresse complète de l’application.','error_admin'=>'Veuillez saisir les données complètes de l’administrateur principal. Le mot de passe doit contenir au moins 12 caractères.','error_prefix'=>'Le préfixe ne peut contenir que des lettres, chiffres et tirets bas et doit commencer par une lettre.','exists'=>'Des tables existent déjà pour ce préfixe. Utilisez un autre préfixe.','missing'=>'Fichier d’installation manquant : '],
'es'=>['title'=>'Instalar TripTale','intro'=>'Esta página crea una instalación nueva y vacía de TripTale.','database'=>'Base de datos','host'=>'Servidor','database_name'=>'Nombre de la base de datos','username'=>'Usuario','password'=>'Contraseña','prefix'=>'Prefijo de tablas','app_admin'=>'Aplicación y administrador principal','url'=>'Dirección de la aplicación','first'=>'Nombre','last'=>'Apellidos','email'=>'Correo electrónico','admin_password'=>'Contraseña del administrador principal','start'=>'Iniciar instalación','done'=>'Instalación completada.','delete'=>'Ahora puedes iniciar sesión. Después elimina setup.php, installer.php e installer-ui.php del servidor.','login'=>'Ir al inicio de sesión','error_data'=>'Introduce los datos de la base de datos y la dirección completa de la aplicación.','error_admin'=>'Introduce los datos completos del administrador principal. La contraseña debe tener al menos 12 caracteres.','error_prefix'=>'El prefijo solo puede contener letras, números y guiones bajos, y debe empezar por una letra.','exists'=>'Ya existen tablas con este prefijo. Usa otro prefijo.','missing'=>'Falta el archivo de instalación: '],
'it'=>['title'=>'Installa TripTale','intro'=>'Questa pagina crea una nuova installazione vuota di TripTale.','database'=>'Database','host'=>'Host','database_name'=>'Nome del database','username'=>'Nome utente','password'=>'Password','prefix'=>'Prefisso delle tabelle','app_admin'=>'Applicazione e amministratore principale','url'=>'Indirizzo dell’applicazione','first'=>'Nome','last'=>'Cognome','email'=>'E-mail','admin_password'=>'Password dell’amministratore principale','start'=>'Avvia installazione','done'=>'Installazione completata.','delete'=>'Ora puoi accedere. Elimina poi setup.php, installer.php e installer-ui.php dal server.','login'=>'Vai all’accesso','error_data'=>'Inserisci i dati del database e l’indirizzo completo dell’applicazione.','error_admin'=>'Inserisci i dati completi dell’amministratore principale. La password deve contenere almeno 12 caratteri.','error_prefix'=>'Il prefisso può contenere solo lettere, numeri e trattini bassi e deve iniziare con una lettera.','exists'=>'Esistono già tabelle con questo prefisso. Usa un prefisso diverso.','missing'=>'File di installazione mancante: '],
];
$installLanguage=(string)($_REQUEST['install_language']??'de');if(!isset($texts[$installLanguage])){$installLanguage='de';}$t=$texts[$installLanguage];$mailHints=['de'=>'Wichtig: Prüfe und speichere vor dem ersten Versand die Absenderadresse unter Einstellungen → Mail-Einstellungen.','en'=>'Important: Before sending the first email, review and save the sender address under Settings → Mail settings.','fr'=>'Important : avant le premier envoi, vérifiez et enregistrez l’adresse d’expédition dans Paramètres → Paramètres e-mail.','es'=>'Importante: antes del primer envío, revisa y guarda la dirección del remitente en Ajustes → Configuración de correo.','it'=>'Importante: prima del primo invio, controlla e salva l’indirizzo del mittente in Impostazioni → Impostazioni e-mail.'];$t['delete'].=' '.$mailHints[$installLanguage];$manifest=require __DIR__.'/database/install-manifest.php';$error=null;$done=false;
function ui_prefix(string $v,string $error):string{$v=trim($v);if(!preg_match('/^[A-Za-z][A-Za-z0-9_]{0,45}$/',$v)){throw new RuntimeException($error);}return str_ends_with($v,'_')?$v:$v.'_';}
function ui_sql(PDO $pdo,string $sql,string $prefix):void{$sql=str_replace(['{{PREFIX}}','travel_1_'],$prefix,$sql);$sql=preg_replace_callback('/\bCONSTRAINT\s+(`?)(fk_[A-Za-z0-9_]+)\1/i',static fn(array $m):string=>'CONSTRAINT '.$prefix.$m[2],$sql)??$sql;foreach(preg_split('/;\s*(?=(?:--[^\n]*\n|\/\*.*?\*\/\s*)*(?:CREATE|ALTER|INSERT|UPDATE|DELETE|SET)\b)/is',$sql)?:[] as $s){if(trim($s)!==''){$pdo->exec($s);}}}
if($_SERVER['REQUEST_METHOD']==='POST'){$v=['host'=>trim((string)($_POST['host']??'')),'database'=>trim((string)($_POST['database']??'')),'user'=>trim((string)($_POST['user']??'')),'password'=>(string)($_POST['password']??''),'base_url'=>rtrim(trim((string)($_POST['base_url']??'')),'/'),'prefix'=>'','version'=>$manifest['version']];$first=trim((string)($_POST['first_name']??''));$last=trim((string)($_POST['last_name']??''));$email=trim((string)($_POST['email']??''));$adminPassword=(string)($_POST['admin_password']??'');$appLanguage=(string)($_POST['app_language']??$installLanguage);if(!isset($texts[$appLanguage])){$appLanguage='de';}try{$v['prefix']=ui_prefix((string)($_POST['prefix']??'triptale_'),$t['error_prefix']);if($v['host']===''||$v['database']===''||$v['user']===''||!filter_var($v['base_url'],FILTER_VALIDATE_URL)){throw new RuntimeException($t['error_data']);}if($first===''||$last===''||!filter_var($email,FILTER_VALIDATE_EMAIL)||strlen($adminPassword)<12){throw new RuntimeException($t['error_admin']);}$pdo=new PDO('mysql:host='.$v['host'].';dbname='.$v['database'].';charset=utf8mb4',$v['user'],$v['password'],[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION]);$q=$pdo->prepare('SHOW TABLES LIKE :name');$q->execute([':name'=>$v['prefix'].'users']);if($q->fetchColumn()){throw new RuntimeException($t['exists']);}$pdo->beginTransaction();foreach(array_merge([$manifest['schema']],$manifest['migrations']) as $file){$path=__DIR__.'/database/'.$file;if(!is_file($path)){throw new RuntimeException($t['missing'].$file);}ui_sql($pdo,(string)file_get_contents($path),$v['prefix']);}$pdo->exec('CREATE TABLE '.$v['prefix'].'app_meta (meta_key VARCHAR(100) NOT NULL,meta_value VARCHAR(255) NULL,PRIMARY KEY(meta_key)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci');$q=$pdo->prepare('INSERT INTO '.$v['prefix'].'users (first_name,last_name,email,password_hash,role,status,preferred_language) VALUES (:first,:last,:email,:hash,\'main_admin\',\'active\',:language)');$q->execute([':first'=>$first,':last'=>$last,':email'=>$email,':hash'=>password_hash($adminPassword,PASSWORD_DEFAULT),':language'=>$appLanguage]);$q=$pdo->prepare('INSERT INTO '.$v['prefix'].'app_meta (meta_key,meta_value) VALUES (\'version\',:version)');$q->execute([':version'=>$manifest['version']]);if($pdo->inTransaction()){$pdo->commit();}if(!is_dir(__DIR__.'/config')&&!mkdir(__DIR__.'/config',0755,true)){throw new RuntimeException('config');}$config=['app'=>['name'=>'TripTale','base_url'=>$v['base_url'],'language'=>$appLanguage,'version'=>$v['version']],'database'=>['host'=>$v['host'],'name'=>$v['database'],'user'=>$v['user'],'password'=>$v['password'],'charset'=>'utf8mb4','prefix'=>$v['prefix']]];if(file_put_contents(__DIR__.'/config/config.php',"<?php\ndeclare(strict_types=1);\n\nreturn ".var_export($config,true).";\n",LOCK_EX)===false){throw new RuntimeException('config');}if(!is_dir(__DIR__.'/uploads')){mkdir(__DIR__.'/uploads',0755,true);}$done=true;}catch(Throwable $e){if(isset($pdo)&&$pdo instanceof PDO&&$pdo->inTransaction()){$pdo->rollBack();}$error=$e->getMessage();}}
?><!doctype html><html lang="<?=htmlspecialchars($installLanguage,ENT_QUOTES,'UTF-8')?>"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title><?=htmlspecialchars($t['title'],ENT_QUOTES,'UTF-8')?></title><style>body{font-family:system-ui,sans-serif;background:#f4f6f8;margin:0;padding:32px;color:#17202a}main{max-width:650px;margin:auto;background:#fff;padding:28px;border-radius:14px;box-shadow:0 4px 18px #0001}label{display:block;margin-top:14px;font-weight:650}input,select{box-sizing:border-box;width:100%;margin-top:6px;padding:11px;border:1px solid #b9c1c8;border-radius:7px;font:inherit}button{margin-top:22px;padding:12px 16px;border:0;border-radius:7px;background:#126e82;color:#fff;font-weight:700;font:inherit}.error{background:#ffe6e3;padding:12px;border-radius:7px}.done{background:#e6f5e9;padding:16px;border-radius:7px;color:#1d6831}h2{margin-top:28px;font-size:1.12rem}@media(max-width:600px){body{padding:12px}main{padding:18px}}</style><main><form method="get"><label>Language / Sprache<select name="install_language" onchange="this.form.submit()"><?php foreach(['de'=>'Deutsch','en'=>'English','fr'=>'Français','es'=>'Español','it'=>'Italiano'] as $code=>$name):?><option value="<?=$code?>"<?=$code===$installLanguage?' selected':''?>><?=$name?></option><?php endforeach;?></select></label></form><h1><?=htmlspecialchars($t['title'],ENT_QUOTES,'UTF-8')?></h1><?php if($done):?><div class="done"><strong><?=htmlspecialchars($t['done'],ENT_QUOTES,'UTF-8')?></strong><p><?=htmlspecialchars($t['delete'],ENT_QUOTES,'UTF-8')?></p><p><a href="/login.php"><?=htmlspecialchars($t['login'],ENT_QUOTES,'UTF-8')?></a></p></div><?php else:?><p><?=htmlspecialchars($t['intro'],ENT_QUOTES,'UTF-8')?></p><?php if($error):?><p class="error"><?=htmlspecialchars($error,ENT_QUOTES,'UTF-8')?></p><?php endif;?><form method="post"><input type="hidden" name="install_language" value="<?=$installLanguage?>"><h2><?=htmlspecialchars($t['database'],ENT_QUOTES,'UTF-8')?></h2><?php foreach(['host','database_name'=>'database','username'=>'user'] as $label=>$name):?><label><?=htmlspecialchars($t[is_int($label)?$name:$label],ENT_QUOTES,'UTF-8')?><input name="<?=$name?>" required value="<?=htmlspecialchars((string)($_POST[$name]??''),ENT_QUOTES,'UTF-8')?>"></label><?php endforeach;?><label><?=htmlspecialchars($t['password'],ENT_QUOTES,'UTF-8')?><input name="password" type="password" required></label><label><?=htmlspecialchars($t['prefix'],ENT_QUOTES,'UTF-8')?><input name="prefix" value="<?=htmlspecialchars((string)($_POST['prefix']??'triptale_'),ENT_QUOTES,'UTF-8')?>" required></label><h2><?=htmlspecialchars($t['app_admin'],ENT_QUOTES,'UTF-8')?></h2><label><?=htmlspecialchars($t['url'],ENT_QUOTES,'UTF-8')?><input name="base_url" type="url" required value="<?=htmlspecialchars((string)($_POST['base_url']??''),ENT_QUOTES,'UTF-8')?>"></label><label>TripTale language<select name="app_language"><?php foreach(['de'=>'Deutsch','en'=>'English','fr'=>'Français','es'=>'Español','it'=>'Italiano'] as $code=>$name):?><option value="<?=$code?>"<?=$code===($_POST['app_language']??$installLanguage)?' selected':''?>><?=$name?></option><?php endforeach;?></select></label><label><?=htmlspecialchars($t['first'],ENT_QUOTES,'UTF-8')?><input name="first_name" required></label><label><?=htmlspecialchars($t['last'],ENT_QUOTES,'UTF-8')?><input name="last_name" required></label><label><?=htmlspecialchars($t['email'],ENT_QUOTES,'UTF-8')?><input name="email" type="email" required></label><label><?=htmlspecialchars($t['admin_password'],ENT_QUOTES,'UTF-8')?><input name="admin_password" type="password" minlength="12" required></label><button><?=htmlspecialchars($t['start'],ENT_QUOTES,'UTF-8')?></button></form><?php endif;?></main></html>
