index.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * Chamilo installation
  5. * This script could be loaded via browser using the URL: main/install/index.php
  6. * or via CM
  7. *
  8. * @package chamilo.install
  9. */
  10. require_once __DIR__.'/../../vendor/autoload.php';
  11. require_once __DIR__.'/../inc/lib/api.lib.php';
  12. require_once __DIR__.'/install.lib.php';
  13. $versionData = require_once __DIR__.'/version.php';
  14. error_reporting(-1);
  15. ini_set('display_errors', '1');
  16. set_time_limit(0);
  17. use Symfony\Component\Console\Output\Output;
  18. use Symfony\Component\HttpFoundation\Request;
  19. use ChamiloLMS\Component\Console\Output\BufferedOutput;
  20. use Chash\Command\Installation\InstallCommand;
  21. use Chash\Command\Installation\UpgradeCommand;
  22. $app = new Silex\Application();
  23. // Setting paths
  24. $app['root_sys'] = dirname(dirname(__DIR__)).'/';
  25. $app['sys_root'] = $app['root_sys'];
  26. $app['sys_data_path'] = isset($_configuration['sys_data_path']) ? $_configuration['sys_data_path'] : $app['root_sys'].'data/';
  27. $app['sys_config_path'] = isset($_configuration['sys_config_path']) ? $_configuration['sys_config_path'] : $app['root_sys'].'config/';
  28. $app['sys_course_path'] = isset($_configuration['sys_course_path']) ? $_configuration['sys_course_path'] : $app['sys_data_path'].'/course';
  29. $app['sys_log_path'] = isset($_configuration['sys_log_path']) ? $_configuration['sys_log_path'] : $app['root_sys'].'logs/';
  30. $app['sys_temp_path'] = isset($_configuration['sys_temp_path']) ? $_configuration['sys_temp_path'] : $app['sys_data_path'].'temp/';
  31. // Registering services
  32. $app['debug'] = true;
  33. $app->register(new Silex\Provider\UrlGeneratorServiceProvider());
  34. $app->register(new Silex\Provider\FormServiceProvider());
  35. $app->register(new Silex\Provider\SessionServiceProvider());
  36. $app->register(new Silex\Provider\DoctrineServiceProvider());
  37. $app->register(new Silex\Provider\TranslationServiceProvider());
  38. $app['translator'] = $app->share($app->extend('translator', function ($translator, $app) {
  39. /*$translator->addLoader('pofile', new PoFileLoader());
  40. $file = 'main/locale/'.$locale.'.po';
  41. $translator->addResource('pofile', $file, $locale);*/
  42. /*$translator->addLoader('yaml', new Symfony\Component\Translation\Loader\YamlFileLoader());
  43. $translator->addResource('yaml', __DIR__.'/lang/fr.yml', 'fr');
  44. $translator->addResource('yaml', __DIR__.'/lang/en.yml', 'en');
  45. $translator->addResource('yaml', __DIR__.'/lang/es.yml', 'es');*/
  46. return $translator;
  47. }));
  48. $app->register(
  49. new Silex\Provider\TwigServiceProvider(),
  50. array(
  51. 'twig.path' => array(
  52. 'templates'
  53. ),
  54. // twitter bootstrap form twig templates
  55. //'twig.form.templates' => array('form_div_layout.html.twig', '../template/default/form/form_custom_template.tpl'),
  56. 'twig.options' => array(
  57. 'debug' => $app['debug'],
  58. 'charset' => 'utf-8',
  59. 'strict_variables' => false,
  60. 'autoescape' => true,
  61. //'cache' => $app['debug'] ? false : $app['twig.cache.path'],
  62. 'cache' => false, // no cache during installation sorry
  63. 'optimizations' => -1, // turn on optimizations with -1
  64. )
  65. )
  66. );
  67. use Knp\Provider\ConsoleServiceProvider;
  68. $app->register(new ConsoleServiceProvider(), array(
  69. 'console.name' => 'Chamilo',
  70. 'console.version' => '1.0.0',
  71. 'console.project_directory' => __DIR__.'/..'
  72. ));
  73. // Adding commands.
  74. /** @var Knp\Console\Application $console */
  75. $console = $app['console'];
  76. $console->addCommands(
  77. array(
  78. // DBAL Commands.
  79. new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(),
  80. new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(),
  81. // Migrations Commands.
  82. new \Doctrine\DBAL\Migrations\Tools\Console\Command\DiffCommand(),
  83. new \Doctrine\DBAL\Migrations\Tools\Console\Command\ExecuteCommand(),
  84. new \Doctrine\DBAL\Migrations\Tools\Console\Command\GenerateCommand(),
  85. new \Doctrine\DBAL\Migrations\Tools\Console\Command\MigrateCommand(),
  86. new \Doctrine\DBAL\Migrations\Tools\Console\Command\StatusCommand(),
  87. new \Doctrine\DBAL\Migrations\Tools\Console\Command\VersionCommand(),
  88. // Chash commands.
  89. new UpgradeCommand(),
  90. new InstallCommand(),
  91. new Chash\Command\Files\CleanCoursesFilesCommand(),
  92. new Chash\Command\Files\CleanTempFolderCommand(),
  93. new Chash\Command\Files\CleanConfigFilesCommand(),
  94. new Chash\Command\Files\MailConfCommand(),
  95. new Chash\Command\Files\SetPermissionsAfterInstallCommand(),
  96. new Chash\Command\Files\GenerateTempFileStructureCommand(),
  97. )
  98. );
  99. $helpers = array(
  100. 'configuration' => new Chash\Helpers\ConfigurationHelper()
  101. );
  102. $helperSet = $console->getHelperSet();
  103. foreach ($helpers as $name => $helper) {
  104. $helperSet->set($helper, $name);
  105. }
  106. $blockInstallation = function () use ($app) {
  107. if (file_exists($app['root_sys'].'config/configuration.php') ||
  108. file_exists($app['root_sys'].'config/configuration.yml')
  109. ) {
  110. return $app->abort(500, "A Chamilo installation was found. You can't reinstall.");
  111. }
  112. $defaultTimeZone = ini_get('date.timezone');
  113. if (empty($defaultTimeZone)) {
  114. $app->abort(500, "Please set your 'date.timezone' setting in your php.ini file");
  115. }
  116. // Check the PHP version.
  117. if (api_check_php_version() == false) {
  118. $app->abort(500, "Incorrect PHP version.");
  119. }
  120. if (api_check_php_version() == false) {
  121. $app->abort(500, "Incorrect PHP version.");
  122. }
  123. // @todo move this in the req page
  124. if (extension_loaded('json') == false) {
  125. $app->abort(500, "php5-json extension must be installed.");
  126. }
  127. };
  128. // Controllers
  129. $app->match('/', function () use ($app) {
  130. // in order to get a list of countries
  131. //var_dump(Symfony\Component\Intl\Intl::getRegionBundle()->getCountryNames());
  132. $languages = array(
  133. 'english' => 'english',
  134. 'spanish' => 'spanish',
  135. 'french' => 'french'
  136. );
  137. $request = $app['request'];
  138. $form = $app['form.factory']->createBuilder('form')
  139. ->add('languages', 'choice', array(
  140. 'choices' => $languages,
  141. 'required' => true,
  142. ))
  143. ->add('continue', 'submit', array('attr' => array('class' => 'btn')))
  144. ->getForm();
  145. if ('POST' == $request->getMethod()) {
  146. $url = $app['url_generator']->generate('requirements');
  147. return $app->redirect($url);
  148. }
  149. return $app['twig']->render('index.tpl', array('form' => $form->createView()));
  150. })
  151. ->bind('welcome')
  152. ->before($blockInstallation);
  153. $app->match('/requirements', function () use ($app) {
  154. $allowedToContinue = checkRequiredSettings();
  155. $request = $app['request'];
  156. $builder = $app['form.factory']->createBuilder('form');
  157. if ($allowedToContinue) {
  158. $builder->add('continue', 'submit', array('attr' => array('class' => 'btn-default')));
  159. } else {
  160. $message = $app['translator']->trans("You need to check your server settings.");
  161. $app['session']->getFlashBag()->add('error', $message);
  162. }
  163. $form = $builder->getForm();
  164. //$req = display_requirements($app, 'new');
  165. if (phpversion() < REQUIRED_PHP_VERSION) {
  166. $phpError = '<strong><font color="red">'.translate('PHPVersionError').'</font></strong>';
  167. } else {
  168. $phpError = '<strong><font color="green">'.translate('PHPVersionOK').' '.phpversion().'</font></strong>';
  169. }
  170. if ('POST' == $request->getMethod()) {
  171. $url = $app['url_generator']->generate('check-database');
  172. return $app->redirect($url);
  173. }
  174. $requirements = drawRequirements($app['translator']);
  175. $options = drawOptions($app['translator']);
  176. $permissions = drawPermissionsSettings($app);
  177. return $app['twig']->render(
  178. 'requirements.tpl',
  179. array(
  180. 'form' => $form->createView(),
  181. 'required_php_version' => REQUIRED_PHP_VERSION,
  182. 'required_php_version_validation' => phpversion() < REQUIRED_PHP_VERSION,
  183. 'php_version' => phpversion(),
  184. 'requirements' => $requirements,
  185. 'options' => $options,
  186. 'permissions' => $permissions,
  187. 'php_error' => $phpError,
  188. 'allow_to_continue' => $allowedToContinue
  189. )
  190. );
  191. })->bind('requirements');
  192. $app->match('/check-database', function () use ($app) {
  193. /** @var Request $request */
  194. $request = $app['request'];
  195. $command = $app['console']->get('chamilo:install');
  196. $data = $command->getDatabaseSettingsParams();
  197. $builder = $app['form.factory']->createBuilder('form');
  198. foreach ($data as $key => $value) {
  199. $value['attributes'] = isset($value['attributes']) && is_array($value['attributes']) ? $value['attributes'] : array();
  200. $builder->add($key, $value['type'], $value['attributes']);
  201. }
  202. $builder->add('check', 'submit', array('attr' => array('class' => 'btn')));
  203. $form = $builder->getForm();
  204. if ('POST' == $request->getMethod()) {
  205. $form->bind($request);
  206. if ($form->isValid()) {
  207. $parameters = $form->getData();
  208. /** @var InstallCommand $command */
  209. $command = $app['console']->get('chamilo:install');
  210. $command->setDatabaseSettings($parameters);
  211. $connection = $command->getUserAccessConnectionToHost();
  212. try {
  213. $sm = $connection->getSchemaManager();
  214. $databases = $sm->listDatabases();
  215. if (in_array($parameters['dbname'], $databases)) {
  216. $message = $app['translator']->trans(
  217. 'The database "%s" being used and is going to be deleted!!',
  218. array('%s' => $parameters['dbname'])
  219. );
  220. $app['session']->getFlashBag()->add('warning', $message);
  221. } else {
  222. $message = $app['translator']->trans(
  223. 'A database "%s" is going to be created',
  224. array('%s' => $parameters['dbname'])
  225. );
  226. $app['session']->getFlashBag()->add('warning', $message);
  227. }
  228. $app['session']->getFlashBag()->add('success', 'Connection ok!');
  229. $app['session']->set('database_settings', $parameters);
  230. $url = $app['url_generator']->generate('portal-settings');
  231. return $app->redirect($url);
  232. } catch (Exception $e) {
  233. $app['session']->getFlashBag()->add(
  234. 'success',
  235. 'Connection error !'.$e->getMessage()
  236. );
  237. }
  238. }
  239. }
  240. return $app['twig']->render(
  241. 'check-database.tpl',
  242. array('form' => $form->createView())
  243. );
  244. })->bind('check-database');
  245. $app->match('/portal-settings', function () use ($app) {
  246. /** @var Request $request */
  247. $request = $app['request'];
  248. /** @var InstallCommand $command */
  249. $command = $app['console']->get('chamilo:install');
  250. $builder = $app['form.factory']->createBuilder('form');
  251. $data = $command->getPortalSettingsParams();
  252. $data['institution_url']['attributes']['data'] = str_replace('main/install/', '', $request->getUriForPath('/'));
  253. $permissionNewDir = $app['session']->get('permissions_for_new_directories');
  254. if ($permissionNewDir) {
  255. $data['permissions_for_new_directories']['attributes']['data'] = $permissionNewDir;
  256. }
  257. $permissionNewFiles = $app['session']->get('permissions_for_new_files');
  258. if ($permissionNewFiles) {
  259. $data['permissions_for_new_files']['attributes']['data'] = $permissionNewFiles;
  260. }
  261. foreach ($data as $key => $value) {
  262. $value['attributes'] = isset($value['attributes']) && is_array($value['attributes']) ? $value['attributes'] : array();
  263. $builder->add($key, $value['type'], $value['attributes']);
  264. }
  265. $builder->add('continue', 'submit', array('attr' => array('class' => 'btn')));
  266. $form = $builder->getForm();
  267. if ('POST' == $request->getMethod()) {
  268. $form->bind($request);
  269. if ($form->isValid()) {
  270. $data = $form->getData();
  271. /* Drive-by sanitizing of the site URL:
  272. * Remove excessive trailing slashes that could break the
  273. * RewriteBase in .htaccess.
  274. *
  275. * See writeHtaccess() in
  276. * vendor/chamilo/chash/src/Chash/Command/Installation/CommonCommand.php
  277. */
  278. $data['institution_url'] = rtrim($data['institution_url'], '/').'/';
  279. $app['session']->set('portal_settings', $data);
  280. $url = $app['url_generator']->generate('admin-settings');
  281. return $app->redirect($url);
  282. }
  283. }
  284. return $app['twig']->render('settings.tpl', array('form' => $form->createView()));
  285. })->bind('portal-settings');
  286. // Admin settings.
  287. $app->match('/admin-settings', function () use ($app) {
  288. $request = $app['request'];
  289. /** @var InstallCommand $command */
  290. $command = $app['console']->get('chamilo:install');
  291. $data = $command->getAdminSettingsParams();
  292. $builder = $app['form.factory']->createBuilder('form', $data);
  293. foreach ($data as $key => $value) {
  294. $builder->add($key, $value['type'], $value['attributes']);
  295. }
  296. $builder->add('continue', 'submit', array('attr' => array('class' => 'btn')));
  297. $form = $builder->getForm();
  298. if ('POST' == $request->getMethod()) {
  299. $form->bind($request);
  300. if ($form->isValid()) {
  301. $data = $form->getData();
  302. $app['session']->set('admin_settings', $data);
  303. $url = $app['url_generator']->generate('resume');
  304. return $app->redirect($url);
  305. }
  306. }
  307. return $app['twig']->render('settings.tpl', array('form' => $form->createView()));
  308. })->bind('admin-settings');
  309. // Resume before installing.
  310. $app->match('/resume', function () use ($app) {
  311. $request = $app['request'];
  312. $data = array();
  313. $portalSettings = $app['session']->get('portal_settings');
  314. $databaseSettings = $app['session']->get('database_settings');
  315. $adminSettings = $app['session']->get('admin_settings');
  316. if (!empty($portalSettings) && !empty($databaseSettings) && !empty($adminSettings)) {
  317. $form = $app['form.factory']->createBuilder('form', $data)
  318. ->add(
  319. 'install',
  320. 'submit',
  321. array(
  322. 'label' => 'Install',
  323. 'attr' => array('class' => 'btn btn-success')
  324. )
  325. )
  326. ->getForm();
  327. if ('POST' == $request->getMethod()) {
  328. $url = $app['url_generator']->generate('installing');
  329. return $app->redirect($url);
  330. }
  331. return $app['twig']->render(
  332. 'resume.tpl',
  333. array(
  334. 'form' => $form->createView(),
  335. 'portal_settings' => $portalSettings,
  336. 'database_settings' => $databaseSettings,
  337. 'admin_settings' => $adminSettings
  338. )
  339. );
  340. } else {
  341. $url = $app['url_generator']->generate('check-database');
  342. return $app->redirect($url);
  343. }
  344. })->bind('resume');
  345. // Installation process.
  346. $app->match('/installing', function () use ($app, $versionData) {
  347. $portalSettings = $app['session']->get('portal_settings');
  348. $adminSettings = $app['session']->get('admin_settings');
  349. $databaseSettings = $app['session']->get('database_settings');
  350. /** @var InstallCommand $command */
  351. $command = $app['console']->get('chamilo:install');
  352. $def = $command->getDefinition();
  353. $input = new Symfony\Component\Console\Input\ArrayInput(
  354. array(
  355. 'name',
  356. 'path' => realpath(__DIR__.'/../../').'/',
  357. 'version' => $versionData['version']
  358. ),
  359. $def
  360. );
  361. $output = new BufferedOutput();
  362. $command->setPortalSettings($portalSettings);
  363. $command->setDatabaseSettings($databaseSettings);
  364. $command->setAdminSettings($adminSettings);
  365. $result = $command->run($input, $output);
  366. if ($result == 1) {
  367. $output = $output->getBuffer();
  368. $app['session']->getFlashBag()->add('success', 'Installation finished');
  369. $app['session']->set('output', $output);
  370. $url = $app['url_generator']->generate('finish');
  371. return $app->redirect($url);
  372. } else {
  373. $app['session']->getFlashBag()->add(
  374. 'error',
  375. 'There was an error during installation, please check your settings.'
  376. );
  377. $app['session']->getFlashBag()->add('error', $output->lastMessage);
  378. $url = $app['url_generator']->generate('check-database');
  379. return $app->redirect($url);
  380. }
  381. })->bind('installing');
  382. // Finish installation.
  383. $app->get('/finish', function () use ($app) {
  384. $output = $app['session']->get('output');
  385. $message = $app['translator']->trans(
  386. 'To protect your site, make the whole %s directory read-only (chmod 0555 on Unix/Linux)',
  387. array('%s' => $app['root_sys'].'config')
  388. );
  389. $app['session']->getFlashBag()->add('warning', $message);
  390. $message = $app['translator']->trans(
  391. 'Delete the %s directory.',
  392. array('%s' => $app['root_sys'].'install')
  393. );
  394. $app['session']->getFlashBag()->add('warning', $message);
  395. return $app['twig']->render('finish.tpl', array('output' => $output));
  396. })->bind('finish');
  397. // Middlewares.
  398. $app->before(
  399. function () use ($app) {
  400. }
  401. );
  402. // Errors
  403. /*
  404. $app->error(function (\Exception $e, $code) use ($app) {
  405. switch ($code) {
  406. case 404:
  407. $message = 'The requested page could not be found.';
  408. break;
  409. default:
  410. // $message = 'We are sorry, but something went terribly wrong.';
  411. $message = $e->getMessage();
  412. }
  413. $app['twig']->addGlobal('code', $code);
  414. $app['twig']->addGlobal('message', $message);
  415. return $app['twig']->render('error.tpl');
  416. });
  417. */
  418. if (PHP_SAPI == 'cli') {
  419. $console->run();
  420. } else {
  421. $app->run();
  422. }