defineEnvironment(); $instance->startInitialization(); if ($instance->askInitDb()) { do { $instance->defineDb(); } while (!$instance->databaseCheck()); $instance->migrate(); $instance->createUser(); $instance->congratulate(); } } /** * Get instance of Initializer * * @return mixed */ public static function getInstance(): Initializer { if (empty( self::$instance )) { self::$instance = new self(); } return self::$instance; } /** * Initializer private constructor. You can get Singleton with getInstance() * * Availiable options: * * --env - One of available environments * * --overwrite - Do overwrite all files without confirmation * * --dbinit - Initialize database after app initialization * * --dbtype - Database type. Available: postgresql, mysql * * --host - Database host, default to 127.0.0.1 * * --port - Database port used by postgresql, default to 5432 * * --schema - Database schema for postresql, default to public * * --dbname - Database name, required * * --username - Database username, required * * --password - Database password, required * * --migrationPath - Migration path, default to vendor/artweb/artbox-core/migrations * * --migrate - Whether to migrate, default to apply, set no to skip migration * * --user_username - Username for user creation * * --user_email - Email for user creation * * --user_password - Password for user creation * * --user - Whether to create user, default to yes, set no to skip creation * * --defaultuser - Whether to use default user creation * * --o - Webpage to open after intallaction process * * --fun - Run HOLLYWOOD BABY!!! * * --phppath - Path to execute php script * * @see Initializer::getInstance() */ private function __construct() { echo $this->formatMessage( "\tArtbox Application Initialization Tool v" . self::VERSION, [ 'bold' ] ) . "\n\n"; } /** * Define environment for an application * * @return string */ private function defineEnvironment() { $envName = $this->getParamValue('env'); $envs = $this->getEnvironmentNames(); if (empty( $envName ) || $envName === '1') { do { $envName = $this->askEnvironment($envs); echo "\n Initialize the application under '{$envName}' environment? [yes|no] "; $answer = trim(fgets(STDIN)); } while (strncasecmp($answer, 'y', 1)); } else { if (!in_array($envName, $envs)) { $this->printError("Wrong environment name, available list: " . implode(', ', $envs)); exit( 1 ); } } $this->environment = $this->envs[ $envName ]; return $this->environment; } /** * Start actual application initialization with files overwriting */ private function startInitialization() { echo "\n Start initialization\n"; echo " =====================\n"; $this->rewriteFiles(); $this->callback(); echo "\n App initialization completed\n"; echo " ==============================\n"; } /** * Ask whether to init databse. If dbinit param is set, this step will be skipped. * * @return bool */ private function askInitDb(): bool { echo " Start database initialization\n"; $params = $this->getParams(); if (!isset( $params[ 'dbinit' ] )) { do { echo $this->formatMessage("\n Init the database? [yes|no] ", [ 'bold' ]); $answer = trim(fgets(STDIN)); } while (( strncasecmp($answer, 'y', 1) !== 0 ) && ( strncasecmp($answer, 'n', 1) !== 0 )); if (strncasecmp($answer, 'n', 1) == 0) { $this->noDatabaseMessage(); } } return true; } /** * Define which database driver to use. Available options: postgresql, mysql */ private function defineDb() { $params = $this->getParams(); if (isset( $params[ 'dbinit' ] )) { $this->validateConnection(); } else { $answer = ''; do { if (!empty( $answer )) { $this->printError("Incorrect database type. Try again or write 'quit' to exit"); } echo "\n Which database do you want to use? [postgresql|mysql] "; $answer = trim(fgets(STDIN)); } while (( strncasecmp($answer, 'q', 1) !== 0 ) && ( !in_array( $answer, [ 'postgresql', 'mysql', 'p', 'm', ] ) )); if (strncasecmp($answer, 'q', 1) === 0) { $this->noDatabaseMessage(); } if (strncasecmp($answer, 'p', 1) === 0) { $answer = 'postgresql'; } else { $answer = 'mysql'; } if ($answer == 'postgresql') { $this->initPostgres(); } else { $this->initMysql(); } } $this->initDb(); } /** * Get parsed params * * @see Initializer::parseParams() * * @return array */ private function getParams(): array { if (empty( $this->params )) { $this->parseParams(); } return $this->params; } /** * Get params from input string * For example * * **php init test --param1=value1 --param2=value2** * * will get * * ** * [ * test, * value1, * value2 * ] * * * @return array */ private function parseParams(): array { $rawParams = []; if (isset( $_SERVER[ 'argv' ] )) { $rawParams = $_SERVER[ 'argv' ]; array_shift($rawParams); } $params = []; foreach ($rawParams as $param) { if (preg_match('/^--(\w+)(=(.*))?$/', $param, $matches)) { $name = $matches[ 1 ]; $params[ $name ] = isset( $matches[ 3 ] ) ? $matches[ 3 ] : true; } else { $params[] = $param; } } $this->params = $params; return $this->params; } /** * Get value of input param. Empty string if not exist. * * @param string $name * * @return string */ private function getParamValue(string $name): string { $params = $this->getParams(); if (isset( $params[ $name ] ) && !empty( $params[ $name ] )) { return $params[ $name ]; } else { return ''; } } /** * Get project root directory according to file system * * @return mixed */ private function getRoot(): string { if (empty( $this->root )) { $this->root = str_replace('\\', '/', __DIR__); } return $this->root; } /** * Get available environments from environments/index.php file * * Follow environments/index.php manifest to create your own environments * * @return array */ private function getEnvironments(): array { $path = "{$this->getRoot()}/environments/index.php"; if (empty( $this->envs )) { /** @noinspection PhpIncludeInspection */ $this->envs = require( $path ); } if (empty( $this->envs )) { die( "There are no available environments in $path" ); } return $this->envs; } /** * Get environment names * * @return array */ private function getEnvironmentNames(): array { return array_keys($this->getEnvironments()); } /** * Show user variants to choose environment from * * @param array $envs * * @return string */ private function askEnvironment(array $envs): string { echo "Which environment do you want the application to be initialized in?\n\n"; foreach ($envs as $i => $name) { echo " [$i] $name\n"; } $answer = $this->offerEnvironment(count($envs)); while (!( ( ctype_digit($answer) && in_array($answer, range(0, count($envs) - 1)) ) || $answer === 'q' )) { $answer = $this->offerEnvironment(count($envs)); } if ($answer === 'q') { echo "\n Quit initialization.\n"; exit( 0 ); } else { if (isset( $envs[ $answer ] )) { $envName = $envs[ $answer ]; } else { die( "Error while trying to get environment name. Try another one." ); } } return $envName; } /** * Offer user to choose environment number * * @param int $count * * @return string */ private function offerEnvironment(int $count): string { echo "\n Your choice [0-" . ( $count - 1 ) . ', or "q" to quit] '; return trim(fgets(STDIN)); } /** * Rewrite files by files in environments/$environment['path'] */ private function rewriteFiles() { $environment = $this->environment; $root = $this->getRoot(); if (isset( $environment[ 'path' ] ) && !empty( $environment[ 'path' ] )) { $path = $environment[ 'path' ]; } else { $this->printError('Environment configuration failed. Please set path value.'); exit( 1 ); } $files = $this->getFileList("$root/environments/$path"); if (isset( $environment[ 'skipFiles' ] )) { $skipFiles = $environment[ 'skipFiles' ]; array_walk( $skipFiles, function (&$value) use ($root) { $value = "$root/$value"; } ); $files = array_diff( $files, array_intersect_key( $environment[ 'skipFiles' ], array_filter($skipFiles, 'file_exists') ) ); } $all = false; foreach ($files as $file) { if (!$this->copyFile("environments/{$path}/$file", $file, $all)) { break; } } } /** * Recursively get all files from $root directory. * * This will ignore .git, .svn directories. * * @param string $root * @param string $basePath * * @return array */ private function getFileList(string $root, string $basePath = ''): array { $files = []; $handle = opendir($root); while (( $path = readdir($handle) ) !== false) { if ($path === '.git' || $path === '.svn' || $path === '.' || $path === '..') { continue; } $fullPath = "$root/$path"; $relativePath = $basePath === '' ? $path : "$basePath/$path"; if (is_dir($fullPath)) { $files = array_merge($files, $this->getFileList($fullPath, $relativePath)); } else { $files[] = $relativePath; } } closedir($handle); return $files; } /** * Run callbacks for application initialization */ private function callback() { $environment = $this->environment; foreach (self::CALLBACKS as $callback) { if (!empty( $environment[ $callback ] )) { $this->$callback($environment[ $callback ]); } } } /** * Set directories in $environment['setWrotable'] to chmod 0777 * * @param $paths */ private function setWritable(array $paths) { $root = $this->getRoot(); foreach ($paths as $writable) { $fullPath = "$root/$writable"; if (is_dir($fullPath)) { if (@chmod($fullPath, 0777)) { echo $this->formatMessage( " ***** Set writable $writable (chmod 0777)", [ 'fg-yellow' ] ) . "\n"; } else { $this->printError("Operation chmod not permitted for directory $writable."); } } else { if (!@mkdir($fullPath, 0777, true)) { $this->printError("Directory $writable does not exist and cannot be created."); } } } } /** * Set files in $environment['setExecutable'] to chmod 0755 * * @param $paths */ private function setExecutable(array $paths) { $root = $this->getRoot(); foreach ($paths as $executable) { $fullPath = "$root/$executable"; if (file_exists($fullPath)) { if (@chmod($fullPath, 0755)) { echo $this->formatMessage(" ***** Set executable $executable (chmod 0755)") . "\n"; } else { $this->printError("Operation chmod not permitted for $executable."); } } else { $this->printError("$executable does not exist."); } } } /** * Set cookie validation keys to files in $environment['setCookieValidationKey']. * * @param $paths */ private function setCookieValidationKey(array $paths) { $root = $this->getRoot(); foreach ($paths as $file) { echo $this->formatMessage( " ***** Generate cookie validation key in $file", [ 'bold', 'fg-magenta', ] ) . "\n"; $file = $root . '/' . $file; $length = 32; $bytes = openssl_random_pseudo_bytes($length); $key = strtr(substr(base64_encode($bytes), 0, $length), '+/=', '_-.'); $this->setParam('cookieValidationKey', $key, $file); } } private function createSymlink(array $links) { $root = $this->getRoot(); foreach ($links as $link => $target) { //first removing folders to avoid errors if the folder already exists @rmdir($root . "/" . $link); //next removing existing symlink in order to update the target if (is_link($root . "/" . $link)) { @unlink($root . "/" . $link); } if (@symlink($root . "/" . $target, $root . "/" . $link)) { echo $this->formatMessage(" ***** Symlink $root/$target $root/$link", [ 'fg-blue' ]) . "\n"; } else { $this->printError("Cannot create symlink $root/$target $root/$link."); } } } /** * Copy file from environment directory to project directory * * @param string $source Environment source file path * @param string $target Project file path target * @param bool $all Rewrite all flag * * @return bool */ private function copyFile(string $source, string $target, bool &$all) { $root = $this->getRoot(); $params = $this->getParams(); if (!is_file($root . '/' . $source)) { echo $this->formatMessage(" ----- skip $target ($source not exist)", [ 'fg-cyan' ]) . "\n"; return true; } if (is_file($root . '/' . $target)) { if (file_get_contents($root . '/' . $source) === file_get_contents($root . '/' . $target)) { echo $this->formatMessage(" ----- unchanged $target", [ 'fg-cyan' ]) . "\n"; return true; } if ($all) { echo $this->formatMessage(" ----- overwrite $target", [ 'fg-blue' ]) . "\n"; } else { echo $this->formatMessage(" -- exist $target", [ 'fg-magenta' ]) . "\n"; echo " overwrite? [Yes|No|All|Quit] "; $answer = !empty( $params[ 'overwrite' ] ) ? $params[ 'overwrite' ] : trim(fgets(STDIN)); echo "\n"; if (!strncasecmp($answer, 'q', 1)) { return false; } else { if (!strncasecmp($answer, 'y', 1)) { echo $this->formatMessage(" ----- overwrite $target", [ 'fg-blue' ]) . "\n"; } else { if (!strncasecmp($answer, 'a', 1)) { echo $this->formatMessage(" ----- overwrite $target", [ 'fg-blue' ]) . "\n"; $all = true; } else { echo $this->formatMessage( " ----- skip $target ($source not exist)", [ 'fg-cyan' ] ) . "\n"; return true; } } } } file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source)); return true; } echo "\n" . $this->formatMessage(" ----- generate $target", [ 'fg-green' ]) . "\n"; @mkdir(dirname($root . '/' . $target), 0777, true); file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source)); return true; } /** * Set param in file to particular value. * * For example: setParam('param', 'value', 'config.php') will replace content in config.php * * from * * 'param' => '' * * to * * 'param' => 'value' * * @param string $param * @param string $value * @param string $file * @param bool $noQuote * @param bool $force * @param bool $alternate */ private function setParam( string $param, string $value, string $file, bool $noQuote = false, bool $force = false, bool $alternate = false ) { if ($alternate) { $regexp = '/(("|\')db("|\')\s*=>\s*)(.*|.*)/'; } else { if ($force) { $regexp = '/(("|\')' . $param . '("|\')\s*=>\s*)(".*"|\'.*\')/'; } else { $regexp = '/(("|\')' . $param . '("|\')\s*=>\s*)(""|\'\')/'; } } if ($noQuote) { $content = preg_replace( $regexp, "\\1$value", file_get_contents($file) ); } else { $content = preg_replace( $regexp, "\\1'$value'", file_get_contents($file) ); } file_put_contents($file, $content); } /** * Init postgres connection * * @return array */ private function initPostgres(): array { $db = [ 'dbtype' => 'postgresql', ]; echo "\n Enter your database host: "; $host = trim(fgets(STDIN)); echo "\n Enter your database port: "; $port = trim(fgets(STDIN)); echo "\n Enter your database schema: "; $db[ 'schema' ] = trim(fgets(STDIN)); echo "\n Enter your database name: "; $name = trim(fgets(STDIN)); echo "\n Enter your database username: "; $db[ 'username' ] = trim(fgets(STDIN)); echo "\n Enter your database password: "; $db[ 'password' ] = trim(fgets(STDIN)); $db[ 'dsn' ] = "pgsql:host={$host};port={$port};dbname={$name}"; $this->db = $db; return $db; } /** * Init mysql connection * * @return array */ private function initMysql(): array { $db = [ 'dbtype' => 'mysql', ]; echo "\n Enter your database host: "; $host = trim(fgets(STDIN)); echo "\n Enter your database name: "; $name = trim(fgets(STDIN)); echo "\n Enter your database username: "; $db[ 'username' ] = trim(fgets(STDIN)); echo "\n Enter your database password: "; $db[ 'password' ] = trim(fgets(STDIN)); $db[ 'dsn' ] = "mysql:host={$host};dbname={$name}"; $this->db = $db; return $db; } /** * Validate non-interactive db data and fill it for further actions. * * @return array */ private function validateConnection(): array { $db = []; $dbType = strtolower($this->getParamValue('dbtype')); if ($dbType !== 'postgresql' && $dbType !== 'mysql') { die( "Supported DB types are postgresql and mysql" ); } if ($dbType === 'postgresql') { $host = $this->getParamValue('host') ? : '127.0.0.1'; $port = $this->getParamValue('port') ? : '5432'; $db[ 'schema' ] = $this->getParamValue('schema') ? : 'public'; $name = $this->getParamValue('dbname'); if (empty( $name )) { die( "Database name must be set" ); } $db[ 'dsn' ] = "pgsql:host={$host};port={$port};dbname={$name}"; if (empty( $username = $this->getParamValue('username') )) { die( "Database username must be set" ); } $db[ 'username' ] = $username; if (empty( $password = $this->getParamValue('password') )) { die( "Database password must be set" ); } $db[ 'password' ] = $password; } else { $host = $this->getParamValue('host') ? : '127.0.0.1'; $name = $this->getParamValue('dbname'); if (empty( $name )) { die( "Database name must be set" ); } $db[ 'dsn' ] = "mysql:host={$host};dbname={$name}"; if (empty( $username = $this->getParamValue('username') )) { die( "Database username must be set" ); } $db[ 'username' ] = $username; if (empty( $password = $this->getParamValue('password') )) { die( "Database password must be set" ); } $db[ 'password' ] = $password; } $db[ 'dbtype' ] = $dbType; $this->db = $db; return $db; } /** * Copy db connection file accroding to choosen driver */ private function initDb() { if (!empty( $configPath = $this->environment[ 'setDbConnection' ] )) { if (preg_match('/(.*)\/.*/', $configPath, $matches)) { $path = $matches[ 1 ]; } else { $this->printError("Unknown error while trying to init database"); exit( 1 ); } $filename = "db{$this->db['dbtype']}.php"; $all = !empty( $this->getParamValue('overwrite') ) ? false : true; $fullpath = "{$path}/{$filename}"; if ($this->copyFile("environments/{$filename}", $fullpath, $all)) { $this->rewriteDb($fullpath, $configPath); } } } /** * Rewrite params in db config and local config files * * @param string $path * @param string $config */ private function rewriteDb(string $path, string $config) { $db = $this->db; $this->setParam('dsn', $db[ 'dsn' ], $path); $this->setParam('username', $db[ 'username' ], $path); $this->setParam('password', $db[ 'password' ], $path); if ($this->db[ 'dbtype' ] == 'postgresql') { $this->setParam('defaultSchema', $db[ 'schema' ], $path); } $filename = "db{$this->db['dbtype']}.php"; $this->setParam('db', "require('{$filename}')", $config, true, true); $driver = ucfirst($db[ 'dbtype' ]); echo $this->formatMessage( "Database access file $path was created and filled with configurations for database driver {$driver}", [ 'fg-green' ] ) . "\n"; echo $this->formatMessage( "Database access file $path was linked to local config file $config", [ 'fg-green' ] ) . "\n"; echo $this->formatMessage("Database Access: ", [ 'bg-yellow' ]) . $this->formatMessage( $this->db[ 'dsn' ], [ 'bg-yellow', 'fg-blue', ] ) . $this->formatMessage(', username: ', [ 'bg-yellow' ]) . $this->formatMessage( $this->db[ 'username' ], [ 'bg-yellow', 'fg-blue', ] ) . "\n"; echo " Database initialization completed\n"; echo " =================================\n"; } /** * Prints error message. * * @param string $message message */ private function printError(string $message) { echo "\n " . $this->formatMessage( "Error. $message", [ 'fg-red', 'bold', ] ) . " \n"; } /** * Returns true if the stream supports colorization. ANSI colors are disabled if not supported by the stream. * - windows without ansicon * - not tty consoles * * @return boolean true if the stream supports ANSI colors, otherwise false. */ private function ansiColorsSupported(): bool { return DIRECTORY_SEPARATOR === '\\' ? getenv('ANSICON') !== false || getenv( 'ConEmuANSI' ) === 'ON' : function_exists('posix_isatty') && @posix_isatty(STDOUT); } /** * Get ANSI code of style. * * @param string $name style name * * @return integer ANSI code of style. */ private function getStyleCode(string $name): int { $styles = [ 'bold' => 1, 'fg-black' => 30, 'fg-red' => 31, 'fg-green' => 32, 'fg-yellow' => 33, 'fg-blue' => 34, 'fg-magenta' => 35, 'fg-cyan' => 36, 'fg-white' => 37, 'bg-black' => 40, 'bg-red' => 41, 'bg-green' => 42, 'bg-yellow' => 43, 'bg-blue' => 44, 'bg-magenta' => 45, 'bg-cyan' => 46, 'bg-white' => 47, ]; return $styles[ $name ]; } /** * Formats message using styles if STDOUT supports it. * * @param string $message message * @param string[] $styles styles * * @return string formatted message. */ public function formatMessage(string $message, array $styles = []): string { if (empty( $styles ) || !$this->ansiColorsSupported()) { return $message; } return sprintf( "\x1b[%sm", implode( ';', array_map( [ $this, 'getStyleCode', ], $styles ) ) ) . $message . "\x1b[0m"; } /** * Inform that an application initialized without database. Exit code 0, means success. */ private function noDatabaseMessage() { echo $this->formatMessage( "\n Attention: ", [ 'bold', 'fg-red', 'bg-yellow', ] ); echo $this->formatMessage( "Application initialized without database. Set it manually in {$this->getRoot()}/common/config/main-local.php and run migration", [ 'bold', 'bg-yellow', ] ) . "\n"; exit( 0 ); } /** * Perform database migration if input param migrate doesn't set to 'no' */ private function migrate() { $migrate = $this->getParamValue('migrate'); if ($migrate == 'no') { echo $this->formatMessage( "Migration skipped by user. In order to application work correct you will need to run it manually", [ 'bg-yellow', 'bold', ] ) . "\n"; exit( 0 ); } elseif ($migrate != 'yes') { do { echo " Do you want to perform database migration? [yes|no]"; $answer = trim(fgets(STDIN)); } while (strncasecmp($answer, 'y', 1) !== 0 && strncasecmp($answer, 'n', 1) !== 0); if (strncasecmp($answer, 'n', 1) === 0) { echo $this->formatMessage( "Migration skipped by user. In order to application work correct you will need to run it manually", [ 'bg-yellow', 'bold', ] ) . "\n"; exit( 0 ); } } echo $this->formatMessage("Migration begins...", [ 'fg-yellow' ]) . "\n"; $migrationPath = $this->getParamValue('migrationPath'); if (empty( $migrationPath )) { $migrationPath = 'vendor/artweb/artbox-core/migrations'; } $phppath = $this->getParamValue('phppath') ? : 'php'; $result = exec("$phppath yii migrate --migrationPath=$migrationPath --interactive=0", $output, $return); if ($return !== 0) { $this->printError("Migration cannot be applied. Run it manually to check the reason"); exit( 1 ); } $this->writeLine($result); foreach ($output as $value) { $this->writeLine($value); } echo $this->formatMessage("Migration ended successfully", [ 'fg-yellow' ]) . "\n"; } /** * Write line of code followed by new line symbol * * @param string $string */ private function writeLine(string $string) { echo $string . "\n"; } /** * Perform user creation if input param user doesn't set to 'no' */ private function createUser() { $params = $this->getParams(); $phppath = $this->getParamValue('phppath') ? : 'php'; if (!isset( $params[ 'defaultuser' ] )) { if ($this->getParamValue('user') == 'no') { echo $this->formatMessage( "User creation skipped by user. Run command 'php yii user/create' manually to create user.", [ 'bg-yellow', 'bold', ] ) . "\n"; exit( 0 ); } do { echo " Do you want to create user? [yes|no]"; $answer = trim(fgets(STDIN)); } while (strncasecmp($answer, 'y', 1) !== 0 && strncasecmp($answer, 'n', 1) !== 0); if (strncasecmp($answer, 'n', 1) === 0) { echo $this->formatMessage( "User creation skipped by user. Run command 'php yii user/create' manually to create user.", [ 'bg-yellow', 'bold', ] ) . "\n"; exit( 0 ); } echo "\n Enter username: "; $username = trim(fgets(STDIN)); echo "\n Enter email: "; $email = trim(fgets(STDIN)); echo "\n Enter password: "; $password = trim(fgets(STDIN)); echo "\n"; $result = exec("$phppath yii create/user $username $email $password", $output, $return); } else { $result = exec("$phppath yii create/user", $output, $return); } $this->handleUserCreation($result, $output, $return); } /** * Handle user creation result * * @param string $result * @param array $output * @param int $return */ private function handleUserCreation($result, $output, $return) { if ($return !== 0) { $this->printError("User cannot be created. Run 'php yii create/user' manually to check the reason"); exit( 1 ); } $this->writeLine($result); echo $this->formatMessage("User created successfully", [ 'fg-yellow' ]) . "\n"; } /** * Congratulate with successfull installation and optionally open browser */ private function congratulate() { echo "\n" . $this->formatMessage( "Congratulations. Artbox Basic has been successfully installed.", [ 'fg-yellow', 'bold', ] ) . "\n"; $url = $this->getParamValue('o'); if (!empty( $url )) { if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { shell_exec("explorer '{$url}'"); } else { shell_exec("sensible-browser {$url} > /dev/null 2>/dev/null &"); $params = $this->getParams(); if (isset( $params[ 'fun' ] )) { echo shell_exec("hollywood"); } } } } /** * Check if database connection could be established * * @return bool * @throws \Exception */ private function databaseCheck(): bool { $params = $this->getParams(); if (isset( $params[ 'checkdb' ] )) { $configPath = $this->environment[ 'setDbConnection' ]; if (preg_match('/(.*)\/.*/', $configPath, $matches)) { $path = $matches[ 1 ]; } else { $this->printError("Unknown error while trying to check connection"); exit( 1 ); } $filename = "db{$this->db['dbtype']}.php"; $fullpath = "{$path}/{$filename}"; $phppath = $this->getParamValue('phppath') ? : 'php'; exec("$phppath yii check/connection {$fullpath}", $output, $return); if ($return > 0) { if (isset( $params[ 'dbinit' ] )) { throw new Exception("Couldn't connect to the database"); } echo $this->printError("Database unavailable. Please choose another database!"); return false; } } echo $this->formatMessage(" Database connection successful!", [ 'fg-green' ]) . "\n"; return true; } }