. */ /* */ /*************************************************************************************/ namespace Thelia\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Filesystem\Filesystem; use Thelia\Command\ContainerAwareCommand; use Thelia\Install\CheckPermission; use Thelia\Install\Database; /** * try to install a new instance of Thelia * * Class Install * @package Thelia\Command * @author Manuel Raynaud */ class Install extends ContainerAwareCommand { /** * Configure the command */ protected function configure() { $this ->setName("thelia:install") ->setDescription("Install thelia using cli tools. For now Thelia only use mysql database") ->setHelp("The thelia:install command install Thelia database and create config file needed.") ->addOption( "db_host", null, InputOption::VALUE_OPTIONAL, "host for your database" ) ->addOption( "db_username", null, InputOption::VALUE_OPTIONAL, "username for your database" ) ->addOption( "db_password", null, InputOption::VALUE_OPTIONAL, "password for your database" ) ->addOption( "db_name", null, InputOption::VALUE_OPTIONAL, "database name" ) ; } protected function execute(InputInterface $input, OutputInterface $output) { $output->writeln(array( '', 'Welcome to Thelia install process', 'You need information about your database configuration (host, username, password, database name, etc)', '', 'Caution : You are installing Thelia in cli mode, we verify some information, but this information are only available for the cli php sapi', 'This informations can be different in your apache or cgi php.ini files', '' )); $this->checkPermission($output); $connectionInfo = array( "host" => $input->getOption("db_host"), "dbName" => $input->getOption("db_name"), "username" => $input->getOption("db_username"), "password" => $input->getOption("db_password") ); while (false === $connection = $this->tryConnection($connectionInfo, $output)) { $connectionInfo = $this->getConnectionInfo($input, $output); } $database = new Database($connection); $database->createDatabase($connectionInfo["dbName"]); $output->writeln(array( "", "Creating Thelia database, please wait", "" )); $database->insertSql($connectionInfo["dbName"]); $output->writeln(array( "", "Database created without errors", "Creating file configuration, please wait", "" )); $this->createConfigFile($connectionInfo); $output->writeln(array( "", "Config file created with success. Your thelia is installed", "" )); } /** * Test if needed directories have write permission * * @param \Symfony\Component\Console\Output\OutputInterface $output */ protected function checkPermission(OutputInterface $output) { $output->writeln(array( "Checking some permissions" )); $permissions = new CheckPermission(false, $this->getContainer()->get('thelia.translator')); $isValid = $permissions->exec(); foreach ($permissions->getValidationMessages() as $item => $data) { if ($data['status']) { $output->writeln(array( sprintf("%s ... %s", $data['text'], "Ok") ) ); } else { $output->writeln(array( sprintf("%s %s", $data['text'], sprintf("%s", $data["hint"]) ) )); } } if (false === $isValid) { $output->writeln(array( "", "Please put correct permissions and reload install process" )); exit; } } /** * rename database config file and complete it * * @param array $connectionInfo */ protected function createConfigFile($connectionInfo) { $fs = new Filesystem(); $sampleConfigFile = THELIA_CONF_DIR . "database.yml.sample"; $configFile = THELIA_CONF_DIR . "database.yml"; $fs->copy($sampleConfigFile, $configFile, true); $configContent = file_get_contents($configFile); $configContent = str_replace("%DRIVER%", "mysql", $configContent); $configContent = str_replace("%USERNAME%", $connectionInfo["username"], $configContent); $configContent = str_replace("%PASSWORD%", $connectionInfo["password"], $configContent); $configContent = str_replace( "%DSN%", sprintf("mysql:host=%s;dbname=%s", $connectionInfo["host"], $connectionInfo["dbName"]), $configContent ); file_put_contents($configFile, $configContent); // FA - no, as no further install will be possible // $fs->remove($sampleConfigFile); $fs->remove($this->getContainer()->getParameter("kernel.cache_dir")); } /** * test database access * * @param $connectionInfo * @param OutputInterface $output * @return bool|\PDO */ protected function tryConnection($connectionInfo, OutputInterface $output) { if (is_null($connectionInfo["dbName"])) { return false; } $dsn = "mysql:host=%s"; try { $connection = new \PDO( sprintf($dsn, $connectionInfo["host"]), $connectionInfo["username"], $connectionInfo["password"] ); $connection->query('SET NAMES \'UTF8\''); } catch (\PDOException $e) { $output->writeln(array( "Wrong connection information" )); return false; } return $connection; } /** * Ask to user all needed information * * @param InputInterface $input * @param OutputInterface $output * @return array */ protected function getConnectionInfo(InputInterface $input, OutputInterface $output) { $dialog = $this->getHelperSet()->get('dialog'); $connectionInfo = array(); $connectionInfo["host"] = $dialog->askAndValidate( $output, $this->decorateInfo("Database host : "), function ($answer) { $answer = trim($answer); if (is_null($answer)) { throw new \RuntimeException("You must specify a database host"); } return $answer; } ); $connectionInfo["dbName"] = $dialog->askAndValidate( $output, $this->decorateInfo("Database name (if database does not exist, Thelia will try to create it) : "), function ($answer) { $answer = trim($answer); if (is_null($answer)) { throw new \RuntimeException("You must specify a database name"); } return $answer; } ); $connectionInfo["username"] = $dialog->askAndValidate( $output, $this->decorateInfo("Database username : "), function ($answer) { $answer = trim($answer); if (is_null($answer)) { throw new \RuntimeException("You must specify a database username"); } return $answer; } ); $connectionInfo["password"] = $dialog->askHiddenResponse( $output, $this->decorateInfo("Database password : ") ); return $connectionInfo; } protected function decorateInfo($text) { return sprintf("%s", $text); } }