*/ public array $data = []; protected static string $view = 'filament.pages.installer'; public function getMaxWidth(): MaxWidth|string { return MaxWidth::SevenExtraLarge; } public static function isInstalled(): bool { return config('app.installed'); } public function mount(): void { abort_if(self::isInstalled(), 404); $this->form->fill(); } protected function getFormSchema(): array { return [ Grid::make() ->schema([ $this->getLanguageComponent(), ]), Wizard::make([ RequirementsStep::make(), EnvironmentStep::make($this), DatabaseStep::make($this), CacheStep::make($this), QueueStep::make($this), SessionStep::make(), ]) ->persistStepInQueryString() ->nextAction(fn (Action $action) => $action->keyBindings('enter')) ->submitAction(new HtmlString(Blade::render(<<<'BLADE' trans('installer.finish') BLADE))), ]; } protected function getLanguageComponent(): Component { return Select::make('language') ->hiddenLabel() ->prefix(trans('profile.language')) ->prefixIcon('tabler-flag') ->required() ->live() ->default('en') ->selectablePlaceholder(false) ->options(fn (LanguageService $languageService) => $languageService->getAvailableLanguages()) ->afterStateUpdated(fn ($state, Application $app) => $app->setLocale($state ?? config('app.locale'))) ->native(false) ->columnStart(4); } protected function getFormStatePath(): ?string { return 'data'; } public function submit(UserCreationService $userCreationService): void { try { // Disable installer $this->writeToEnvironment(['APP_INSTALLED' => 'true']); // Run migrations $this->runMigrations(); // Create admin user & login $user = $this->createAdminUser($userCreationService); auth()->guard()->login($user, true); // Write session data at the very end to avoid "page expired" errors $this->writeToEnv('env_session'); // Redirect to admin panel $this->redirect(Filament::getPanel('admin')->getUrl()); } catch (Halt) { } } public function writeToEnv(string $key): void { try { $variables = array_get($this->data, $key); $variables = array_filter($variables); // Filter array to remove NULL values $this->writeToEnvironment($variables); } catch (Exception $exception) { report($exception); Notification::make() ->title(trans('installer.exceptions.write_env')) ->body($exception->getMessage()) ->danger() ->persistent() ->send(); throw new Halt(trans('installer.exceptions.write_env')); } Artisan::call('config:clear'); } public function runMigrations(): void { try { Artisan::call('migrate', [ '--force' => true, '--seed' => true, ]); } catch (Exception $exception) { report($exception); Notification::make() ->title(trans('installer.database.exceptions.migration')) ->body($exception->getMessage()) ->danger() ->persistent() ->send(); throw new Halt(trans('installer.exceptions.migration')); } if (!$this->hasCompletedMigrations()) { Notification::make() ->title(trans('installer.database.exceptions.migration')) ->danger() ->persistent() ->send(); throw new Halt(trans('installer.database.exceptions.migration')); } } public function createAdminUser(UserCreationService $userCreationService): User { try { $userData = array_get($this->data, 'user'); $userData['root_admin'] = true; return $userCreationService->handle($userData); } catch (Exception $exception) { report($exception); Notification::make() ->title(trans('installer.exceptions.create_user')) ->body($exception->getMessage()) ->danger() ->persistent() ->send(); throw new Halt(trans('installer.exceptions.create_user')); } } }