diff options
Diffstat (limited to 'main/app/system/Bakery/Command/Setup.php')
-rwxr-xr-x | main/app/system/Bakery/Command/Setup.php | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/main/app/system/Bakery/Command/Setup.php b/main/app/system/Bakery/Command/Setup.php new file mode 100755 index 0000000..b489ce2 --- /dev/null +++ b/main/app/system/Bakery/Command/Setup.php @@ -0,0 +1,223 @@ +<?php +/** + * UserFrosting (http://www.userfrosting.com) + * + * @link https://github.com/userfrosting/UserFrosting + * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License) + */ +namespace UserFrosting\System\Bakery\Command; + +use Illuminate\Database\Capsule\Manager as Capsule; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; +use UserFrosting\System\Bakery\BaseCommand; + +/** + * Setup wizard CLI Tools. + * Helper command to setup .env file + * + * @author Alex Weissman (https://alexanderweissman.com) + */ +class Setup extends BaseCommand +{ + /** + * envfile path + */ + protected $envPath = \UserFrosting\APP_DIR. '/.env'; + + /** + * {@inheritDoc} + */ + protected function configure() + { + $this->setName("setup") + ->setDescription("UserFrosting configuration wizard") + ->setHelp("Helper command to setup the database and email configuration. This can also be done manually by editing the <comment>app/.env</comment> file or using global server environment variables.") + ->addOption("force", "f", InputOption::VALUE_NONE, "If `.env` file exist, force setup to run again"); + } + + /** + * {@inheritDoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + // Get config + $config = $this->ci->config; + + // Get options + $force = $input->getOption('force'); + + // Display header, + $this->io->title("UserFrosting's Setup Wizard"); + + // Check if the .env file exist. + if (!$force && file_exists($this->envPath)) { + $this->io->note("File `{$this->envPath}` already exist. Use the `php bakery setup -f` command to force setup to run again."); + return; + } + + // There might not be any `.env` file because there may be some custom config or global env values defined on the server. + // We'll check for that. If the configs are empty, we'll assume nothing is defined and go strait to setup. + if (!$force && $config["db.default.host"] != "" && $config["db.default.database"] != "" && $config["db.default.username"] != "") { + $this->io->note("File `{$this->envPath}` was not found, but some database configuration variables are present. Global system environment variables might be defined. If this is not right, use -f option to force setup to run."); + return; + } + + //Goto setup + $this->setupEnv(); + } + + /** + * Setup the `.env` file. + * + * @access public + * @return void + */ + public function setupEnv() + { + // Get config + $config = $this->ci->config; + + // Get the db driver choices + $drivers = $this->databaseDrivers(); + + + // Ask the questions + $this->io->section("Setting up database"); + $this->io->note("Database credentials will be saved in `app/.env`"); + + $driver = $this->io->choice("Database type", $drivers->pluck('name')->toArray()); + $driver = $drivers->where('name', $driver)->first(); + + $driverName = $driver['driver']; + $defaultDBName = $driver['defaultDBName']; + + if ($driverName == 'sqlite') { + $name = $this->io->ask("Database name", $defaultDBName); + + $dbParams = [ + 'driver' => $driverName, + 'database' => $name + ]; + } else { + $defaultPort = $driver['defaultPort']; + + $host = $this->io->ask("Hostname", "localhost"); + $port = $this->io->ask("Port", $defaultPort); + $name = $this->io->ask("Database name", $defaultDBName); + $user = $this->io->ask("Username", "userfrosting"); + $password = $this->io->askHidden("Password", function ($password) { + // Use custom validator to accept empty password + return $password; + }); + + $dbParams = [ + 'driver' => $driverName, + 'host' => $host, + 'port' => $port, + 'database' => $name, + 'username' => $user, + 'password' => $password, + 'charset' => $config['db.default.charset'] + ]; + } + + // Setup a new db connection + $capsule = new Capsule; + $capsule->addConnection($dbParams); + + // Test the db connexion. + try { + $conn = $capsule->getConnection(); + $conn->getPdo(); + $this->io->success("Database connection successful"); + $success = true; + } catch (\PDOException $e) { + $message = "Could not connect to the database '{$dbParams['username']}@{$dbParams['host']}/{$dbParams['database']}':".PHP_EOL; + $message .= "Exception: " . $e->getMessage() . PHP_EOL.PHP_EOL; + $message .= "Please check your database configuration and/or google the exception shown above and run the command again."; + $this->io->error($message); + exit(1); + } + + // Ask for the smtp values now + $this->io->section("Enter your SMTP credentials"); + $this->io->write("This is used to send emails from the system. Edit `app/.env` if you have problems with this later."); + $smtpHost = $this->io->ask("SMTP Host", "host.example.com"); + $smtpUser = $this->io->ask("SMTP User", "relay@example.com"); + $smtpPassword = $this->io->askHidden("SMTP Password", function ($password) { + // Use custom validator to accept empty password + return $password; + }); + + if ($driverName == 'sqlite') { + $fileContent = [ + "UF_MODE=\"\"\n", + "DB_DRIVER=\"{$dbParams['driver']}\"\n", + "DB_NAME=\"{$dbParams['database']}\"\n", + "SMTP_HOST=\"$smtpHost\"\n", + "SMTP_USER=\"$smtpUser\"\n", + "SMTP_PASSWORD=\"$smtpPassword\"\n" + ]; + } else { + $fileContent = [ + "UF_MODE=\"\"\n", + "DB_DRIVER=\"{$dbParams['driver']}\"\n", + "DB_HOST=\"{$dbParams['host']}\"\n", + "DB_PORT=\"{$dbParams['port']}\"\n", + "DB_NAME=\"{$dbParams['database']}\"\n", + "DB_USER=\"{$dbParams['username']}\"\n", + "DB_PASSWORD=\"{$dbParams['password']}\"\n", + "SMTP_HOST=\"$smtpHost\"\n", + "SMTP_USER=\"$smtpUser\"\n", + "SMTP_PASSWORD=\"$smtpPassword\"\n" + ]; + } + + // Let's save this config + file_put_contents($this->envPath, $fileContent); + + // At this point, `$this->uf` is still using the old configs. + // We need to refresh the `db.default` config values + $newConfig = array_merge($config['db.default'], $dbParams); + $this->ci->config->set("db.default", $newConfig); + } + + /** + * Return the database choices for the env setup. + * + * @access protected + * @return void + */ + protected function databaseDrivers() + { + return collect([ + [ + "driver" => "mysql", + "name" => "MySQL / MariaDB", + "defaultDBName" => "userfrosting", + "defaultPort" => 3306 + ], + [ + "driver" => "pgsql", + "name" => "ProgreSQL", + "defaultDBName" => "userfrosting", + "defaultPort" => 5432 + ], + [ + "driver" => "sqlsrv", + "name" => "SQL Server", + "defaultDBName" => "userfrosting", + "defaultPort" => 1433 + ], + [ + "driver" => "sqlite", + "name" => "SQLite", + "defaultDBName" => \UserFrosting\DB_DIR . \UserFrosting\DS . 'userfrosting.db', + "defaultPort" => null + ] + ]); + } +} |