envExists()) { return redirect('/'); } return view('installer', [ 'appUrl' => $request->getSchemeAndHttpHost(), ]); } public function store(Request $request): View|RedirectResponse { if ($this->envExists()) { return redirect('/'); } $data = $request->validate([ 'app_url' => ['required', 'url'], 'db_host' => ['required', 'string', 'max:255'], 'db_port' => ['nullable', 'integer'], 'db_database' => ['required', 'string', 'max:255'], 'db_username' => ['required', 'string', 'max:255'], 'db_password' => ['nullable', 'string'], 'admin_name' => ['required', 'string', 'max:255'], 'admin_email' => ['required', 'email', 'max:255'], 'admin_password' => ['required', 'string', 'min:8'], ]); $appKey = 'base64:' . base64_encode(random_bytes(32)); $envLines = [ 'APP_NAME="speedBB"', 'APP_ENV=production', 'APP_DEBUG=false', 'APP_URL=' . $data['app_url'], 'APP_KEY=' . $appKey, '', 'DB_CONNECTION=mysql', 'DB_HOST=' . $data['db_host'], 'DB_PORT=' . ($data['db_port'] ?: 3306), 'DB_DATABASE=' . $data['db_database'], 'DB_USERNAME=' . $data['db_username'], 'DB_PASSWORD=' . ($data['db_password'] ?? ''), '', 'MAIL_MAILER=sendmail', 'MAIL_SENDMAIL_PATH="/usr/sbin/sendmail -bs -i"', 'MAIL_FROM_ADDRESS="hello@example.com"', 'MAIL_FROM_NAME="speedBB"', ]; $this->writeEnv(implode("\n", $envLines) . "\n"); config([ 'app.key' => $appKey, 'app.url' => $data['app_url'], 'database.default' => 'mysql', 'database.connections.mysql.host' => $data['db_host'], 'database.connections.mysql.port' => (int) ($data['db_port'] ?: 3306), 'database.connections.mysql.database' => $data['db_database'], 'database.connections.mysql.username' => $data['db_username'], 'database.connections.mysql.password' => $data['db_password'] ?? '', 'mail.default' => 'sendmail', 'mail.mailers.sendmail.path' => '/usr/sbin/sendmail -bs -i', ]); DB::purge('mysql'); try { DB::connection('mysql')->getPdo(); } catch (\Throwable $e) { $this->removeEnv(); return view('installer', [ 'appUrl' => $data['app_url'], 'error' => 'Database connection failed: ' . $e->getMessage(), 'old' => $data, ]); } $migrateExit = Artisan::call('migrate', ['--force' => true]); if ($migrateExit !== 0) { $this->removeEnv(); return view('installer', [ 'appUrl' => $data['app_url'], 'error' => 'Migration failed. Please check your database credentials.', 'old' => $data, ]); } $adminRole = Role::firstOrCreate(['name' => 'ROLE_ADMIN']); $founderRole = Role::firstOrCreate(['name' => 'ROLE_FOUNDER']); $user = User::create([ 'name' => $data['admin_name'], 'name_canonical' => Str::lower(trim($data['admin_name'])), 'email' => $data['admin_email'], 'password' => Hash::make($data['admin_password']), 'email_verified_at' => now(), ]); $user->roles()->sync([$adminRole->id, $founderRole->id]); return view('installer-success'); } private function envExists(): bool { return file_exists(base_path('.env')); } private function writeEnv(string $contents): void { $path = base_path('.env'); file_put_contents($path, $contents); } private function removeEnv(): void { $path = base_path('.env'); if (file_exists($path)) { unlink($path); } } }