diff --git a/app/Filament/Pages/Installer/PanelInstaller.php b/app/Filament/Pages/Installer/PanelInstaller.php
index fba27eade8..bad77920d0 100644
--- a/app/Filament/Pages/Installer/PanelInstaller.php
+++ b/app/Filament/Pages/Installer/PanelInstaller.php
@@ -3,12 +3,12 @@
namespace App\Filament\Pages\Installer;
use App\Filament\Pages\Dashboard;
-use App\Filament\Pages\Installer\Steps\AdminUserStep;
-use App\Filament\Pages\Installer\Steps\CompletedStep;
+use App\Filament\Pages\Installer\Steps\CacheStep;
use App\Filament\Pages\Installer\Steps\DatabaseStep;
use App\Filament\Pages\Installer\Steps\EnvironmentStep;
-use App\Filament\Pages\Installer\Steps\RedisStep;
+use App\Filament\Pages\Installer\Steps\QueueStep;
use App\Filament\Pages\Installer\Steps\RequirementsStep;
+use App\Filament\Pages\Installer\Steps\SessionStep;
use App\Models\User;
use App\Services\Users\UserCreationService;
use App\Traits\CheckMigrationsTrait;
@@ -19,7 +19,6 @@
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Form;
-use Filament\Forms\Get;
use Filament\Notifications\Notification;
use Filament\Pages\SimplePage;
use Filament\Support\Enums\MaxWidth;
@@ -43,8 +42,6 @@ class PanelInstaller extends SimplePage implements HasForms
protected static string $view = 'filament.pages.installer';
- private User $user;
-
public function getMaxWidth(): MaxWidth|string
{
return MaxWidth::SevenExtraLarge;
@@ -70,10 +67,9 @@ protected function getFormSchema(): array
RequirementsStep::make(),
EnvironmentStep::make($this),
DatabaseStep::make($this),
- RedisStep::make($this)
- ->hidden(fn (Get $get) => $get('env_general.SESSION_DRIVER') != 'redis' && $get('env_general.QUEUE_CONNECTION') != 'redis' && $get('env_general.CACHE_STORE') != 'redis'),
- AdminUserStep::make($this),
- CompletedStep::make(),
+ CacheStep::make($this),
+ QueueStep::make($this),
+ SessionStep::make(),
])
->persistStepInQueryString()
->nextAction(fn (Action $action) => $action->keyBindings('enter'))
@@ -95,14 +91,17 @@ protected function getFormStatePath(): ?string
return 'data';
}
- public function submit(): Redirector|RedirectResponse
+ public function submit(UserCreationService $userCreationService): Redirector|RedirectResponse
{
// Disable installer
$this->writeToEnvironment(['APP_INSTALLED' => 'true']);
- // Login user
- $this->user ??= User::all()->filter(fn ($user) => $user->isRootAdmin())->first();
- auth()->guard()->login($this->user, true);
+ // 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
return redirect(Dashboard::getUrl());
@@ -112,6 +111,7 @@ 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);
@@ -161,12 +161,13 @@ public function runMigrations(string $driver): void
}
}
- public function createAdminUser(UserCreationService $userCreationService): void
+ public function createAdminUser(UserCreationService $userCreationService): User
{
try {
$userData = array_get($this->data, 'user');
$userData['root_admin'] = true;
- $this->user = $userCreationService->handle($userData);
+
+ return $userCreationService->handle($userData);
} catch (Exception $exception) {
report($exception);
diff --git a/app/Filament/Pages/Installer/Steps/AdminUserStep.php b/app/Filament/Pages/Installer/Steps/AdminUserStep.php
deleted file mode 100644
index 5bdfe38d94..0000000000
--- a/app/Filament/Pages/Installer/Steps/AdminUserStep.php
+++ /dev/null
@@ -1,34 +0,0 @@
-label('Admin User')
- ->schema([
- TextInput::make('user.email')
- ->label('Admin E-Mail')
- ->required()
- ->email()
- ->placeholder('admin@example.com'),
- TextInput::make('user.username')
- ->label('Admin Username')
- ->required()
- ->placeholder('admin'),
- TextInput::make('user.password')
- ->label('Admin Password')
- ->required()
- ->password()
- ->revealable(),
- ])
- ->afterValidation(fn (UserCreationService $service) => $installer->createAdminUser($service));
- }
-}
diff --git a/app/Filament/Pages/Installer/Steps/CacheStep.php b/app/Filament/Pages/Installer/Steps/CacheStep.php
new file mode 100644
index 0000000000..71b3994d47
--- /dev/null
+++ b/app/Filament/Pages/Installer/Steps/CacheStep.php
@@ -0,0 +1,123 @@
+ 'Filesystem',
+ 'redis' => 'Redis',
+ ];
+
+ public static function make(PanelInstaller $installer): Step
+ {
+ return Step::make('cache')
+ ->label('Cache')
+ ->columns()
+ ->schema([
+ ToggleButtons::make('env_cache.CACHE_STORE')
+ ->label('Cache Driver')
+ ->hintIcon('tabler-question-mark')
+ ->hintIconTooltip('The driver used for caching. We recommend "Filesystem".')
+ ->required()
+ ->inline()
+ ->options(self::CACHE_DRIVERS)
+ ->default(config('cache.default'))
+ ->columnSpanFull()
+ ->live()
+ ->afterStateUpdated(function ($state, Set $set, Get $get) {
+ if ($state !== 'redis') {
+ $set('env_cache.REDIS_HOST', null);
+ $set('env_cache.REDIS_PORT', null);
+ $set('env_cache.REDIS_USERNAME', null);
+ $set('env_cache.REDIS_PASSWORD', null);
+ } else {
+ $set('env_cache.REDIS_HOST', $get('env_cache.REDIS_HOST') ?? '127.0.0.1');
+ $set('env_cache.REDIS_PORT', $get('env_cache.REDIS_PORT') ?? '6379');
+ $set('env_cache.REDIS_USERNAME', null);
+ }
+ }),
+ TextInput::make('env_cache.REDIS_HOST')
+ ->label('Redis Host')
+ ->placeholder('127.0.0.1')
+ ->hintIcon('tabler-question-mark')
+ ->hintIconTooltip('The host of your redis server. Make sure it is reachable.')
+ ->required(fn (Get $get) => $get('env_cache.CACHE_STORE') === 'redis')
+ ->default(fn (Get $get) => $get('env_cache.CACHE_STORE') === 'redis' ? config('database.redis.default.host') : null)
+ ->visible(fn (Get $get) => $get('env_cache.CACHE_STORE') === 'redis'),
+ TextInput::make('env_cache.REDIS_PORT')
+ ->label('Redis Port')
+ ->placeholder('6379')
+ ->hintIcon('tabler-question-mark')
+ ->hintIconTooltip('The port of your redis server.')
+ ->required(fn (Get $get) => $get('env_cache.CACHE_STORE') === 'redis')
+ ->default(fn (Get $get) => $get('env_cache.CACHE_STORE') === 'redis' ? config('database.redis.default.port') : null)
+ ->visible(fn (Get $get) => $get('env_cache.CACHE_STORE') === 'redis'),
+ TextInput::make('env_cache.REDIS_USERNAME')
+ ->label('Redis Username')
+ ->hintIcon('tabler-question-mark')
+ ->hintIconTooltip('The name of your redis user. Can be empty')
+ ->default(fn (Get $get) => $get('env_cache.CACHE_STORE') === 'redis' ? config('database.redis.default.username') : null)
+ ->visible(fn (Get $get) => $get('env_cache.CACHE_STORE') === 'redis'),
+ TextInput::make('env_cache.REDIS_PASSWORD')
+ ->label('Redis Password')
+ ->hintIcon('tabler-question-mark')
+ ->hintIconTooltip('The password for your redis user. Can be empty.')
+ ->password()
+ ->revealable()
+ ->default(fn (Get $get) => $get('env_cache.CACHE_STORE') === 'redis' ? config('database.redis.default.password') : null)
+ ->visible(fn (Get $get) => $get('env_cache.CACHE_STORE') === 'redis'),
+ ])
+ ->afterValidation(function (Get $get, Application $app) use ($installer) {
+ $driver = $get('env_cache.CACHE_STORE');
+
+ if (!self::testConnection($app, $driver, $get('env_cache.REDIS_HOST'), $get('env_cache.REDIS_PORT'), $get('env_cache.REDIS_USERNAME'), $get('env_cache.REDIS_PASSWORD'))) {
+ throw new Halt('Redis connection failed');
+ }
+
+ $installer->writeToEnv('env_cache');
+ });
+ }
+
+ private static function testConnection(Application $app, string $driver, ?string $host, null|string|int $port, ?string $username, ?string $password): bool
+ {
+ if ($driver !== 'redis') {
+ return true;
+ }
+
+ try {
+ $redis = new RedisManager($app, 'predis', [
+ 'default' => [
+ 'host' => $host,
+ 'port' => $port,
+ 'username' => $username,
+ 'password' => $password,
+ ],
+ ]);
+
+ $redis->connection()->command('ping');
+ } catch (Exception $exception) {
+ Notification::make()
+ ->title('Redis connection failed')
+ ->body($exception->getMessage())
+ ->danger()
+ ->send();
+
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/app/Filament/Pages/Installer/Steps/CompletedStep.php b/app/Filament/Pages/Installer/Steps/CompletedStep.php
deleted file mode 100644
index 50f9a780cf..0000000000
--- a/app/Filament/Pages/Installer/Steps/CompletedStep.php
+++ /dev/null
@@ -1,34 +0,0 @@
-label('Setup complete')
- ->schema([
- Placeholder::make('')
- ->content(new HtmlString('The setup is nearly complete!
As last step you need to create a new cronjob that runs every minute to process specific tasks, such as session cleanup and scheduled tasks, and also create a queue worker.')),
- TextInput::make('crontab')
- ->label(new HtmlString('Run the following command to setup your crontab. Note that www-data
is your webserver user. On some systems this username might be different!'))
- ->disabled()
- ->hintAction(CopyAction::make())
- ->default('(crontab -l -u www-data 2>/dev/null; echo "* * * * * php ' . base_path() . '/artisan schedule:run >> /dev/null 2>&1") | crontab -u www-data -'),
- TextInput::make('queueService')
- ->label(new HtmlString('To setup the queue worker service you simply have to run the following command.'))
- ->disabled()
- ->hintAction(CopyAction::make())
- ->default('sudo php ' . base_path() . '/artisan p:environment:queue-service'),
- Placeholder::make('')
- ->content('After you finished these two last tasks you can click on "Finish" and use your new panel! Have fun!'),
- ]);
- }
-}
diff --git a/app/Filament/Pages/Installer/Steps/DatabaseStep.php b/app/Filament/Pages/Installer/Steps/DatabaseStep.php
index 3a4449777e..7ddae24f02 100644
--- a/app/Filament/Pages/Installer/Steps/DatabaseStep.php
+++ b/app/Filament/Pages/Installer/Steps/DatabaseStep.php
@@ -5,62 +5,92 @@
use App\Filament\Pages\Installer\PanelInstaller;
use Exception;
use Filament\Forms\Components\TextInput;
+use Filament\Forms\Components\ToggleButtons;
use Filament\Forms\Components\Wizard\Step;
use Filament\Forms\Get;
+use Filament\Forms\Set;
use Filament\Notifications\Notification;
use Filament\Support\Exceptions\Halt;
use Illuminate\Support\Facades\DB;
class DatabaseStep
{
+ public const DATABASE_DRIVERS = [
+ 'sqlite' => 'SQLite',
+ 'mariadb' => 'MariaDB',
+ 'mysql' => 'MySQL',
+ ];
+
public static function make(PanelInstaller $installer): Step
{
return Step::make('database')
->label('Database')
->columns()
->schema([
+ ToggleButtons::make('env_database.DB_CONNECTION')
+ ->label('Database Driver')
+ ->hintIcon('tabler-question-mark')
+ ->hintIconTooltip('The driver used for the panel database. We recommend "SQLite".')
+ ->required()
+ ->inline()
+ ->options(self::DATABASE_DRIVERS)
+ ->default(config('database.default'))
+ ->live()
+ ->afterStateUpdated(function ($state, Set $set, Get $get) {
+ $set('env_database.DB_DATABASE', $state === 'sqlite' ? 'database.sqlite' : 'panel');
+
+ if ($state === 'sqlite') {
+ $set('env_database.DB_HOST', null);
+ $set('env_database.DB_PORT', null);
+ $set('env_database.DB_USERNAME', null);
+ $set('env_database.DB_PASSWORD', null);
+ } else {
+ $set('env_database.DB_HOST', $get('env_database.DB_HOST') ?? '127.0.0.1');
+ $set('env_database.DB_PORT', $get('env_database.DB_PORT') ?? '3306');
+ $set('env_database.DB_USERNAME', $get('env_database.DB_USERNAME') ?? 'pelican');
+ }
+ }),
TextInput::make('env_database.DB_DATABASE')
- ->label(fn (Get $get) => $get('env_general.DB_CONNECTION') === 'sqlite' ? 'Database Path' : 'Database Name')
- ->columnSpanFull()
+ ->label(fn (Get $get) => $get('env_database.DB_CONNECTION') === 'sqlite' ? 'Database Path' : 'Database Name')
+ ->placeholder(fn (Get $get) => $get('env_database.DB_CONNECTION') === 'sqlite' ? 'database.sqlite' : 'panel')
->hintIcon('tabler-question-mark')
- ->hintIconTooltip(fn (Get $get) => $get('env_general.DB_CONNECTION') === 'sqlite' ? 'The path of your .sqlite file relative to the database folder.' : 'The name of the panel database.')
+ ->hintIconTooltip(fn (Get $get) => $get('env_database.DB_CONNECTION') === 'sqlite' ? 'The path of your .sqlite file relative to the database folder.' : 'The name of the panel database.')
->required()
- ->default(fn (Get $get) => env('DB_DATABASE', $get('env_general.DB_CONNECTION') === 'sqlite' ? 'database.sqlite' : 'panel')),
+ ->default('database.sqlite'),
TextInput::make('env_database.DB_HOST')
->label('Database Host')
+ ->placeholder('127.0.0.1')
->hintIcon('tabler-question-mark')
->hintIconTooltip('The host of your database. Make sure it is reachable.')
- ->required(fn (Get $get) => $get('env_general.DB_CONNECTION') !== 'sqlite')
- ->default(fn (Get $get) => $get('env_general.DB_CONNECTION') !== 'sqlite' ? env('DB_HOST', '127.0.0.1') : null)
- ->hidden(fn (Get $get) => $get('env_general.DB_CONNECTION') === 'sqlite'),
+ ->required(fn (Get $get) => $get('env_database.DB_CONNECTION') !== 'sqlite')
+ ->hidden(fn (Get $get) => $get('env_database.DB_CONNECTION') === 'sqlite'),
TextInput::make('env_database.DB_PORT')
->label('Database Port')
+ ->placeholder('3306')
->hintIcon('tabler-question-mark')
->hintIconTooltip('The port of your database.')
- ->required(fn (Get $get) => $get('env_general.DB_CONNECTION') !== 'sqlite')
->numeric()
->minValue(1)
->maxValue(65535)
- ->default(fn (Get $get) => $get('env_general.DB_CONNECTION') !== 'sqlite' ? env('DB_PORT', 3306) : null)
- ->hidden(fn (Get $get) => $get('env_general.DB_CONNECTION') === 'sqlite'),
+ ->required(fn (Get $get) => $get('env_database.DB_CONNECTION') !== 'sqlite')
+ ->hidden(fn (Get $get) => $get('env_database.DB_CONNECTION') === 'sqlite'),
TextInput::make('env_database.DB_USERNAME')
->label('Database Username')
+ ->placeholder('pelican')
->hintIcon('tabler-question-mark')
->hintIconTooltip('The name of your database user.')
- ->required(fn (Get $get) => $get('env_general.DB_CONNECTION') !== 'sqlite')
- ->default(fn (Get $get) => $get('env_general.DB_CONNECTION') !== 'sqlite' ? env('DB_USERNAME', 'pelican') : null)
- ->hidden(fn (Get $get) => $get('env_general.DB_CONNECTION') === 'sqlite'),
+ ->required(fn (Get $get) => $get('env_database.DB_CONNECTION') !== 'sqlite')
+ ->hidden(fn (Get $get) => $get('env_database.DB_CONNECTION') === 'sqlite'),
TextInput::make('env_database.DB_PASSWORD')
->label('Database Password')
->hintIcon('tabler-question-mark')
->hintIconTooltip('The password of your database user. Can be empty.')
->password()
->revealable()
- ->default(fn (Get $get) => $get('env_general.DB_CONNECTION') !== 'sqlite' ? env('DB_PASSWORD') : null)
- ->hidden(fn (Get $get) => $get('env_general.DB_CONNECTION') === 'sqlite'),
+ ->hidden(fn (Get $get) => $get('env_database.DB_CONNECTION') === 'sqlite'),
])
->afterValidation(function (Get $get) use ($installer) {
- $driver = $get('env_general.DB_CONNECTION');
+ $driver = $get('env_database.DB_CONNECTION');
if (!self::testConnection($driver, $get('env_database.DB_HOST'), $get('env_database.DB_PORT'), $get('env_database.DB_DATABASE'), $get('env_database.DB_USERNAME'), $get('env_database.DB_PASSWORD'))) {
throw new Halt('Database connection failed');
diff --git a/app/Filament/Pages/Installer/Steps/EnvironmentStep.php b/app/Filament/Pages/Installer/Steps/EnvironmentStep.php
index 5df2ecd40a..0c54069126 100644
--- a/app/Filament/Pages/Installer/Steps/EnvironmentStep.php
+++ b/app/Filament/Pages/Installer/Steps/EnvironmentStep.php
@@ -3,40 +3,12 @@
namespace App\Filament\Pages\Installer\Steps;
use App\Filament\Pages\Installer\PanelInstaller;
-use App\Traits\EnvironmentWriterTrait;
+use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\TextInput;
-use Filament\Forms\Components\ToggleButtons;
use Filament\Forms\Components\Wizard\Step;
-use Filament\Forms\Set;
class EnvironmentStep
{
- use EnvironmentWriterTrait;
-
- public const CACHE_DRIVERS = [
- 'file' => 'Filesystem',
- 'redis' => 'Redis',
- ];
-
- public const SESSION_DRIVERS = [
- 'file' => 'Filesystem',
- 'database' => 'Database',
- 'cookie' => 'Cookie',
- 'redis' => 'Redis',
- ];
-
- public const QUEUE_DRIVERS = [
- 'database' => 'Database',
- 'sync' => 'Sync',
- 'redis' => 'Redis',
- ];
-
- public const DATABASE_DRIVERS = [
- 'sqlite' => 'SQLite',
- 'mariadb' => 'MariaDB',
- 'mysql' => 'MySQL',
- ];
-
public static function make(PanelInstaller $installer): Step
{
return Step::make('environment')
@@ -54,44 +26,26 @@ public static function make(PanelInstaller $installer): Step
->hintIcon('tabler-question-mark')
->hintIconTooltip('This will be the URL you access your Panel from.')
->required()
- ->default(url(''))
- ->live()
- ->afterStateUpdated(fn ($state, Set $set) => $set('env_general.SESSION_SECURE_COOKIE', str_starts_with($state, 'https://') ? 'true' : 'false')),
- TextInput::make('env_general.SESSION_SECURE_COOKIE')
- ->hidden()
- ->default(str_starts_with(url(''), 'https://') ? 'true' : 'false'),
- ToggleButtons::make('env_general.CACHE_STORE')
- ->label('Cache Driver')
- ->hintIcon('tabler-question-mark')
- ->hintIconTooltip('The driver used for caching. We recommend "Filesystem".')
- ->required()
- ->inline()
- ->options(self::CACHE_DRIVERS)
- ->default(config('cache.default', 'file')),
- ToggleButtons::make('env_general.SESSION_DRIVER')
- ->label('Session Driver')
- ->hintIcon('tabler-question-mark')
- ->hintIconTooltip('The driver used for storing sessions. We recommend "Filesystem" or "Database".')
- ->required()
- ->inline()
- ->options(self::SESSION_DRIVERS)
- ->default(config('session.driver', 'file')),
- ToggleButtons::make('env_general.QUEUE_CONNECTION')
- ->label('Queue Driver')
- ->hintIcon('tabler-question-mark')
- ->hintIconTooltip('The driver used for handling queues. We recommend "Database".')
- ->required()
- ->inline()
- ->options(self::QUEUE_DRIVERS)
- ->default(config('queue.default', 'database')),
- ToggleButtons::make('env_general.DB_CONNECTION')
- ->label('Database Driver')
- ->hintIcon('tabler-question-mark')
- ->hintIconTooltip('The driver used for the panel database. We recommend "SQLite".')
- ->required()
- ->inline()
- ->options(self::DATABASE_DRIVERS)
- ->default(config('database.default', 'sqlite')),
+ ->default(url('')),
+ Fieldset::make('adminuser')
+ ->label('Admin User')
+ ->columns(3)
+ ->schema([
+ TextInput::make('user.email')
+ ->label('E-Mail')
+ ->required()
+ ->email()
+ ->placeholder('admin@example.com'),
+ TextInput::make('user.username')
+ ->label('Username')
+ ->required()
+ ->placeholder('admin'),
+ TextInput::make('user.password')
+ ->label('Password')
+ ->required()
+ ->password()
+ ->revealable(),
+ ]),
])
->afterValidation(fn () => $installer->writeToEnv('env_general'));
}
diff --git a/app/Filament/Pages/Installer/Steps/QueueStep.php b/app/Filament/Pages/Installer/Steps/QueueStep.php
new file mode 100644
index 0000000000..4e6c065d0e
--- /dev/null
+++ b/app/Filament/Pages/Installer/Steps/QueueStep.php
@@ -0,0 +1,64 @@
+ 'Database',
+ 'redis' => 'Redis',
+ 'sync' => 'Sync',
+ ];
+
+ public static function make(PanelInstaller $installer): Step
+ {
+ return Step::make('queue')
+ ->label('Queue')
+ ->columns()
+ ->schema([
+ ToggleButtons::make('env_queue.QUEUE_CONNECTION')
+ ->label('Queue Driver')
+ ->hintIcon('tabler-question-mark')
+ ->hintIconTooltip('The driver used for handling queues. We recommend "Database".')
+ ->required()
+ ->inline()
+ ->options(self::QUEUE_DRIVERS)
+ ->disableOptionWhen(fn ($value, Get $get) => $value === 'redis' && $get('env_cache.CACHE_STORE') !== 'redis')
+ ->default(config('queue.default')),
+ Toggle::make('done')
+ ->label('I have done both steps below.')
+ ->accepted(fn () => !file_exists('/.dockerenv'))
+ ->inline(false)
+ ->validationMessages([
+ 'accepted' => 'You need to do both steps before continuing!',
+ ])
+ ->hidden(fn () => file_exists('/.dockerenv')),
+ TextInput::make('crontab')
+ ->label(new HtmlString('Run the following command to set up your crontab. Note that www-data
is your webserver user. On some systems this username might be different!'))
+ ->disabled()
+ ->hintAction(CopyAction::make())
+ ->default('(crontab -l -u www-data 2>/dev/null; echo "* * * * * php ' . base_path() . '/artisan schedule:run >> /dev/null 2>&1") | crontab -u www-data -')
+ ->hidden(fn () => file_exists('/.dockerenv'))
+ ->columnSpanFull(),
+ TextInput::make('queueService')
+ ->label(new HtmlString('To setup the queue worker service you simply have to run the following command.'))
+ ->disabled()
+ ->hintAction(CopyAction::make())
+ ->default('sudo php ' . base_path() . '/artisan p:environment:queue-service')
+ ->hidden(fn () => file_exists('/.dockerenv'))
+ ->columnSpanFull(),
+ ])
+ ->afterValidation(function () use ($installer) {
+ $installer->writeToEnv('env_queue');
+ });
+ }
+}
diff --git a/app/Filament/Pages/Installer/Steps/RedisStep.php b/app/Filament/Pages/Installer/Steps/RedisStep.php
deleted file mode 100644
index df07e98e4c..0000000000
--- a/app/Filament/Pages/Installer/Steps/RedisStep.php
+++ /dev/null
@@ -1,85 +0,0 @@
-label('Redis')
- ->columns()
- ->schema([
- TextInput::make('env_redis.REDIS_HOST')
- ->label('Redis Host')
- ->hintIcon('tabler-question-mark')
- ->hintIconTooltip('The host of your redis server. Make sure it is reachable.')
- ->required()
- ->default(config('database.redis.default.host')),
- TextInput::make('env_redis.REDIS_PORT')
- ->label('Redis Port')
- ->hintIcon('tabler-question-mark')
- ->hintIconTooltip('The port of your redis server.')
- ->required()
- ->default(config('database.redis.default.port')),
- TextInput::make('env_redis.REDIS_USERNAME')
- ->label('Redis Username')
- ->hintIcon('tabler-question-mark')
- ->hintIconTooltip('The name of your redis user. Can be empty')
- ->default(config('database.redis.default.username')),
- TextInput::make('env_redis.REDIS_PASSWORD')
- ->label('Redis Password')
- ->hintIcon('tabler-question-mark')
- ->hintIconTooltip('The password for your redis user. Can be empty.')
- ->password()
- ->revealable()
- ->default(config('database.redis.default.password')),
- ])
- ->afterValidation(function (Get $get, Application $app) use ($installer) {
- if (!self::testConnection($app, $get('env_redis.REDIS_HOST'), $get('env_redis.REDIS_PORT'), $get('env_redis.REDIS_USERNAME'), $get('env_redis.REDIS_PASSWORD'))) {
- throw new Halt('Redis connection failed');
- }
-
- $installer->writeToEnv('env_redis');
- });
- }
-
- private static function testConnection(Application $app, string $host, null|string|int $port, ?string $username, ?string $password): bool
- {
- try {
- $redis = new RedisManager($app, 'predis', [
- 'default' => [
- 'host' => $host,
- 'port' => $port,
- 'username' => $username,
- 'password' => $password,
- ],
- ]);
-
- $redis->connection()->command('ping');
- } catch (Exception $exception) {
- Notification::make()
- ->title('Redis connection failed')
- ->body($exception->getMessage())
- ->danger()
- ->send();
-
- return false;
- }
-
- return true;
- }
-}
diff --git a/app/Filament/Pages/Installer/Steps/SessionStep.php b/app/Filament/Pages/Installer/Steps/SessionStep.php
new file mode 100644
index 0000000000..ceb9a77ae0
--- /dev/null
+++ b/app/Filament/Pages/Installer/Steps/SessionStep.php
@@ -0,0 +1,38 @@
+ 'Filesystem',
+ 'database' => 'Database',
+ 'cookie' => 'Cookie',
+ 'redis' => 'Redis',
+ ];
+
+ public static function make(): Step
+ {
+ return Step::make('session')
+ ->label('Session')
+ ->schema([
+ ToggleButtons::make('env_session.SESSION_DRIVER')
+ ->label('Session Driver')
+ ->hintIcon('tabler-question-mark')
+ ->hintIconTooltip('The driver used for storing sessions. We recommend "Filesystem" or "Database".')
+ ->required()
+ ->inline()
+ ->options(self::SESSION_DRIVERS)
+ ->disableOptionWhen(fn ($value, Get $get) => $value === 'redis' && $get('env_cache.CACHE_STORE') !== 'redis')
+ ->default(config('session.driver')),
+ TextInput::make('env_session.SESSION_SECURE_COOKIE')
+ ->hidden()
+ ->default(request()->isSecure()),
+ ]);
+ }
+}