global.inc.php 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914
  1. <?php
  2. /** For licensing terms, see /license.txt */
  3. /**
  4. * This is a bootstrap file that loads all Chamilo dependencies including:
  5. *
  6. * - Chamilo settings config/configuration.yml or config/configuration.php (in this order, using what if finds first)
  7. * - Database (Using Doctrine DBAL/ORM)
  8. * - Templates (Using Twig)
  9. * - Loading language files (Using Symfony component)
  10. * - Loading mail settings (Using SwiftMailer smtp/sendmail/mail)
  11. * - Debug (Using Monolog)
  12. *
  13. * ALL Chamilo scripts must include this file in order to have the $app container
  14. * This script returns a $app Application instance so you have access to all the services.
  15. *
  16. * @package chamilo.include
  17. *
  18. */
  19. use Silex\Application;
  20. use \ChamiloSession as Session;
  21. use Symfony\Component\HttpFoundation\RedirectResponse;
  22. use Symfony\Component\HttpFoundation\Response;
  23. use Symfony\Component\HttpFoundation\Request;
  24. use Symfony\Component\Yaml\Parser;
  25. // Determine the directory path for this file.
  26. $includePath = dirname(__FILE__);
  27. // Start Silex.
  28. $app = new Application();
  29. // @todo add a helper to read the configuration file once!
  30. // Include the main Chamilo platform configuration file.
  31. // @todo use a service provider to load configuration files:
  32. /*
  33. $app->register(new Igorw\Silex\ConfigServiceProvider($settingsFile));
  34. */
  35. /** Reading configuration files */
  36. // Reading configuration file from main/inc/conf/configuration.php or app/config/configuration.yml
  37. $configurationFilePath = $includePath.'/conf/configuration.php';
  38. $configurationYMLFile = $includePath.'/../../config/configuration.yml';
  39. $configurationFileAppPath = $includePath.'/../../config/configuration.php';
  40. $alreadyInstalled = false;
  41. $_configuration = array();
  42. if (file_exists($configurationFilePath) || file_exists($configurationYMLFile) || file_exists($configurationFileAppPath)) {
  43. if (file_exists($configurationFilePath)) {
  44. require_once $configurationFilePath;
  45. }
  46. if (file_exists($configurationFileAppPath)) {
  47. $configurationFilePath = $configurationFileAppPath;
  48. require_once $configurationFileAppPath;
  49. }
  50. $alreadyInstalled = true;
  51. }
  52. // Overwriting $_configuration
  53. if (file_exists($configurationYMLFile)) {
  54. $yaml = new Parser();
  55. $configurationYML = $yaml->parse(file_get_contents($configurationYMLFile));
  56. if (is_array($configurationYML) && !empty($configurationYML)) {
  57. if (isset($_configuration)) {
  58. $_configuration = array_merge($_configuration, $configurationYML);
  59. } else {
  60. $_configuration = $configurationYML;
  61. }
  62. }
  63. }
  64. /** Setting Chamilo paths */
  65. $app['root_sys'] = isset($_configuration['root_sys']) ? $_configuration['root_sys'] : dirname(dirname(__DIR__)).'/';
  66. $app['sys_root'] = $app['root_sys'];
  67. $app['sys_data_path'] = isset($_configuration['sys_data_path']) ? $_configuration['sys_data_path'] : $app['root_sys'].'data/';
  68. $app['sys_config_path'] = isset($_configuration['sys_config_path']) ? $_configuration['sys_config_path'] : $app['root_sys'].'config/';
  69. $app['sys_course_path'] = isset($_configuration['sys_course_path']) ? $_configuration['sys_course_path'] : $app['sys_data_path'].'/courses/';
  70. $app['sys_temp_path'] = isset($_configuration['sys_temp_path']) ? $_configuration['sys_temp_path'] : $app['sys_data_path'].'temp/';
  71. $app['sys_log_path'] = isset($_configuration['sys_log_path']) ? $_configuration['sys_log_path'] : $app['root_sys'].'logs/';
  72. /** Loading config files (mail, auth, profile) */
  73. if ($alreadyInstalled) {
  74. $configPath = $app['sys_config_path'];
  75. $confFiles = array(
  76. 'auth.conf.php',
  77. 'events.conf.php',
  78. 'mail.conf.php',
  79. 'portfolio.conf.php',
  80. 'profile.conf.php'
  81. );
  82. foreach ($confFiles as $confFile) {
  83. if (file_exists($configPath.$confFile)) {
  84. require_once $configPath.$confFile;
  85. }
  86. }
  87. // Fixing $_configuration array
  88. // Fixes bug in Chamilo 1.8.7.1 array was not set
  89. $administrator['email'] = isset($administrator['email']) ? $administrator['email'] : 'admin@example.com';
  90. $administrator['name'] = isset($administrator['name']) ? $administrator['name'] : 'Admin';
  91. // Code for transitional purposes, it can be removed right before the 1.8.7 release.
  92. /*if (empty($_configuration['system_version'])) {
  93. $_configuration['system_version'] = (!empty($_configuration['dokeos_version']) ? $_configuration['dokeos_version'] : '');
  94. $_configuration['system_stable'] = (!empty($_configuration['dokeos_stable']) ? $_configuration['dokeos_stable'] : '');
  95. $_configuration['software_url'] = 'http://www.chamilo.org/';
  96. }*/
  97. // For backward compatibility.
  98. $_configuration['dokeos_version'] = isset($_configuration['system_version']) ? $_configuration['system_version'] : null;
  99. //$_configuration['dokeos_stable'] = $_configuration['system_stable'];
  100. $userPasswordCrypted = (!empty($_configuration['password_encryption']) ? $_configuration['password_encryption'] : 'sha1');
  101. }
  102. /** End loading config files */
  103. /** Including legacy libs */
  104. require_once $includePath.'/lib/api.lib.php';
  105. // Setting $_configuration['url_append']
  106. $urlInfo = isset($_configuration['root_web']) ? parse_url($_configuration['root_web']) : null;
  107. $_configuration['url_append'] = null;
  108. if (isset($urlInfo['path'])) {
  109. $_configuration['url_append'] = '/'.basename($urlInfo['path']);
  110. }
  111. $libPath = $includePath.'/lib/';
  112. // Database constants
  113. require_once $libPath.'database.constants.inc.php';
  114. // @todo Rewrite the events.lib.inc.php in a class
  115. require_once $libPath.'events.lib.inc.php';
  116. // Load allowed tag definitions for kses and/or HTMLPurifier.
  117. require_once $libPath.'formvalidator/Rule/allowed_tags.inc.php';
  118. // Add the path to the pear packages to the include path
  119. ini_set('include_path', api_create_include_path_setting($includePath));
  120. $app['configuration_file'] = $configurationFilePath;
  121. $app['configuration_yml_file'] = $configurationYMLFile;
  122. $app['languages_file'] = array();
  123. $app['installed'] = $alreadyInstalled;
  124. $app['app.theme'] = 'chamilo';
  125. // Developer options relies in the configuration.php file
  126. $app['debug'] = isset($_configuration['debug']) ? $_configuration['debug'] : false;
  127. $app['show_profiler'] = isset($_configuration['show_profiler']) ? $_configuration['show_profiler'] : false;
  128. // Enables assetic in order to load 1 compressed stylesheet or split files
  129. //$app['assetic.enabled'] = $app['debug'];
  130. // Hardcoded to false by default. Implementation is not finished yet.
  131. $app['assetic.enabled'] = false;
  132. // Dumps assets
  133. $app['assetic.auto_dump_assets'] = false;
  134. // Loading $app settings depending of the debug option
  135. if ($app['debug']) {
  136. require_once __DIR__.'/../../src/ChamiloLMS/Resources/config/dev.php';
  137. } else {
  138. require_once __DIR__.'/../../src/ChamiloLMS/Resources/config/prod.php';
  139. }
  140. // Classic way of render pages or the Controller approach
  141. $app['classic_layout'] = false;
  142. $app['full_width'] = false;
  143. $app['breadcrumb'] = array();
  144. // The script is allowed? This setting is modified when calling api_is_not_allowed()
  145. $app['allowed'] = true;
  146. // Session settings
  147. use Symfony\Component\HttpFoundation\Session\Storage\Handler;
  148. // Default options
  149. $app['session.storage.options'] = array(
  150. 'name' => 'chamilo_session',
  151. //'cookie_lifetime' => 30, //Cookie lifetime
  152. //'cookie_path' => null, //Cookie path
  153. //'cookie_domain' => null, //Cookie domain
  154. //'cookie_secure' => null, //Cookie secure (HTTPS)
  155. 'cookie_httponly' => true //Whether the cookie is http only
  156. );
  157. // Registering the Session service provider
  158. $app->register(new Silex\Provider\SessionServiceProvider());
  159. // Session using memcached:
  160. if (isset($_configuration['session.memcached.settings'])) {
  161. $memcachedSettings = $_configuration['session.memcached.settings'];
  162. $app['session.storage.handler'] = $app->share(function () use ($app, $memcachedSettings) {
  163. $memcached = new Memcached($memcachedSettings['persistent_id']);
  164. $memcached->addServer($memcachedSettings['host'], $memcachedSettings['port']);
  165. return new Handler\MemcachedSessionHandler($memcached, $memcachedSettings['options']);
  166. });
  167. }
  168. use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
  169. // Session using Doctrine a new table needed to be created, before using it:
  170. if (isset($_configuration['session.doctrine.settings'])) {
  171. /*
  172. CREATE TABLE `session_handler` (
  173. `session_id` varchar(255) NOT NULL,
  174. `session_value` text NOT NULL,
  175. `session_time` int(11) NOT NULL,
  176. PRIMARY KEY (`session_id`)
  177. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;*/
  178. $app['session.db_options'] = array(
  179. 'db_table' => 'session_handler',
  180. 'db_id_col' => 'session_id',
  181. 'db_data_col' => 'session_value',
  182. 'db_time_col' => 'session_time',
  183. );
  184. $app['session.storage.handler'] = $app->share(function () use ($app) {
  185. return new PdoSessionHandler(
  186. $app['db']->getWrappedConnection(),
  187. $app['session.db_options'],
  188. $app['session.storage.options']
  189. );
  190. });
  191. }
  192. // Loading chamilo settings
  193. /* @todo create a service provider to load plugins.
  194. Check how bolt add extensions (including twig templates, config with yml)*/
  195. // Template settings loaded in template.lib.php
  196. $app['template.show_header'] = true;
  197. $app['template.show_footer'] = true;
  198. $app['template.show_learnpath'] = false;
  199. $app['template.hide_global_chat'] = true;
  200. $app['template.load_plugins'] = true;
  201. $app['configuration'] = $_configuration;
  202. // Inclusion of internationalization libraries
  203. require_once $libPath.'internationalization.lib.php';
  204. // Functions for internal use behind this API
  205. require_once $libPath.'internationalization_internal.lib.php';
  206. $_plugins = array();
  207. if ($alreadyInstalled) {
  208. /** Including service providers */
  209. require_once 'services.php';
  210. }
  211. $charset = 'UTF-8';
  212. // Preserving the value of the global variable $charset.
  213. $charset_initial_value = $charset;
  214. // Section (tabs in the main Chamilo menu)
  215. $app['this_section'] = SECTION_GLOBAL;
  216. // Manage Chamilo error messages
  217. $app->error(
  218. function (\Exception $e, $code) use ($app) {
  219. if ($app['debug']) {
  220. //return;
  221. }
  222. $message = null;
  223. if (isset($code)) {
  224. switch ($code) {
  225. case 401:
  226. $message = 'Unauthorized';
  227. break;
  228. case 404: // not found
  229. $message = 'The requested page could not be found.';
  230. break;
  231. default:
  232. //$message = 'We are sorry, but something went terribly wrong.';
  233. $message = $e->getMessage();
  234. }
  235. } else {
  236. $code = null;
  237. }
  238. Session::setSession($app['session']);
  239. //$code = ($e instanceof HttpException) ? $e->getStatusCode() : 500;
  240. // It seems that error() is executed first than the before() middleware
  241. // @ŧodo check this one
  242. $templateStyle = api_get_setting('template');
  243. $templateStyle = isset($templateStyle) && !empty($templateStyle) ? $templateStyle : 'default';
  244. if (!is_dir($app['sys_root'].'main/template/'.$templateStyle)) {
  245. $templateStyle = 'default';
  246. }
  247. $app['template_style'] = $templateStyle;
  248. // Default layout.
  249. $app['default_layout'] = $app['template_style'].'/layout/layout_1_col.tpl';
  250. /** @var Template $template */
  251. $template = $app['template'];
  252. $template->assign('error', array('code' => $code, 'message' => $message));
  253. $response = $template->render_layout('error.tpl');
  254. return new Response($response);
  255. }
  256. );
  257. // Checking if we have a valid language. If not we set it to the platform language.
  258. $cidReset = null;
  259. if ($alreadyInstalled) {
  260. // Initialization of the internationalization library.
  261. //api_initialize_internationalization();
  262. // Initialization of the default encoding that will be used by the multibyte string routines in the internationalization library.
  263. //api_set_internationalization_default_encoding($charset);
  264. // require $includePath.'/local.inc.php';
  265. /** Loading languages and sublanguages **/
  266. // @todo improve the language loading
  267. // if we use the javascript version (without go button) we receive a get
  268. // if we use the non-javascript version (with the go button) we receive a post
  269. // Include all files (first english and then current interface language)
  270. //$app['this_script'] = isset($this_script) ? $this_script : null;
  271. // Sometimes the variable $language_interface is changed
  272. // temporarily for achieving translation in different language.
  273. // We need to save the genuine value of this variable and
  274. // to use it within the function get_lang(...).
  275. //$language_interface_initial_value = $language_interface;
  276. //$this_script = $app['this_script'];
  277. /* This will only work if we are in the page to edit a sub_language */
  278. /*
  279. if (isset($this_script) && $this_script == 'sub_language') {
  280. require_once api_get_path(SYS_CODE_PATH).'admin/sub_language.class.php';
  281. // getting the arrays of files i.e notification, trad4all, etc
  282. $language_files_to_load = SubLanguageManager:: get_lang_folder_files_list(
  283. api_get_path(SYS_LANG_PATH).'english',
  284. true
  285. );
  286. //getting parent info
  287. $languageId = isset($_REQUEST['id']) ? $_REQUEST['id'] : null;
  288. $parent_language = SubLanguageManager::get_all_information_of_language($languageId);
  289. $subLanguageId = isset($_REQUEST['sub_language_id']) ? $_REQUEST['sub_language_id'] : null;
  290. //getting sub language info
  291. $sub_language = SubLanguageManager::get_all_information_of_language($subLanguageId);
  292. $english_language_array = $parent_language_array = $sub_language_array = array();
  293. if (!empty($language_files_to_load)) {
  294. foreach ($language_files_to_load as $language_file_item) {
  295. $lang_list_pre = array_keys($GLOBALS);
  296. //loading english
  297. $path = $langPath.'english/'.$language_file_item.'.inc.php';
  298. if (file_exists($path)) {
  299. include $path;
  300. }
  301. $lang_list_post = array_keys($GLOBALS);
  302. $lang_list_result = array_diff($lang_list_post, $lang_list_pre);
  303. unset($lang_list_pre);
  304. // english language array
  305. $english_language_array[$language_file_item] = compact($lang_list_result);
  306. //cleaning the variables
  307. foreach ($lang_list_result as $item) {
  308. unset(${$item});
  309. }
  310. $parent_file = $langPath.$parent_language['dokeos_folder'].'/'.$language_file_item.'.inc.php';
  311. if (file_exists($parent_file) && is_file($parent_file)) {
  312. include_once $parent_file;
  313. }
  314. // parent language array
  315. $parent_language_array[$language_file_item] = compact($lang_list_result);
  316. //cleaning the variables
  317. foreach ($lang_list_result as $item) {
  318. unset(${$item});
  319. }
  320. if (!empty($sub_language)) {
  321. $sub_file = $langPath.$sub_language['dokeos_folder'].'/'.$language_file_item.'.inc.php';
  322. if (file_exists($sub_file) && is_file($sub_file)) {
  323. include $sub_file;
  324. }
  325. }
  326. // sub language array
  327. $sub_language_array[$language_file_item] = compact($lang_list_result);
  328. //cleaning the variables
  329. foreach ($lang_list_result as $item) {
  330. unset(${$item});
  331. }
  332. }
  333. }
  334. }*/
  335. } else {
  336. $app['language_interface'] = $language_interface = $language_interface_initial_value = 'english';
  337. }
  338. /**
  339. * Include all necessary language files
  340. * - trad4all
  341. * - notification
  342. * - custom tool language files
  343. */
  344. /*
  345. $language_files = array();
  346. $language_files[] = 'trad4all';
  347. $language_files[] = 'notification';
  348. $language_files[] = 'accessibility';
  349. if (isset($language_file)) {
  350. if (!is_array($language_file)) {
  351. $language_files[] = $language_file;
  352. } else {
  353. $language_files = array_merge($language_files, $language_file);
  354. }
  355. }
  356. if (isset($app['languages_file'])) {
  357. $language_files = array_merge($language_files, $app['languages_file']);
  358. }
  359. // if a set of language files has been properly defined
  360. if (is_array($language_files)) {
  361. // if the sub-language feature is on
  362. if (api_get_setting('allow_use_sub_language') == 'true') {
  363. require_once api_get_path(SYS_CODE_PATH).'admin/sub_language.class.php';
  364. $parent_path = SubLanguageManager::get_parent_language_path($language_interface);
  365. foreach ($language_files as $index => $language_file) {
  366. // include English
  367. include $langPath.'english/'.$language_file.'.inc.php';
  368. // prepare string for current language and its parent
  369. $lang_file = $langPath.$language_interface.'/'.$language_file.'.inc.php';
  370. $parent_lang_file = $langPath.$parent_path.'/'.$language_file.'.inc.php';
  371. // load the parent language file first
  372. if (file_exists($parent_lang_file)) {
  373. include $parent_lang_file;
  374. }
  375. // overwrite the parent language translations if there is a child
  376. if (file_exists($lang_file)) {
  377. include $lang_file;
  378. }
  379. }
  380. } else {
  381. // if the sub-languages feature is not on, then just load the
  382. // set language interface
  383. foreach ($language_files as $index => $language_file) {
  384. // include English
  385. include $langPath.'english/'.$language_file.'.inc.php';
  386. // prepare string for current language
  387. $langFile = $langPath.$language_interface.'/'.$language_file.'.inc.php';
  388. if (file_exists($langFile)) {
  389. include $langFile;
  390. }
  391. }
  392. }
  393. }*/
  394. // End loading languages
  395. /** Silex Middlewares. */
  396. /** A "before" middleware allows you to tweak the Request before the controller is executed. */
  397. use Symfony\Component\Translation\Loader\PoFileLoader;
  398. use Symfony\Component\Translation\Loader\MoFileLoader;
  399. use Symfony\Component\Finder\Finder;
  400. $app->before(
  401. function () use ($app) {
  402. /** @var Request $request */
  403. $request = $app['request'];
  404. // Checking configuration file. If does not exists redirect to the install folder.
  405. if (!file_exists($app['configuration_file']) && !file_exists($app['configuration_yml_file'])) {
  406. $url = str_replace('web', 'main/install', $request->getBasePath());
  407. return new RedirectResponse($url);
  408. }
  409. // Check the PHP version.
  410. if (api_check_php_version() == false) {
  411. $app->abort(500, "Incorrect PHP version.");
  412. }
  413. // Check data folder
  414. if (!is_writable($app['sys_data_path'])) {
  415. $app->abort(500, "data folder must be writable.");
  416. }
  417. // Checks temp folder permissions.
  418. if (!is_writable($app['sys_temp_path'])) {
  419. $app->abort(500, "data/temp folder must be writable.");
  420. }
  421. // Checking that configuration is loaded
  422. if (!isset($app['configuration'])) {
  423. $app->abort(500, '$configuration array must be set in the configuration.php file.');
  424. }
  425. $configuration = $app['configuration'];
  426. // Check if root_web exists
  427. if (!isset($configuration['root_web'])) {
  428. $app->abort(500, '$configuration[root_web] must be set in the configuration.php file.');
  429. }
  430. // Starting the session for more info see: http://silex.sensiolabs.org/doc/providers/session.html
  431. $request->getSession()->start();
  432. // Setting session obj
  433. Session::setSession($app['session']);
  434. UserManager::setEntityManager($app['orm.em']);
  435. /** @var ChamiloLMS\Component\DataFilesystem\DataFilesystem $filesystem */
  436. $filesystem = $app['chamilo.filesystem'];
  437. if ($app['debug']) {
  438. // Creates data/temp folders for every request if debug is on.
  439. $filesystem->createFolders($app['temp.paths']->folders);
  440. }
  441. // If Assetic is enabled copy folders from theme inside "web/"
  442. if ($app['assetic.auto_dump_assets']) {
  443. $filesystem->copyFolders($app['temp.paths']->copyFolders);
  444. }
  445. // Check and modify the date of user in the track.e.online table
  446. Online::loginCheck(api_get_user_id());
  447. // Setting access_url id (multiple url feature)
  448. if (api_get_multiple_access_url()) {
  449. $_configuration = $app['configuration'];
  450. $_configuration['access_url'] = 1;
  451. $access_urls = api_get_access_urls();
  452. //$protocol = ((!empty($_SERVER['HTTPS']) && strtoupper($_SERVER['HTTPS']) != 'OFF') ? 'https' : 'http').'://';
  453. $protocol = $request->getScheme().'://';
  454. $request_url1 = $protocol.$_SERVER['SERVER_NAME'].'/';
  455. $request_url2 = $protocol.$_SERVER['HTTP_HOST'].'/';
  456. foreach ($access_urls as & $details) {
  457. if ($request_url1 == $details['url'] or $request_url2 == $details['url']) {
  458. $_configuration['access_url'] = $details['id'];
  459. }
  460. }
  461. Session::write('url_id', $_configuration['access_url']);
  462. Session::write('url_info', api_get_current_access_url_info($_configuration['access_url']));
  463. } else {
  464. Session::write('url_id', 1);
  465. }
  466. // Loading portal settings from DB.
  467. $settings_refresh_info = api_get_settings_params_simple(array('variable = ?' => 'settings_latest_update'));
  468. $settings_latest_update = $settings_refresh_info ? $settings_refresh_info['selected_value'] : null;
  469. $_setting = Session::read('_setting');
  470. if (empty($_setting)) {
  471. api_set_settings_and_plugins();
  472. } else {
  473. if (isset($_setting['settings_latest_update']) && $_setting['settings_latest_update'] != $settings_latest_update) {
  474. api_set_settings_and_plugins();
  475. }
  476. }
  477. $app['plugins'] = Session::read('_plugins');
  478. // Default template style.
  479. $templateStyle = api_get_setting('template');
  480. $templateStyle = isset($templateStyle) && !empty($templateStyle) ? $templateStyle : 'default';
  481. if (!is_dir($app['sys_root'].'main/template/'.$templateStyle)) {
  482. $templateStyle = 'default';
  483. }
  484. $app['template_style'] = $templateStyle;
  485. // Default layout.
  486. $app['default_layout'] = $app['template_style'].'/layout/layout_1_col.tpl';
  487. // Setting languages.
  488. $app['api_get_languages'] = api_get_languages();
  489. $app['language_interface'] = $language_interface = api_get_language_interface();
  490. // Reconfigure template now that we know the user.
  491. $app['template.hide_global_chat'] = !api_is_global_chat_enabled();
  492. /** Setting the course quota */
  493. // Default quota for the course documents folder
  494. $default_quota = api_get_setting('default_document_quotum');
  495. // Just in case the setting is not correctly set
  496. if (empty($default_quota)) {
  497. $default_quota = 100000000;
  498. }
  499. define('DEFAULT_DOCUMENT_QUOTA', $default_quota);
  500. // Specification for usernames:
  501. // 1. ASCII-letters, digits, "." (dot), "_" (underscore) are acceptable, 40 characters maximum length.
  502. // 2. Empty username is formally valid, but it is reserved for the anonymous user.
  503. // 3. Checking the login_is_email portal setting in order to accept 100 chars maximum
  504. $default_username_length = 40;
  505. if (api_get_setting('login_is_email') == 'true') {
  506. $default_username_length = 100;
  507. }
  508. define('USERNAME_MAX_LENGTH', $default_username_length);
  509. $user = null;
  510. /** Security component. */
  511. /** @var Symfony\Component\Security\Core\SecurityContext $security */
  512. $security = $app['security'];
  513. if ($security->isGranted('IS_AUTHENTICATED_FULLY')) {
  514. // Checking token in order to get the current user.
  515. $token = $security->getToken();
  516. if (null !== $token) {
  517. /** @var Entity\User $user */
  518. $user = $token->getUser();
  519. }
  520. // For backward compatibility.
  521. $userInfo = api_get_user_info($user->getUserId());
  522. $userInfo['is_anonymous'] = false;
  523. Session::write('_user', $userInfo);
  524. $app['current_user'] = $userInfo;
  525. // Setting admin permissions.
  526. if ($security->isGranted('ROLE_ADMIN')) {
  527. Session::write('is_platformAdmin', true);
  528. }
  529. // Setting teachers permissions.
  530. if ($security->isGranted('ROLE_TEACHER')) {
  531. Session::write('is_allowedCreateCourse', true);
  532. }
  533. } else {
  534. Session::erase('_user');
  535. Session::erase('is_platformAdmin');
  536. Session::erase('is_allowedCreateCourse');
  537. }
  538. /** Translator component. */
  539. $app['translator.cache.enabled'] = false;
  540. $language = api_get_setting('platformLanguage');
  541. $iso = api_get_language_isocode($language);
  542. /** @var Symfony\Component\Translation\Translator $translator */
  543. $translator = $app['translator'];
  544. $translator->setLocale($iso);
  545. // From the login page
  546. $language = $request->get('language');
  547. if (!empty($language)) {
  548. $iso = api_get_language_isocode($language);
  549. $translator->setLocale($iso);
  550. }
  551. // From the user
  552. if ($user && $userInfo) {
  553. // @todo check why this does not works
  554. //$language = $user->getLanguage();
  555. $language = $userInfo['language'];
  556. $iso = api_get_language_isocode($language);
  557. $translator->setLocale($iso);
  558. }
  559. // From the course
  560. $courseInfo = api_get_course_info();
  561. if ($courseInfo && !empty($courseInfo)) {
  562. $iso = api_get_language_isocode($courseInfo['language']);
  563. $translator->setLocale($iso);
  564. }
  565. $app['translator'] = $app->share($app->extend('translator', function ($translator, $app) {
  566. $locale = $translator->getLocale();
  567. /** @var Symfony\Component\Translation\Translator $translator */
  568. if ($app['translator.cache.enabled']) {
  569. //$phpFileDumper = new Symfony\Component\Translation\Dumper\PhpFileDumper();
  570. $dumper = new Symfony\Component\Translation\Dumper\MoFileDumper();
  571. $catalogue = new Symfony\Component\Translation\MessageCatalogue($locale);
  572. $catalogue->add(array('foo' => 'bar'));
  573. $dumper->dump($catalogue, array('path' => $app['sys_temp_path']));
  574. } else {
  575. $translator->addLoader('pofile', new PoFileLoader());
  576. $file = $app['root_sys'].'main/locale/'.$locale.'.po';
  577. if (file_exists($file)) {
  578. $translator->addResource('pofile', $file, $locale);
  579. }
  580. $customFile = $app['root_sys'].'main/locale/'.$locale.'.custom.po';
  581. if (file_exists($customFile)) {
  582. $translator->addResource('pofile', $customFile, $locale);
  583. }
  584. // Validators
  585. $file = $app['root_sys'].'vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators.'.$locale.'.xlf';
  586. $translator->addLoader('xlf', new Symfony\Component\Translation\Loader\XliffFileLoader());
  587. if (file_exists($file)) {
  588. $translator->addResource('xlf', $file, $locale, 'validators');
  589. }
  590. /*$translator->addLoader('mofile', new MoFileLoader());
  591. $filePath = api_get_path(SYS_PATH).'main/locale/'.$locale.'.mo';
  592. if (!file_exists($filePath)) {
  593. $filePath = api_get_path(SYS_PATH).'main/locale/en.mo';
  594. }
  595. $translator->addResource('mofile', $filePath, $locale);*/
  596. return $translator;
  597. }
  598. }));
  599. // Check if we are inside a Chamilo course tool (or we need to set the $this->getCourse() in the controllers)
  600. $isCourseTool = (strpos($request->getPathInfo(), 'courses/') === false) ? false : true;
  601. if (!$isCourseTool) {
  602. // @todo add a before in controller in order to load the courses and course_session object
  603. $isCourseTool = (strpos($request->getPathInfo(), 'question_manager/exercise_distribution/') === false) ? false : true;
  604. }
  605. if (!$isCourseTool) {
  606. // @todo add a before in controller in order to load the courses and course_session object
  607. $isCourseTool = (strpos($request->getPathInfo(), 'exercise_statistics/exercise_distribution/') === false) ? false : true;
  608. }
  609. if (!$isCourseTool) {
  610. // @todo add a before in controller in order to load the courses and course_session object
  611. $isCourseTool = (strpos($request->getPathInfo(), 'question_manager/questions/') === false) ? false : true;
  612. }
  613. // Setting course entity for controllers and templates
  614. if ($isCourseTool) {
  615. // The course parameter is loaded
  616. $course = $request->get('course');
  617. if (empty($course)) {
  618. $course = $request->get('cidReq');
  619. }
  620. if (!empty($course)) {
  621. // Converting /courses/XXX/ to a Entity/Course object
  622. $course = $app['orm.em']->getRepository('Entity\Course')->findOneByCode($course);
  623. } else {
  624. $courseId = $request->get('courseId');
  625. // Converting /courses/XXX/ to a Entity/Course object
  626. $course = $app['orm.em']->getRepository('Entity\Course')->find($courseId);
  627. }
  628. $app['course'] = $course;
  629. $app['template']->assign('course', $course);
  630. $sessionId = $request->get('id_session');
  631. $session = $app['orm.em']->getRepository('Entity\Session')->findOneById($sessionId);
  632. $app['course_session'] = $session;
  633. $app['template']->assign('course_session', $session);
  634. }
  635. }
  636. );
  637. /** An after application middleware allows you to tweak the Response before it is sent to the client */
  638. $app->after(
  639. function (Request $request, Response $response) {
  640. }
  641. );
  642. /** A "finish" application middleware allows you to execute tasks after the Response has been sent to
  643. * the client (like sending emails or logging) */
  644. $app->finish(
  645. function (Request $request) use ($app) {
  646. }
  647. );
  648. // End Silex Middlewares
  649. // The global variable $charset has been defined in a language file too (trad4all.inc.php), this is legacy situation.
  650. // So, we have to reassign this variable again in order to keep its value right.
  651. $charset = $charset_initial_value;
  652. // The global variable $text_dir has been defined in the language file trad4all.inc.php.
  653. // For determing text direction correspondent to the current language we use now information from the internationalization library.
  654. $text_dir = api_get_text_direction();
  655. /** "Login as user" custom script */
  656. // @todo move this code in a controller
  657. /*
  658. if (!isset($_SESSION['login_as']) && isset($_user)) {
  659. // if $_SESSION['login_as'] is set, then the user is an admin logged as the user
  660. $tbl_track_login = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
  661. $sql_last_connection = "SELECT login_id, login_date FROM $tbl_track_login
  662. WHERE login_user_id = '".api_get_user_id()."'
  663. ORDER BY login_date DESC LIMIT 0,1";
  664. $q_last_connection = Database::query($sql_last_connection);
  665. if (Database::num_rows($q_last_connection) > 0) {
  666. $i_id_last_connection = Database::result($q_last_connection, 0, 'login_id');
  667. // is the latest logout_date still relevant?
  668. $sql_logout_date = "SELECT logout_date FROM $tbl_track_login WHERE login_id = $i_id_last_connection";
  669. $q_logout_date = Database::query($sql_logout_date);
  670. $res_logout_date = api_convert_sql_date(Database::result($q_logout_date, 0, 'logout_date'));
  671. if ($res_logout_date < time() - $app['configuration']['session_lifetime']) {
  672. // now that it's created, we can get its ID and carry on
  673. $q_last_connection = Database::query($sql_last_connection);
  674. $i_id_last_connection = Database::result($q_last_connection, 0, 'login_id');
  675. }
  676. $now = api_get_utc_datetime();
  677. $s_sql_update_logout_date = "UPDATE $tbl_track_login SET logout_date = '$now' WHERE login_id = $i_id_last_connection";
  678. Database::query($s_sql_update_logout_date);
  679. }
  680. }*/
  681. // Add language_measure_frequency to your main/inc/conf/configuration.php in
  682. // order to generate language variables frequency measurements (you can then
  683. // see them through main/cron/lang/langstats.php)
  684. // The langstat object will then be used in the get_lang() function.
  685. // This block can be removed to speed things up a bit as it should only ever
  686. // be used in development versions.
  687. // @todo create a service provider to load this
  688. if (isset($app['configuration']['language_measure_frequency']) && $app['configuration']['language_measure_frequency'] == 1) {
  689. require_once api_get_path(SYS_CODE_PATH).'/cron/lang/langstats.class.php';
  690. $langstats = new langstats();
  691. }
  692. /** Setting the is_admin key */
  693. $app['is_admin'] = false;
  694. /** Including routes */
  695. require_once 'routes.php';
  696. // Setting doctrine2 extensions
  697. if (isset($app['configuration']['main_database']) && isset($app['db.event_manager'])) {
  698. // @todo improvement do not create every time this objects
  699. $sortableGroup = new Gedmo\Mapping\Annotation\SortableGroup(array());
  700. $sortablePosition = new Gedmo\Mapping\Annotation\SortablePosition(array());
  701. $tree = new Gedmo\Mapping\Annotation\Tree(array());
  702. $tree = new Gedmo\Mapping\Annotation\TreeParent(array());
  703. $tree = new Gedmo\Mapping\Annotation\TreeLeft(array());
  704. $tree = new Gedmo\Mapping\Annotation\TreeRight(array());
  705. $tree = new Gedmo\Mapping\Annotation\TreeRoot(array());
  706. $tree = new Gedmo\Mapping\Annotation\TreeLevel(array());
  707. $tree = new Gedmo\Mapping\Annotation\Versioned(array());
  708. $tree = new Gedmo\Mapping\Annotation\Loggable(array());
  709. $tree = new Gedmo\Loggable\Entity\LogEntry();
  710. // Setting Doctrine2 extensions
  711. $timestampableListener = new \Gedmo\Timestampable\TimestampableListener();
  712. // $app['db.event_manager']->addEventSubscriber($timestampableListener);
  713. $app['dbs.event_manager']['db_read']->addEventSubscriber($timestampableListener);
  714. $app['dbs.event_manager']['db_write']->addEventSubscriber($timestampableListener);
  715. $sluggableListener = new \Gedmo\Sluggable\SluggableListener();
  716. // $app['db.event_manager']->addEventSubscriber($sluggableListener);
  717. $app['dbs.event_manager']['db_read']->addEventSubscriber($sluggableListener);
  718. $app['dbs.event_manager']['db_write']->addEventSubscriber($sluggableListener);
  719. $sortableListener = new Gedmo\Sortable\SortableListener();
  720. // $app['db.event_manager']->addEventSubscriber($sortableListener);
  721. $app['dbs.event_manager']['db_read']->addEventSubscriber($sortableListener);
  722. $app['dbs.event_manager']['db_write']->addEventSubscriber($sortableListener);
  723. $treeListener = new \Gedmo\Tree\TreeListener();
  724. //$treeListener->setAnnotationReader($cachedAnnotationReader);
  725. // $app['db.event_manager']->addEventSubscriber($treeListener);
  726. $app['dbs.event_manager']['db_read']->addEventSubscriber($treeListener);
  727. $app['dbs.event_manager']['db_write']->addEventSubscriber($treeListener);
  728. $loggableListener = new \Gedmo\Loggable\LoggableListener();
  729. if (PHP_SAPI != 'cli') {
  730. //$userInfo = api_get_user_info();
  731. if (isset($userInfo) && !empty($userInfo['username'])) {
  732. //$loggableListener->setUsername($userInfo['username']);
  733. }
  734. }
  735. $app['dbs.event_manager']['db_read']->addEventSubscriber($loggableListener);
  736. $app['dbs.event_manager']['db_write']->addEventSubscriber($loggableListener);
  737. }
  738. return $app;