diff --git a/src/Commands/Commandable.php b/src/Commands/Commandable.php index bfa05fa..7dff325 100644 --- a/src/Commands/Commandable.php +++ b/src/Commands/Commandable.php @@ -75,7 +75,7 @@ public function optionInt(string $option, ?int $default = null): ?int return (int) $this->optionArgument($option, $default); } - public function optionBool(string $option, ?bool $default = null): ?bool + public function optionBool(string $option, ?bool $default = false): ?bool { return (bool) $this->optionArgument($option, $default); } diff --git a/src/Commands/Db/DbTestCommand.php b/src/Commands/Db/DbTestCommand.php new file mode 100644 index 0000000..276e466 --- /dev/null +++ b/src/Commands/Db/DbTestCommand.php @@ -0,0 +1,136 @@ +title(); + + $credentials = $this->optionBool('credentials'); + $success = false; + + $this->info('Testing database connection...'); + $this->newLine(); + + $connection = Schema::getConnection(); + + $driver = $connection->getDriverName(); + $database = $connection->getDatabaseName(); + $host = $connection->getConfig('host'); + $port = $connection->getConfig('port'); + $username = $connection->getConfig('username'); + $password = $connection->getConfig('password'); + + $this->comment("Driver: {$driver}"); + $this->comment("Database: {$database}"); + $this->comment("Host: {$host}"); + $this->comment("Port: {$port}"); + + if ($credentials) { + $this->comment("Username: {$username}"); + $this->comment("Password: {$password}"); + } + + $this->newLine(); + + $this->comment("Try to ping database at {$host}:{$port}..."); + $available = $this->pingDatabase($host, $port); + $this->info($available ? 'Database is available.' : 'Database is not available.'); + + $this->newLine(); + + if ($available) { + $success = $this->testConnection($connection); + } else { + $this->comment('Try to get error information...'); + $this->getError($connection); + + $success = false; + } + + if (! $success) { + return Command::FAILURE; + } + + return Command::SUCCESS; + } + + private function pingDatabase(string $url, int|string $port): bool + { + $connection = @fsockopen($url, $port, $errno, $errstr, 1); + if (is_resource($connection)) { + fclose($connection); + + return true; + } + + return false; + } + + private function getError(\Illuminate\Database\Connection $connection): void + { + try { + $connection->getPdo(); + } catch (\Throwable $th) { + $this->error($th->getMessage()); + } + } + + private function testConnection(\Illuminate\Database\Connection $connection): bool + { + $driverName = null; + $serverInfo = null; + $clientVersion = null; + $serverVersion = null; + $connectionStatus = null; + + try { + $pdo = $connection->getPdo(); + + $driverName = $pdo->getAttribute(\PDO::ATTR_DRIVER_NAME); + $serverInfo = $pdo->getAttribute(\PDO::ATTR_SERVER_INFO); + $clientVersion = $pdo->getAttribute(\PDO::ATTR_CLIENT_VERSION); + $serverVersion = $pdo->getAttribute(\PDO::ATTR_SERVER_VERSION); + $connectionStatus = $pdo->getAttribute(\PDO::ATTR_CONNECTION_STATUS); + } catch (\Exception $e) { + $this->error('Connection failed.'); + + return false; + } + + $this->alert('Connection successful.'); + $this->comment("Driver name: {$driverName}"); + $this->comment("Server info: {$serverInfo}"); + $this->comment("Client version: {$clientVersion}"); + $this->comment("Server version: {$serverVersion}"); + $this->comment("Connection status: {$connectionStatus}"); + + return true; + } +} diff --git a/src/Commands/Setup/SetupInstallCommand.php b/src/Commands/Setup/SetupInstallCommand.php new file mode 100644 index 0000000..ef6152c --- /dev/null +++ b/src/Commands/Setup/SetupInstallCommand.php @@ -0,0 +1,86 @@ +title(); + + $production = $this->optionBool('production', false); + + $this->info('Create .env file...'); + + if (! file_exists(base_path('.env'))) { + copy(base_path('.env.example'), base_path('.env')); + } + + $this->info('Generating key...'); + + Artisan::call('key:generate', [ + '--force' => true, + ], $this->output); + + if ($production) { + $this->dotenvProduction(); + $this->info('Production mode enabled.'); + } + + $this->info('Linking storage...'); + + Artisan::call('storage:link', [ + '--force' => true, + ], $this->output); + + $this->info('Migrating database...'); + + Artisan::call('migrate', [ + '--force' => true, + ], $this->output); + + $this->info('Seeding database...'); + + Artisan::call('db:seed', [ + '--force' => true, + ], $this->output); + + $this->info('Done.'); + + return Command::SUCCESS; + } + + private function dotenvProduction(): void + { + $env = file_get_contents(base_path('.env')); + + $env = str_replace('APP_ENV=local', 'APP_ENV=production', $env); + $env = str_replace('APP_DEBUG=true', 'APP_DEBUG=false', $env); + + file_put_contents(base_path('.env'), $env); + } +} diff --git a/src/StewardServiceProvider.php b/src/StewardServiceProvider.php index 0eba714..1f520c9 100644 --- a/src/StewardServiceProvider.php +++ b/src/StewardServiceProvider.php @@ -44,6 +44,8 @@ public function configurePackage(Package $package): void \Kiwilan\Steward\Commands\Jobs\JobsClearCommand::class, \Kiwilan\Steward\Commands\Model\ModelBackupCommand::class, \Kiwilan\Steward\Commands\Model\ModelRestoreCommand::class, + \Kiwilan\Steward\Commands\Setup\SetupInstallCommand::class, + \Kiwilan\Steward\Commands\Db\DbTestCommand::class, ]); }