diff --git a/src/ChamiloLMS/Command/Database/InstallCommand.php b/src/ChamiloLMS/Command/Database/InstallCommand.php new file mode 100644 index 0000000000..4d3b7725f1 --- /dev/null +++ b/src/ChamiloLMS/Command/Database/InstallCommand.php @@ -0,0 +1,282 @@ +setName('chamilo:install') + ->setDescription('Execute a Chamilo installation to a specified version') + ->addArgument('version', InputArgument::OPTIONAL, 'The version to migrate to.', null) + ->addOption('path', null, InputOption::VALUE_OPTIONAL, 'The path to the chamilo folder'); + } + + /** + * Gets the configuration folder + * + * @return string + */ + public function getConfigurationFile() + { + return api_get_path(SYS_PATH).'main/inc/conf/'; + } + + /** + * Gets the installation version path + * + * @param string $version + * + * @return string + */ + public function getInstallationPath($version) + { + return api_get_path(SYS_PATH).'main/install/'.$version.'/'; + } + + + /** + * Executes a command via CLI + * + * @param Console\Input\InputInterface $input + * @param Console\Output\OutputInterface $output + * + * @return int|null|void + */ + protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output) + { + $configurationPath = $this->getConfigurationFile(); + + $dialog = $this->getHelperSet()->get('dialog'); + + $version = $input->getArgument('version'); + $defaultVersion = $this->getLatestVersion(); + + if (empty($version)) { + $version = $defaultVersion; + } + + $output->writeln("Welcome to the Chamilo installation process!"); + + if (!is_writable($configurationPath)) { + $output->writeln("Folder ".$configurationPath." must be writable"); + } + + $sqlFolder = $this->getInstallationPath($version); + + if (!is_dir($sqlFolder)) { + $output->writeln("Sorry you can't install Chamilo :( Installation files for version $version does not exists: ".$sqlFolder); + + return false; + } + + /*if (!$dialog->askConfirmation( + $output, + 'You are about to install Chamilo $version here:'.$configurationPath.' Are you sure?(y/N)', + false + ) + ) { + return; + }*/ + + /* + if (file_exists($configurationPath.'configuration.php') || file_exists($configurationPath.'configuration.yml')) { + if (!$dialog->askConfirmation( + $output, + 'There is a Chamilo installation located here: '.$configurationPath.' Are you sure you want to continue?(y/N)', + false + ) + ) { + return; + } + }*/ + + //Getting default configuration parameters + require_once api_get_path(SYS_PATH).'main/install/configuration.dist.yml.php'; + + $avoidVariables = array( + 'db_glue', + 'code_append', + 'course_folder', + 'db_admin_path', + 'cdn_enable', + 'verbose_backup', + 'session_stored_in_db', + 'session_lifetime', + 'software_name', + 'software_url', + 'deny_delete_users', + 'system_version', + 'system_stable' + ); + + $newConfigurationArray = array(); + foreach ($_configuration as $key => $value) { + if (in_array($key, $avoidVariables)) { + $newConfigurationArray[$key] = $value; + continue; + } + if (!is_array($value)) { + $data = $dialog->ask( + $output, + "Please enter the value of the $key ($value): ", + $value + ); + $newConfigurationArray[$key] = $data; + } else { + $newConfigurationArray[$key] = $value; + } + } + + //Installing database + $result = $this->install($version, $newConfigurationArray, $output); + + if ($result) { + $this->createAdminUser($newConfigurationArray, $output); + $this->writeConfiguration($newConfigurationArray, $version); + $output->writeln("Database installation finished!"); + } + } + + /** + * + * @param $newConfigurationArray + * @param $output + * @return bool + */ + public function createAdminUser($newConfigurationArray, $output) + { + $dialog = $this->getHelperSet()->get('dialog'); + + //Creating admin user + $output->writeln("Chamilo was successfully installed visit: ".$newConfigurationArray['root_web']); + + $adminUser = array( + 'lastname' => 'Julio', + 'firstname' => 'M', + 'username' => 'admin', + 'password' => 'admin', + 'email' => 'admin@example.org' + ); + + $output->writeln("Creating an admin User"); + $userInfo = array(); + foreach ($adminUser as $key => $value) { + $data = $dialog->ask( + $output, + "Please enter the $key ($value): ", + $value + ); + $userInfo[$key] = $data; + } + $userInfo = \UserManager::add($userInfo); + if ($userInfo && isset($userInfo['user_id'])) { + $userId = $userInfo['user_id']; + \UserManager::add_user_as_admin($userInfo['user_id']); + $output->writeln("User admin created with id: $userId"); + + return true; + } + + return false; + } + + /** + * @return string + */ + public function getLatestVersion() + { + return '1.10'; + } + + /** + * Writes the configuration file a yml file + * @param $newConfigurationArray + * @param $version + */ + public function writeConfiguration($newConfigurationArray, $version) + { + $configurationPath = $this->getConfigurationFile(); + + $newConfigurationArray['system_version'] = $version; + $dumper = new Dumper(); + $yaml = $dumper->dump($newConfigurationArray, 2); //inline + $newConfigurationFile = $configurationPath.'configuration.yml'; + file_put_contents($newConfigurationFile, $yaml); + } + + /** + * Installs Chamilo + * + * @param string $version + * @param array $_configuration + * @param $output + * @return bool + */ + public function install($version, $_configuration, $output) + { + $sqlFolder = $this->getInstallationPath($version); + $output->writeln("Creating database ... "); + + $result = $this->createDatabase($_configuration); + + //Importing files + if ($result) { + $command = $this->getApplication()->find('dbal:import'); + + $arguments = array( + 'command' => 'dbal:import', + 'file' => array( + $sqlFolder.'db_main.sql', + $sqlFolder.'db_stats.sql', + $sqlFolder.'db_user.sql', + $sqlFolder.'db_course.sql', + ) + ); + $input = new ArrayInput($arguments); + $command->run($input, $output); + + //Getting extra information about the installation + $result = \Database::query("SELECT selected_value FROM ".\Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT)." WHERE variable = 'chamilo_database_version'"); + $result = \Database::fetch_array($result); + + $output->writeln("Showing chamilo_database_version value: ".$result['selected_value']); + + return true; + } + } + + /** + * Creates a Database + * @todo use doctrine? + * + * @return resource + */ + public function createDatabase($_configuration) + { + /* + $command = $this->getApplication()->find('orm:schema-tool:create'); + $arguments = array( + 'command' => 'orm:schema-tool:create', + ); + $input = new ArrayInput($arguments); + $command->run($input, $output); + exit; + */ + return \Database::query("CREATE DATABASE IF NOT EXISTS ".mysql_real_escape_string($_configuration['main_database'])." DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci"); + } +} \ No newline at end of file diff --git a/src/ChamiloLMS/Command/Database/StatusCommand.php b/src/ChamiloLMS/Command/Database/StatusCommand.php new file mode 100644 index 0000000000..037d73c120 --- /dev/null +++ b/src/ChamiloLMS/Command/Database/StatusCommand.php @@ -0,0 +1,58 @@ +setName('chamilo:status') + ->setDescription('Show the information of the current Chamilo installation') + ->addOption('configuration', null, InputOption::VALUE_OPTIONAL, 'The path to a migrations configuration file.'); + } + + + /** + * Executes a command via CLI + * + * @param Console\Input\InputInterface $input + * @param Console\Output\OutputInterface $output + * @return int|null|void + */ + protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output) + { + global $_configuration; + + if (!isset($_configuration['root_sys'])) { + $output->writeln("Chamilo is not installed here!"); + exit; + } + + $configurationPath = api_get_path(SYS_PATH).'main/inc/conf/'; + + $query = "SELECT selected_value FROM settings_current WHERE variable = 'chamilo_database_version'"; + $conn = $this->getHelper('main_database')->getConnection(); + $data = $conn->executeQuery($query); + $data = $data->fetch(); + + $chamiloVersion = $data['selected_value']; + $output->writeln('Chamilo status'); + $output->writeln("Chamilo configuration path: ".$configurationPath.""); + + $output->writeln('Chamilo $_configuration[system_version]: '.$_configuration['system_version'].''); + $output->writeln("Chamilo setting: 'chamilo_database_version': ".$chamiloVersion.""); + } + +} + diff --git a/src/ChamiloLMS/Command/Database/MigrationCommand.php b/src/ChamiloLMS/Command/Database/UpgradeCommand.php similarity index 75% rename from src/ChamiloLMS/Command/Database/MigrationCommand.php rename to src/ChamiloLMS/Command/Database/UpgradeCommand.php index 106746f49f..e87242e354 100644 --- a/src/ChamiloLMS/Command/Database/MigrationCommand.php +++ b/src/ChamiloLMS/Command/Database/UpgradeCommand.php @@ -13,23 +13,31 @@ use Doctrine\DBAL\Migrations\Tools\Console\Command\AbstractCommand; /** * Class MigrationCommand */ -class MigrationCommand extends AbstractCommand +class UpgradeCommand extends AbstractCommand { protected function configure() { $this - ->setName('migrations:migrate_chamilo') + ->setName('chamilo:upgrade') ->setDescription('Execute a chamilo migration to a specified version or the latest available version.') ->addArgument('version', InputArgument::REQUIRED, 'The version to migrate to.', null) ->addOption('dry-run', null, InputOption::VALUE_NONE, 'Execute the migration as a dry run.') ->addOption('configuration', null, InputOption::VALUE_OPTIONAL, 'The path to a migrations configuration file.'); } + /** + * Gets the min version available to migrate + * @return mixed + */ public function getMinVersionSupportedByInstall() { return key($this->availableVersions()); } + /** + * Gets an array with the supported Chamilo versions to migrate + * @return array + */ public function getVersionNumberList() { $versionList = $this->availableVersions(); @@ -37,9 +45,15 @@ class MigrationCommand extends AbstractCommand foreach ($versionList as $version => $info) { $versionNumberList[] = $version; } + return $versionNumberList; } + /** + * Gets an array with the settings for every supported version + * + * @return array + */ public function availableVersions() { $versionList = array( @@ -72,6 +86,14 @@ class MigrationCommand extends AbstractCommand return $versionList; } + /** + * + * Gets the content of a version from the available versions + * + * @param $version + * + * @return bool + */ public function getAvailableVersionInfo($version) { $versionList = $this->availableVersions(); @@ -83,8 +105,35 @@ class MigrationCommand extends AbstractCommand return false; } + /** + * Executes a command via CLI + * + * @param Console\Input\InputInterface $input + * @param Console\Output\OutputInterface $output + * @return int|null|void + */ protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output) { + global $_configuration; + + if (!isset($_configuration['root_sys'])) { + $output->writeln("Chamilo is not installed here!"); + exit; + } + + $configurationPath = api_get_path(SYS_PATH).'main/inc/conf/'; + + //Checking configuration file + if (!is_writable($configurationPath)) { + $output->writeln("Folder ".$configurationPath." must have writable permissions"); + } + + //Getting chamilo_database_version + /*$conn = $this->getHelper('main_database')->getConnection(); + $data = $conn->executeQuery("SELECT selected_value FROM settings_current WHERE variable = 'chamilo_database_version'"); + $data = $data->fetch(); + $versionFromDB = $data['selected_value'];*/ + $version = $input->getArgument('version'); $dryRun = $input->getOption('dry-run'); $minVersion = $this->getMinVersionSupportedByInstall(); @@ -110,34 +159,43 @@ class MigrationCommand extends AbstractCommand global $_configuration; $currentVersion = null; - //Checking root_sys and correct Chamilo version to install + //Checking root_sys and correct Chamilo version to install if (!isset($_configuration['root_sys'])) { $output->writeln("Can't migrate Chamilo. This is not a Chamilo folder installation."); } - if (isset($_configuration['system_version']) && - !empty($_configuration['system_version']) && - $_configuration['system_version'] > $minVersion && - $version > $_configuration['system_version'] - ) { + //Checking system_version + + + if (!isset($_configuration['system_version']) || empty($_configuration['system_version'])) { + $output->writeln("You have something wrong in your Chamilo installation check it with chamilo:status."); + exit; + } + + if (version_compare($_configuration['system_version'], $minVersion, '<')) { + $output->writeln("Your Chamilo version is not supported! The minimun version is: $minVersion You want to update from ".$_configuration['system_version']." to $minVersion"); + exit; + } + + if (version_compare($version, $_configuration['system_version'], '>')) { $currentVersion = $_configuration['system_version']; } else { - $output->writeln("Please provide a version greater than your current installation > ".$_configuration['system_version'].""); + $output->writeln("Please provide a version greater than ".$_configuration['system_version']." your selected version: $version"); + $output->writeln("You can also check your installation health's with chamilo:status"); exit; } $versionInfo = $this->getAvailableVersionInfo($version); - if (isset($versionInfo['hook_to_version']) && isset($doctrineVersion)) { if ($doctrineVersion == $versionInfo['hook_to_version']) { - $output->writeln("Nothing to update!"); + $output->writeln("You already have the latest version. Nothing to update!"); exit; } } - + $output->writeln("Welcome to the Chamilo upgrade CLI!"); //Too much questions? @@ -164,11 +222,11 @@ class MigrationCommand extends AbstractCommand $output->writeln('Migrating from Chamilo version: '.$_configuration['system_version'].' to version '.$version); //Starting - $output->writeln('Starting migration for Chamilo portal located here: '.$_configuration['root_sys'].''); + $output->writeln('Starting upgrade for Chamilo with configuration file: '.$configurationPath.'configuration.php'); $oldVersion = $currentVersion; foreach ($versionList as $versionItem => $versionInfo) { - if ($versionItem > $currentVersion && $versionItem <= $version) { + if (version_compare($versionItem, $currentVersion, '>') && version_compare($versionItem, $version, '<=')) { if (isset($versionInfo['require_update']) && $versionInfo['require_update'] == true) { //Greater than my current version $this->startMigration($oldVersion, $versionItem, $dryRun, $output); @@ -178,10 +236,12 @@ class MigrationCommand extends AbstractCommand } } } + $output->writeln("wow! You just finish to migrate. Too check the current status of your platform. Execute:chamilo:status"); + } /** - * + * Gets the Doctrine configuration file path * @return string */ public function getMigrationConfigurationFile() @@ -190,8 +250,14 @@ class MigrationCommand extends AbstractCommand } /** - * @param $version + * Starts a migration + * + * @param $fromVersion + * @param $toVersion + * @param $dryRun * @param $output + * + * @return bool */ public function startMigration($fromVersion, $toVersion, $dryRun, $output) { @@ -205,7 +271,9 @@ class MigrationCommand extends AbstractCommand if (file_exists($sqlToInstall)) { //$result = $this->processSQL($sqlToInstall, $dryRun, $output); $result = true; + $output->writeln(""); $output->writeln("Executing file: '$sqlToInstall'"); + $output->writeln("You have to select yes for the 'Chamilo Migrations'"); if ($result) { $command = $this->getApplication()->find('migrations:migrate'); @@ -220,12 +288,15 @@ class MigrationCommand extends AbstractCommand } } } + return false; } /** * - * @param $sqlFilePath - * @param $dryRun + * Converts a SQL file into a array of SQL queries in order to be executed by the Doctrine connection obj + * + * @param string $sqlFilePath + * @param bool $dryRun * @param $output * * @return bool @@ -269,8 +340,9 @@ class MigrationCommand extends AbstractCommand /** * Function originally wrote in install.lib.php - * @param $file - * @param $section + * + * @param string $file + * @param string $section * @param bool $printErrors * * @return array|bool diff --git a/tests/doctrine_console/cli-config.php b/tests/doctrine_console/cli-config.php index c938024ddf..cf06d4fd33 100755 --- a/tests/doctrine_console/cli-config.php +++ b/tests/doctrine_console/cli-config.php @@ -8,6 +8,7 @@ $config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache); use Doctrine\Common\Annotations\AnnotationReader; use Doctrine\Common\Annotations\AnnotationRegistry; +use Symfony\Component\Yaml\Parser; AnnotationRegistry::registerFile(api_get_path(SYS_PATH)."vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php"); $reader = new AnnotationReader(); @@ -18,7 +19,16 @@ $config->setMetadataDriverImpl($driverImpl); $config->setProxyDir(__DIR__ . '/Proxies'); $config->setProxyNamespace('Proxies'); -$courseList = CourseManager::get_real_course_list(); +//$courseList = CourseManager::get_real_course_list(); +$courseList = array(); + +$configurationPath = api_get_path(SYS_PATH).'main/inc/conf/'; +$newConfigurationFile = $configurationPath.'configuration.yml'; + +if (is_file($newConfigurationFile) && file_exists($newConfigurationFile)) { + $yaml = new Parser(); + $_configuration = $yaml->parse(file_get_contents($newConfigurationFile)); +} $connectionOptions = array(); @@ -42,31 +52,25 @@ $connectionOptions['main_database'] = array( 'host' => $_configuration['db_host'], ); -$connectionOptions['statistics_database'] = array( - 'driver' => 'pdo_mysql', - 'dbname' => $_configuration['statistics_database'], - 'user' => $_configuration['db_user'], - 'password' => $_configuration['db_password'], - 'host' => $_configuration['db_host'], -); - -/* -$connectionOptions['scorm_database'] = array( - 'driver' => 'pdo_mysql', - 'dbname' => $_configuration['scorm_database'], - 'user' => $_configuration['db_user'], - 'password' => $_configuration['db_password'], - 'host' => $_configuration['db_host'], -);*/ - -$connectionOptions['user_personal_database'] = array( - 'driver' => 'pdo_mysql', - 'dbname' => $_configuration['user_personal_database'], - 'user' => $_configuration['db_user'], - 'password' => $_configuration['db_password'], - 'host' => $_configuration['db_host'], -); +if (isset($_configuration['statistics_database'])) { + $connectionOptions['statistics_database'] = array( + 'driver' => 'pdo_mysql', + 'dbname' => $_configuration['statistics_database'], + 'user' => $_configuration['db_user'], + 'password' => $_configuration['db_password'], + 'host' => $_configuration['db_host'], + ); +} +if (isset($_configuration['user_personal_database'])) { + $connectionOptions['user_personal_database'] = array( + 'driver' => 'pdo_mysql', + 'dbname' => $_configuration['user_personal_database'], + 'user' => $_configuration['db_user'], + 'password' => $_configuration['db_password'], + 'host' => $_configuration['db_host'], + ); +} $defaultConnection = array( 'driver' => 'pdo_mysql', diff --git a/tests/doctrine_console/doctrine.php b/tests/doctrine_console/doctrine.php index a59eb4d632..f5fa67c271 100755 --- a/tests/doctrine_console/doctrine.php +++ b/tests/doctrine_console/doctrine.php @@ -12,6 +12,7 @@ $helperSet = $cli->getHelperSet(); foreach ($helpers as $name => $helper) { $helperSet->set($helper, $name); } + $cli->addCommands(array( // DBAL Commands new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(), @@ -40,8 +41,8 @@ $cli->addCommands(array( new \Doctrine\DBAL\Migrations\Tools\Console\Command\MigrateCommand(), new \Doctrine\DBAL\Migrations\Tools\Console\Command\StatusCommand(), new \Doctrine\DBAL\Migrations\Tools\Console\Command\VersionCommand(), - new ChamiloLMS\Command\Database\MigrationCommand() - - + new ChamiloLMS\Command\Database\UpgradeCommand(), + new ChamiloLMS\Command\Database\InstallCommand(), + new ChamiloLMS\Command\Database\StatusCommand(), )); $cli->run();