PageRenderTime 61ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/phpBB/install/install_install.php

http://github.com/phpbb/phpbb3
PHP | 2331 lines | 1707 code | 371 blank | 253 comment | 179 complexity | 11c96777d71e6d7c6039932173a88f95 MD5 | raw file
Possible License(s): AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. *
  4. * This file is part of the phpBB Forum Software package.
  5. *
  6. * @copyright (c) phpBB Limited <https://www.phpbb.com>
  7. * @license GNU General Public License, version 2 (GPL-2.0)
  8. *
  9. * For full copyright and license information, please see
  10. * the docs/CREDITS.txt file.
  11. *
  12. */
  13. /**
  14. */
  15. if (!defined('IN_INSTALL'))
  16. {
  17. // Someone has tried to access the file direct. This is not a good idea, so exit
  18. exit;
  19. }
  20. if (!empty($setmodules))
  21. {
  22. // If phpBB is already installed we do not include this module
  23. if (phpbb_check_installation_exists($phpbb_root_path, $phpEx) && !file_exists($phpbb_root_path . 'cache/install_lock'))
  24. {
  25. return;
  26. }
  27. $module[] = array(
  28. 'module_type' => 'install',
  29. 'module_title' => 'INSTALL',
  30. 'module_filename' => substr(basename(__FILE__), 0, -strlen($phpEx)-1),
  31. 'module_order' => 10,
  32. 'module_subs' => '',
  33. 'module_stages' => array('INTRO', 'REQUIREMENTS', 'DATABASE', 'ADMINISTRATOR', 'CONFIG_FILE', 'ADVANCED', 'CREATE_TABLE', 'FINAL'),
  34. 'module_reqs' => ''
  35. );
  36. }
  37. /**
  38. * Installation
  39. */
  40. class install_install extends module
  41. {
  42. function install_install(&$p_master)
  43. {
  44. $this->p_master = &$p_master;
  45. }
  46. function main($mode, $sub)
  47. {
  48. global $lang, $template, $language, $phpbb_root_path, $phpEx;
  49. global $phpbb_container, $cache, $phpbb_log, $request, $phpbb_config_php_file;
  50. switch ($sub)
  51. {
  52. case 'intro':
  53. $phpbb_container->get('cache.driver')->purge();
  54. $this->page_title = $lang['SUB_INTRO'];
  55. $template->assign_vars(array(
  56. 'TITLE' => $lang['INSTALL_INTRO'],
  57. 'BODY' => $lang['INSTALL_INTRO_BODY'],
  58. 'L_SUBMIT' => $lang['NEXT_STEP'],
  59. 'S_LANG_SELECT' => '<select id="language" name="language">' . $this->p_master->inst_language_select($language) . '</select>',
  60. 'U_ACTION' => $this->p_master->module_url . "?mode=$mode&amp;sub=requirements&amp;language=$language",
  61. ));
  62. break;
  63. case 'requirements':
  64. $this->check_server_requirements($mode, $sub);
  65. break;
  66. case 'database':
  67. $this->obtain_database_settings($mode, $sub);
  68. break;
  69. case 'administrator':
  70. $this->obtain_admin_settings($mode, $sub);
  71. break;
  72. case 'config_file':
  73. $this->create_config_file($mode, $sub);
  74. break;
  75. case 'advanced':
  76. $this->obtain_advanced_settings($mode, $sub);
  77. break;
  78. case 'create_table':
  79. $this->load_schema($mode, $sub);
  80. break;
  81. case 'final':
  82. // Enable super globals to prevent issues with the new \phpbb\request\request object
  83. $request->enable_super_globals();
  84. // Create a normal container now
  85. $phpbb_container_builder = new \phpbb\di\container_builder($phpbb_config_php_file, $phpbb_root_path, $phpEx);
  86. $phpbb_container = $phpbb_container_builder->get_container();
  87. // Sets the global variables
  88. $cache = $phpbb_container->get('cache');
  89. $phpbb_log = $phpbb_container->get('log');
  90. $this->build_search_index($mode, $sub);
  91. $this->add_modules($mode, $sub);
  92. $this->add_language($mode, $sub);
  93. $this->add_bots($mode, $sub);
  94. $this->email_admin($mode, $sub);
  95. $this->disable_avatars_if_unwritable();
  96. $this->populate_migrations($phpbb_container->get('ext.manager'), $phpbb_container->get('migrator'));
  97. // Remove the lock file
  98. @unlink($phpbb_root_path . 'cache/install_lock');
  99. break;
  100. }
  101. $this->tpl_name = 'install_install';
  102. }
  103. /**
  104. * Checks that the server we are installing on meets the requirements for running phpBB
  105. */
  106. function check_server_requirements($mode, $sub)
  107. {
  108. global $lang, $template, $phpbb_root_path, $phpEx, $language;
  109. $this->page_title = $lang['STAGE_REQUIREMENTS'];
  110. $template->assign_vars(array(
  111. 'TITLE' => $lang['REQUIREMENTS_TITLE'],
  112. 'BODY' => $lang['REQUIREMENTS_EXPLAIN'],
  113. ));
  114. $passed = array('php' => false, 'db' => false, 'files' => false, 'pcre' => false, 'imagesize' => false, 'json' => false,);
  115. // Test for basic PHP settings
  116. $template->assign_block_vars('checks', array(
  117. 'S_LEGEND' => true,
  118. 'LEGEND' => $lang['PHP_SETTINGS'],
  119. 'LEGEND_EXPLAIN' => $lang['PHP_SETTINGS_EXPLAIN'],
  120. ));
  121. // Test the minimum and maximum version of PHP
  122. $php_version = PHP_VERSION;
  123. if ((version_compare($php_version, '5.3.3') < 0) || (version_compare($php_version, '7.0.0-dev', '>=')))
  124. {
  125. $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
  126. }
  127. else
  128. {
  129. $passed['php'] = true;
  130. // We also give feedback on whether we're running in safe mode
  131. $result = '<strong style="color:green">' . $lang['YES'];
  132. if (@ini_get('safe_mode') == '1' || strtolower(@ini_get('safe_mode')) == 'on')
  133. {
  134. $result .= ', ' . $lang['PHP_SAFE_MODE'];
  135. }
  136. $result .= '</strong>';
  137. }
  138. $template->assign_block_vars('checks', array(
  139. 'TITLE' => $lang['PHP_VERSION_REQD'],
  140. 'RESULT' => $result,
  141. 'S_EXPLAIN' => false,
  142. 'S_LEGEND' => false,
  143. ));
  144. // Don't check for register_globals on 5.4+
  145. if (version_compare($php_version, '5.4.0-dev') < 0)
  146. {
  147. // Check for register_globals being enabled
  148. if (@ini_get('register_globals') == '1' || strtolower(@ini_get('register_globals')) == 'on')
  149. {
  150. $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
  151. }
  152. else
  153. {
  154. $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
  155. }
  156. $template->assign_block_vars('checks', array(
  157. 'TITLE' => $lang['PHP_REGISTER_GLOBALS'],
  158. 'TITLE_EXPLAIN' => $lang['PHP_REGISTER_GLOBALS_EXPLAIN'],
  159. 'RESULT' => $result,
  160. 'S_EXPLAIN' => true,
  161. 'S_LEGEND' => false,
  162. ));
  163. }
  164. // Check for url_fopen
  165. if (@ini_get('allow_url_fopen') == '1' || strtolower(@ini_get('allow_url_fopen')) == 'on')
  166. {
  167. $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
  168. }
  169. else
  170. {
  171. $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
  172. }
  173. $template->assign_block_vars('checks', array(
  174. 'TITLE' => $lang['PHP_URL_FOPEN_SUPPORT'],
  175. 'TITLE_EXPLAIN' => $lang['PHP_URL_FOPEN_SUPPORT_EXPLAIN'],
  176. 'RESULT' => $result,
  177. 'S_EXPLAIN' => true,
  178. 'S_LEGEND' => false,
  179. ));
  180. // Check for getimagesize
  181. if (@function_exists('getimagesize'))
  182. {
  183. $passed['imagesize'] = true;
  184. $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
  185. }
  186. else
  187. {
  188. $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
  189. }
  190. $template->assign_block_vars('checks', array(
  191. 'TITLE' => $lang['PHP_GETIMAGESIZE_SUPPORT'],
  192. 'TITLE_EXPLAIN' => $lang['PHP_GETIMAGESIZE_SUPPORT_EXPLAIN'],
  193. 'RESULT' => $result,
  194. 'S_EXPLAIN' => true,
  195. 'S_LEGEND' => false,
  196. ));
  197. // Check for PCRE UTF-8 support
  198. if (@preg_match('//u', ''))
  199. {
  200. $passed['pcre'] = true;
  201. $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
  202. }
  203. else
  204. {
  205. $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
  206. }
  207. $template->assign_block_vars('checks', array(
  208. 'TITLE' => $lang['PCRE_UTF_SUPPORT'],
  209. 'TITLE_EXPLAIN' => $lang['PCRE_UTF_SUPPORT_EXPLAIN'],
  210. 'RESULT' => $result,
  211. 'S_EXPLAIN' => true,
  212. 'S_LEGEND' => false,
  213. ));
  214. // Check for php json support
  215. if (@extension_loaded('json'))
  216. {
  217. $passed['json'] = true;
  218. $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
  219. }
  220. else
  221. {
  222. $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
  223. }
  224. $template->assign_block_vars('checks', array(
  225. 'TITLE' => $lang['PHP_JSON_SUPPORT'],
  226. 'TITLE_EXPLAIN' => $lang['PHP_JSON_SUPPORT_EXPLAIN'],
  227. 'RESULT' => $result,
  228. 'S_EXPLAIN' => true,
  229. 'S_LEGEND' => false,
  230. ));
  231. $passed['mbstring'] = true;
  232. if (@extension_loaded('mbstring'))
  233. {
  234. // Test for available database modules
  235. $template->assign_block_vars('checks', array(
  236. 'S_LEGEND' => true,
  237. 'LEGEND' => $lang['MBSTRING_CHECK'],
  238. 'LEGEND_EXPLAIN' => $lang['MBSTRING_CHECK_EXPLAIN'],
  239. ));
  240. $checks = array(
  241. array('func_overload', '&', MB_OVERLOAD_MAIL|MB_OVERLOAD_STRING),
  242. array('encoding_translation', '!=', 0),
  243. array('http_input', '!=', array('pass', '')),
  244. array('http_output', '!=', array('pass', ''))
  245. );
  246. foreach ($checks as $mb_checks)
  247. {
  248. $ini_val = @ini_get('mbstring.' . $mb_checks[0]);
  249. switch ($mb_checks[1])
  250. {
  251. case '&':
  252. if (intval($ini_val) & $mb_checks[2])
  253. {
  254. $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
  255. $passed['mbstring'] = false;
  256. }
  257. else
  258. {
  259. $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
  260. }
  261. break;
  262. case '!=':
  263. if (!is_array($mb_checks[2]) && $ini_val != $mb_checks[2] ||
  264. is_array($mb_checks[2]) && !in_array($ini_val, $mb_checks[2]))
  265. {
  266. $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
  267. $passed['mbstring'] = false;
  268. }
  269. else
  270. {
  271. $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
  272. }
  273. break;
  274. }
  275. $template->assign_block_vars('checks', array(
  276. 'TITLE' => $lang['MBSTRING_' . strtoupper($mb_checks[0])],
  277. 'TITLE_EXPLAIN' => $lang['MBSTRING_' . strtoupper($mb_checks[0]) . '_EXPLAIN'],
  278. 'RESULT' => $result,
  279. 'S_EXPLAIN' => true,
  280. 'S_LEGEND' => false,
  281. ));
  282. }
  283. }
  284. // Test for available database modules
  285. $template->assign_block_vars('checks', array(
  286. 'S_LEGEND' => true,
  287. 'LEGEND' => $lang['PHP_SUPPORTED_DB'],
  288. 'LEGEND_EXPLAIN' => $lang['PHP_SUPPORTED_DB_EXPLAIN'],
  289. ));
  290. $available_dbms = get_available_dbms(false, true);
  291. $passed['db'] = $available_dbms['ANY_DB_SUPPORT'];
  292. unset($available_dbms['ANY_DB_SUPPORT']);
  293. foreach ($available_dbms as $db_name => $db_ary)
  294. {
  295. if (!$db_ary['AVAILABLE'])
  296. {
  297. $template->assign_block_vars('checks', array(
  298. 'TITLE' => $lang['DLL_' . strtoupper($db_name)],
  299. 'RESULT' => '<span style="color:red">' . $lang['UNAVAILABLE'] . '</span>',
  300. 'S_EXPLAIN' => false,
  301. 'S_LEGEND' => false,
  302. ));
  303. }
  304. else
  305. {
  306. $template->assign_block_vars('checks', array(
  307. 'TITLE' => $lang['DLL_' . strtoupper($db_name)],
  308. 'RESULT' => '<strong style="color:green">' . $lang['AVAILABLE'] . '</strong>',
  309. 'S_EXPLAIN' => false,
  310. 'S_LEGEND' => false,
  311. ));
  312. }
  313. }
  314. // Test for other modules
  315. $template->assign_block_vars('checks', array(
  316. 'S_LEGEND' => true,
  317. 'LEGEND' => $lang['PHP_OPTIONAL_MODULE'],
  318. 'LEGEND_EXPLAIN' => $lang['PHP_OPTIONAL_MODULE_EXPLAIN'],
  319. ));
  320. foreach ($this->php_dlls_other as $dll)
  321. {
  322. if (!@extension_loaded($dll))
  323. {
  324. $template->assign_block_vars('checks', array(
  325. 'TITLE' => $lang['DLL_' . strtoupper($dll)],
  326. 'RESULT' => '<strong style="color:red">' . $lang['UNAVAILABLE'] . '</strong>',
  327. 'S_EXPLAIN' => false,
  328. 'S_LEGEND' => false,
  329. ));
  330. continue;
  331. }
  332. $template->assign_block_vars('checks', array(
  333. 'TITLE' => $lang['DLL_' . strtoupper($dll)],
  334. 'RESULT' => '<strong style="color:green">' . $lang['AVAILABLE'] . '</strong>',
  335. 'S_EXPLAIN' => false,
  336. 'S_LEGEND' => false,
  337. ));
  338. }
  339. // Can we find ImageMagick anywhere on the system?
  340. $exe = (DIRECTORY_SEPARATOR == '\\') ? '.exe' : '';
  341. $magic_home = getenv('MAGICK_HOME');
  342. $img_imagick = '';
  343. if (empty($magic_home))
  344. {
  345. $locations = array('C:/WINDOWS/', 'C:/WINNT/', 'C:/WINDOWS/SYSTEM/', 'C:/WINNT/SYSTEM/', 'C:/WINDOWS/SYSTEM32/', 'C:/WINNT/SYSTEM32/', '/usr/bin/', '/usr/sbin/', '/usr/local/bin/', '/usr/local/sbin/', '/opt/', '/usr/imagemagick/', '/usr/bin/imagemagick/');
  346. $path_locations = str_replace('\\', '/', (explode(($exe) ? ';' : ':', getenv('PATH'))));
  347. $locations = array_merge($path_locations, $locations);
  348. foreach ($locations as $location)
  349. {
  350. // The path might not end properly, fudge it
  351. if (substr($location, -1, 1) !== '/')
  352. {
  353. $location .= '/';
  354. }
  355. if (@file_exists($location) && @is_readable($location . 'mogrify' . $exe) && @filesize($location . 'mogrify' . $exe) > 3000)
  356. {
  357. $img_imagick = str_replace('\\', '/', $location);
  358. continue;
  359. }
  360. }
  361. }
  362. else
  363. {
  364. $img_imagick = str_replace('\\', '/', $magic_home);
  365. }
  366. $template->assign_block_vars('checks', array(
  367. 'TITLE' => $lang['APP_MAGICK'],
  368. 'RESULT' => ($img_imagick) ? '<strong style="color:green">' . $lang['AVAILABLE'] . ', ' . $img_imagick . '</strong>' : '<strong style="color:blue">' . $lang['NO_LOCATION'] . '</strong>',
  369. 'S_EXPLAIN' => false,
  370. 'S_LEGEND' => false,
  371. ));
  372. // Check permissions on files/directories we need access to
  373. $template->assign_block_vars('checks', array(
  374. 'S_LEGEND' => true,
  375. 'LEGEND' => $lang['FILES_REQUIRED'],
  376. 'LEGEND_EXPLAIN' => $lang['FILES_REQUIRED_EXPLAIN'],
  377. ));
  378. $directories = array('cache/', 'files/', 'store/');
  379. umask(0);
  380. $passed['files'] = true;
  381. foreach ($directories as $dir)
  382. {
  383. $exists = $write = false;
  384. // Try to create the directory if it does not exist
  385. if (!file_exists($phpbb_root_path . $dir))
  386. {
  387. @mkdir($phpbb_root_path . $dir, 0777);
  388. phpbb_chmod($phpbb_root_path . $dir, CHMOD_READ | CHMOD_WRITE);
  389. }
  390. // Now really check
  391. if (file_exists($phpbb_root_path . $dir) && is_dir($phpbb_root_path . $dir))
  392. {
  393. phpbb_chmod($phpbb_root_path . $dir, CHMOD_READ | CHMOD_WRITE);
  394. $exists = true;
  395. }
  396. // Now check if it is writable by storing a simple file
  397. $fp = @fopen($phpbb_root_path . $dir . 'test_lock', 'wb');
  398. if ($fp !== false)
  399. {
  400. $write = true;
  401. }
  402. @fclose($fp);
  403. @unlink($phpbb_root_path . $dir . 'test_lock');
  404. $passed['files'] = ($exists && $write && $passed['files']) ? true : false;
  405. $exists = ($exists) ? '<strong style="color:green">' . $lang['FOUND'] . '</strong>' : '<strong style="color:red">' . $lang['NOT_FOUND'] . '</strong>';
  406. $write = ($write) ? ', <strong style="color:green">' . $lang['WRITABLE'] . '</strong>' : (($exists) ? ', <strong style="color:red">' . $lang['UNWRITABLE'] . '</strong>' : '');
  407. $template->assign_block_vars('checks', array(
  408. 'TITLE' => $dir,
  409. 'RESULT' => $exists . $write,
  410. 'S_EXPLAIN' => false,
  411. 'S_LEGEND' => false,
  412. ));
  413. }
  414. // Check permissions on files/directories it would be useful access to
  415. $template->assign_block_vars('checks', array(
  416. 'S_LEGEND' => true,
  417. 'LEGEND' => $lang['FILES_OPTIONAL'],
  418. 'LEGEND_EXPLAIN' => $lang['FILES_OPTIONAL_EXPLAIN'],
  419. ));
  420. $directories = array('config.' . $phpEx, 'images/avatars/upload/');
  421. foreach ($directories as $dir)
  422. {
  423. $write = $exists = true;
  424. if (file_exists($phpbb_root_path . $dir))
  425. {
  426. if (!phpbb_is_writable($phpbb_root_path . $dir))
  427. {
  428. $write = false;
  429. }
  430. }
  431. else
  432. {
  433. $write = $exists = false;
  434. }
  435. $exists_str = ($exists) ? '<strong style="color:green">' . $lang['FOUND'] . '</strong>' : '<strong style="color:red">' . $lang['NOT_FOUND'] . '</strong>';
  436. $write_str = ($write) ? ', <strong style="color:green">' . $lang['WRITABLE'] . '</strong>' : (($exists) ? ', <strong style="color:red">' . $lang['UNWRITABLE'] . '</strong>' : '');
  437. $template->assign_block_vars('checks', array(
  438. 'TITLE' => $dir,
  439. 'RESULT' => $exists_str . $write_str,
  440. 'S_EXPLAIN' => false,
  441. 'S_LEGEND' => false,
  442. ));
  443. }
  444. // And finally where do we want to go next (well today is taken isn't it :P)
  445. $s_hidden_fields = ($img_imagick) ? '<input type="hidden" name="img_imagick" value="' . addslashes($img_imagick) . '" />' : '';
  446. $url = (!in_array(false, $passed)) ? $this->p_master->module_url . "?mode=$mode&amp;sub=database&amp;language=$language" : $this->p_master->module_url . "?mode=$mode&amp;sub=requirements&amp;language=$language ";
  447. $submit = (!in_array(false, $passed)) ? $lang['INSTALL_START'] : $lang['INSTALL_TEST'];
  448. $template->assign_vars(array(
  449. 'L_SUBMIT' => $submit,
  450. 'S_HIDDEN' => $s_hidden_fields,
  451. 'U_ACTION' => $url,
  452. ));
  453. }
  454. /**
  455. * Obtain the information required to connect to the database
  456. */
  457. function obtain_database_settings($mode, $sub)
  458. {
  459. global $lang, $template, $phpEx;
  460. $this->page_title = $lang['STAGE_DATABASE'];
  461. // Obtain any submitted data
  462. $data = $this->get_submitted_data();
  463. $connect_test = false;
  464. $error = array();
  465. $available_dbms = get_available_dbms(false, true);
  466. // Has the user opted to test the connection?
  467. if (isset($_POST['testdb']))
  468. {
  469. if (!isset($available_dbms[$data['dbms']]) || !$available_dbms[$data['dbms']]['AVAILABLE'])
  470. {
  471. $error[] = $lang['INST_ERR_NO_DB'];
  472. $connect_test = false;
  473. }
  474. else if (!preg_match(get_preg_expression('table_prefix'), $data['table_prefix']))
  475. {
  476. $error[] = $lang['INST_ERR_DB_INVALID_PREFIX'];
  477. $connect_test = false;
  478. }
  479. else
  480. {
  481. $connect_test = connect_check_db(true, $error, $available_dbms[$data['dbms']], $data['table_prefix'], $data['dbhost'], $data['dbuser'], htmlspecialchars_decode($data['dbpasswd']), $data['dbname'], $data['dbport']);
  482. }
  483. $template->assign_block_vars('checks', array(
  484. 'S_LEGEND' => true,
  485. 'LEGEND' => $lang['DB_CONNECTION'],
  486. 'LEGEND_EXPLAIN' => false,
  487. ));
  488. if ($connect_test)
  489. {
  490. $template->assign_block_vars('checks', array(
  491. 'TITLE' => $lang['DB_TEST'],
  492. 'RESULT' => '<strong style="color:green">' . $lang['SUCCESSFUL_CONNECT'] . '</strong>',
  493. 'S_EXPLAIN' => false,
  494. 'S_LEGEND' => false,
  495. ));
  496. }
  497. else
  498. {
  499. $template->assign_block_vars('checks', array(
  500. 'TITLE' => $lang['DB_TEST'],
  501. 'RESULT' => '<strong style="color:red">' . implode('<br />', $error) . '</strong>',
  502. 'S_EXPLAIN' => false,
  503. 'S_LEGEND' => false,
  504. ));
  505. }
  506. }
  507. if (!$connect_test)
  508. {
  509. // Update the list of available DBMS modules to only contain those which can be used
  510. $available_dbms_temp = array();
  511. foreach ($available_dbms as $type => $dbms_ary)
  512. {
  513. if (!$dbms_ary['AVAILABLE'])
  514. {
  515. continue;
  516. }
  517. $available_dbms_temp[$type] = $dbms_ary;
  518. }
  519. $available_dbms = &$available_dbms_temp;
  520. // And now for the main part of this page
  521. $data['table_prefix'] = (!empty($data['table_prefix']) ? $data['table_prefix'] : 'phpbb_');
  522. foreach ($this->db_config_options as $config_key => $vars)
  523. {
  524. if (!is_array($vars) && strpos($config_key, 'legend') === false)
  525. {
  526. continue;
  527. }
  528. if (strpos($config_key, 'legend') !== false)
  529. {
  530. $template->assign_block_vars('options', array(
  531. 'S_LEGEND' => true,
  532. 'LEGEND' => $lang[$vars])
  533. );
  534. continue;
  535. }
  536. $options = isset($vars['options']) ? $vars['options'] : '';
  537. $template->assign_block_vars('options', array(
  538. 'KEY' => $config_key,
  539. 'TITLE' => $lang[$vars['lang']],
  540. 'S_EXPLAIN' => $vars['explain'],
  541. 'S_LEGEND' => false,
  542. 'TITLE_EXPLAIN' => ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '',
  543. 'CONTENT' => $this->p_master->input_field($config_key, $vars['type'], $data[$config_key], $options),
  544. )
  545. );
  546. }
  547. }
  548. // And finally where do we want to go next (well today is taken isn't it :P)
  549. $s_hidden_fields = ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
  550. $s_hidden_fields .= '<input type="hidden" name="language" value="' . $data['language'] . '" />';
  551. if ($connect_test)
  552. {
  553. foreach ($this->db_config_options as $config_key => $vars)
  554. {
  555. if (!is_array($vars))
  556. {
  557. continue;
  558. }
  559. $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
  560. }
  561. }
  562. $url = ($connect_test) ? $this->p_master->module_url . "?mode=$mode&amp;sub=administrator" : $this->p_master->module_url . "?mode=$mode&amp;sub=database";
  563. $s_hidden_fields .= ($connect_test) ? '' : '<input type="hidden" name="testdb" value="true" />';
  564. $submit = $lang['NEXT_STEP'];
  565. $template->assign_vars(array(
  566. 'L_SUBMIT' => $submit,
  567. 'S_HIDDEN' => $s_hidden_fields,
  568. 'U_ACTION' => $url,
  569. ));
  570. }
  571. /**
  572. * Obtain the administrator's name, password and email address
  573. */
  574. function obtain_admin_settings($mode, $sub)
  575. {
  576. global $lang, $template, $phpEx;
  577. $this->page_title = $lang['STAGE_ADMINISTRATOR'];
  578. // Obtain any submitted data
  579. $data = $this->get_submitted_data();
  580. if ($data['dbms'] == '')
  581. {
  582. // Someone's been silly and tried calling this page direct
  583. // So we send them back to the start to do it again properly
  584. $this->p_master->redirect("index.$phpEx?mode=install");
  585. }
  586. $s_hidden_fields = ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
  587. $passed = false;
  588. $data['default_lang'] = ($data['default_lang'] !== '') ? $data['default_lang'] : $data['language'];
  589. if (isset($_POST['check']))
  590. {
  591. $error = array();
  592. // Check the entered email address and password
  593. if ($data['admin_name'] == '' || $data['admin_pass1'] == '' || $data['admin_pass2'] == '' || $data['board_email'] == '')
  594. {
  595. $error[] = $lang['INST_ERR_MISSING_DATA'];
  596. }
  597. if ($data['admin_pass1'] != $data['admin_pass2'] && $data['admin_pass1'] != '')
  598. {
  599. $error[] = $lang['INST_ERR_PASSWORD_MISMATCH'];
  600. }
  601. // Test against the default username rules
  602. if ($data['admin_name'] != '' && utf8_strlen($data['admin_name']) < 3)
  603. {
  604. $error[] = $lang['INST_ERR_USER_TOO_SHORT'];
  605. }
  606. if ($data['admin_name'] != '' && utf8_strlen($data['admin_name']) > 20)
  607. {
  608. $error[] = $lang['INST_ERR_USER_TOO_LONG'];
  609. }
  610. // Test against the default password rules
  611. if ($data['admin_pass1'] != '' && utf8_strlen($data['admin_pass1']) < 6)
  612. {
  613. $error[] = $lang['INST_ERR_PASSWORD_TOO_SHORT'];
  614. }
  615. if ($data['admin_pass1'] != '' && utf8_strlen($data['admin_pass1']) > 30)
  616. {
  617. $error[] = $lang['INST_ERR_PASSWORD_TOO_LONG'];
  618. }
  619. if ($data['board_email'] != '' && !preg_match('/^' . get_preg_expression('email') . '$/i', $data['board_email']))
  620. {
  621. $error[] = $lang['INST_ERR_EMAIL_INVALID'];
  622. }
  623. $template->assign_block_vars('checks', array(
  624. 'S_LEGEND' => true,
  625. 'LEGEND' => $lang['STAGE_ADMINISTRATOR'],
  626. 'LEGEND_EXPLAIN' => false,
  627. ));
  628. if (!sizeof($error))
  629. {
  630. $passed = true;
  631. $template->assign_block_vars('checks', array(
  632. 'TITLE' => $lang['ADMIN_TEST'],
  633. 'RESULT' => '<strong style="color:green">' . $lang['TESTS_PASSED'] . '</strong>',
  634. 'S_EXPLAIN' => false,
  635. 'S_LEGEND' => false,
  636. ));
  637. }
  638. else
  639. {
  640. $template->assign_block_vars('checks', array(
  641. 'TITLE' => $lang['ADMIN_TEST'],
  642. 'RESULT' => '<strong style="color:red">' . implode('<br />', $error) . '</strong>',
  643. 'S_EXPLAIN' => false,
  644. 'S_LEGEND' => false,
  645. ));
  646. }
  647. }
  648. if (!$passed)
  649. {
  650. foreach ($this->admin_config_options as $config_key => $vars)
  651. {
  652. if (!is_array($vars) && strpos($config_key, 'legend') === false)
  653. {
  654. continue;
  655. }
  656. if (strpos($config_key, 'legend') !== false)
  657. {
  658. $template->assign_block_vars('options', array(
  659. 'S_LEGEND' => true,
  660. 'LEGEND' => $lang[$vars])
  661. );
  662. continue;
  663. }
  664. $options = isset($vars['options']) ? $vars['options'] : '';
  665. $template->assign_block_vars('options', array(
  666. 'KEY' => $config_key,
  667. 'TITLE' => $lang[$vars['lang']],
  668. 'S_EXPLAIN' => $vars['explain'],
  669. 'S_LEGEND' => false,
  670. 'TITLE_EXPLAIN' => ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '',
  671. 'CONTENT' => $this->p_master->input_field($config_key, $vars['type'], $data[$config_key], $options),
  672. )
  673. );
  674. }
  675. }
  676. else
  677. {
  678. foreach ($this->admin_config_options as $config_key => $vars)
  679. {
  680. if (!is_array($vars))
  681. {
  682. continue;
  683. }
  684. $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
  685. }
  686. }
  687. $s_hidden_fields .= ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
  688. $s_hidden_fields .= '<input type="hidden" name="language" value="' . $data['language'] . '" />';
  689. foreach ($this->db_config_options as $config_key => $vars)
  690. {
  691. if (!is_array($vars))
  692. {
  693. continue;
  694. }
  695. $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
  696. }
  697. $submit = $lang['NEXT_STEP'];
  698. $url = ($passed) ? $this->p_master->module_url . "?mode=$mode&amp;sub=config_file" : $this->p_master->module_url . "?mode=$mode&amp;sub=administrator";
  699. $s_hidden_fields .= ($passed) ? '' : '<input type="hidden" name="check" value="true" />';
  700. $template->assign_vars(array(
  701. 'L_SUBMIT' => $submit,
  702. 'S_HIDDEN' => $s_hidden_fields,
  703. 'U_ACTION' => $url,
  704. ));
  705. }
  706. /**
  707. * Writes the config file to disk, or if unable to do so offers alternative methods
  708. */
  709. function create_config_file($mode, $sub)
  710. {
  711. global $lang, $template, $phpbb_root_path, $phpEx;
  712. $this->page_title = $lang['STAGE_CONFIG_FILE'];
  713. // Obtain any submitted data
  714. $data = $this->get_submitted_data();
  715. if ($data['dbms'] == '')
  716. {
  717. // Someone's been silly and tried calling this page direct
  718. // So we send them back to the start to do it again properly
  719. $this->p_master->redirect("index.$phpEx?mode=install");
  720. }
  721. $s_hidden_fields = ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
  722. $s_hidden_fields .= '<input type="hidden" name="language" value="' . $data['language'] . '" />';
  723. $written = false;
  724. // Create a list of any PHP modules we wish to have loaded
  725. $available_dbms = get_available_dbms($data['dbms']);
  726. // Create a lock file to indicate that there is an install in progress
  727. $fp = @fopen($phpbb_root_path . 'cache/install_lock', 'wb');
  728. if ($fp === false)
  729. {
  730. // We were unable to create the lock file - abort
  731. $this->p_master->error($lang['UNABLE_WRITE_LOCK'], __LINE__, __FILE__);
  732. }
  733. @fclose($fp);
  734. @chmod($phpbb_root_path . 'cache/install_lock', 0777);
  735. // Time to convert the data provided into a config file
  736. $config_data = phpbb_create_config_file_data($data, $available_dbms[$data['dbms']]['DRIVER']);
  737. // Attempt to write out the config file directly. If it works, this is the easiest way to do it ...
  738. if ((file_exists($phpbb_root_path . 'config.' . $phpEx) && phpbb_is_writable($phpbb_root_path . 'config.' . $phpEx)) || phpbb_is_writable($phpbb_root_path))
  739. {
  740. // Assume it will work ... if nothing goes wrong below
  741. $written = true;
  742. if (!($fp = @fopen($phpbb_root_path . 'config.' . $phpEx, 'w')))
  743. {
  744. // Something went wrong ... so let's try another method
  745. $written = false;
  746. }
  747. if (!(@fwrite($fp, $config_data)))
  748. {
  749. // Something went wrong ... so let's try another method
  750. $written = false;
  751. }
  752. @fclose($fp);
  753. if ($written)
  754. {
  755. // We may revert back to chmod() if we see problems with users not able to change their config.php file directly
  756. phpbb_chmod($phpbb_root_path . 'config.' . $phpEx, CHMOD_READ);
  757. }
  758. }
  759. if (isset($_POST['dldone']))
  760. {
  761. // Do a basic check to make sure that the file has been uploaded
  762. // Note that all we check is that the file has _something_ in it
  763. // We don't compare the contents exactly - if they can't upload
  764. // a single file correctly, it's likely they will have other problems....
  765. if (filesize($phpbb_root_path . 'config.' . $phpEx) > 10)
  766. {
  767. $written = true;
  768. }
  769. }
  770. $config_options = array_merge($this->db_config_options, $this->admin_config_options);
  771. foreach ($config_options as $config_key => $vars)
  772. {
  773. if (!is_array($vars))
  774. {
  775. continue;
  776. }
  777. $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
  778. }
  779. if (!$written)
  780. {
  781. // OK, so it didn't work let's try the alternatives
  782. if (isset($_POST['dlconfig']))
  783. {
  784. // They want a copy of the file to download, so send the relevant headers and dump out the data
  785. header("Content-Type: text/x-delimtext; name=\"config.$phpEx\"");
  786. header("Content-disposition: attachment; filename=config.$phpEx");
  787. echo $config_data;
  788. exit;
  789. }
  790. // The option to download the config file is always available, so output it here
  791. $template->assign_vars(array(
  792. 'BODY' => $lang['CONFIG_FILE_UNABLE_WRITE'],
  793. 'L_DL_CONFIG' => $lang['DL_CONFIG'],
  794. 'L_DL_CONFIG_EXPLAIN' => $lang['DL_CONFIG_EXPLAIN'],
  795. 'L_DL_DONE' => $lang['DONE'],
  796. 'L_DL_DOWNLOAD' => $lang['DL_DOWNLOAD'],
  797. 'S_HIDDEN' => $s_hidden_fields,
  798. 'S_SHOW_DOWNLOAD' => true,
  799. 'U_ACTION' => $this->p_master->module_url . "?mode=$mode&amp;sub=config_file",
  800. ));
  801. return;
  802. }
  803. else
  804. {
  805. $template->assign_vars(array(
  806. 'BODY' => $lang['CONFIG_FILE_WRITTEN'],
  807. 'L_SUBMIT' => $lang['NEXT_STEP'],
  808. 'S_HIDDEN' => $s_hidden_fields,
  809. 'U_ACTION' => $this->p_master->module_url . "?mode=$mode&amp;sub=advanced",
  810. ));
  811. return;
  812. }
  813. }
  814. /**
  815. * Provide an opportunity to customise some advanced settings during the install
  816. * in case it is necessary for them to be set to access later
  817. */
  818. function obtain_advanced_settings($mode, $sub)
  819. {
  820. global $lang, $template, $phpEx, $request;
  821. $this->page_title = $lang['STAGE_ADVANCED'];
  822. // Obtain any submitted data
  823. $data = $this->get_submitted_data();
  824. if ($data['dbms'] == '')
  825. {
  826. // Someone's been silly and tried calling this page direct
  827. // So we send them back to the start to do it again properly
  828. $this->p_master->redirect("index.$phpEx?mode=install");
  829. }
  830. $s_hidden_fields = ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
  831. $s_hidden_fields .= '<input type="hidden" name="language" value="' . $data['language'] . '" />';
  832. // HTTP_HOST is having the correct browser url in most cases...
  833. $server_name = strtolower(htmlspecialchars_decode($request->header('Host', $request->server('SERVER_NAME'))));
  834. // HTTP HOST can carry a port number...
  835. if (strpos($server_name, ':') !== false)
  836. {
  837. $server_name = substr($server_name, 0, strpos($server_name, ':'));
  838. }
  839. $data['email_enable'] = ($data['email_enable'] !== '') ? $data['email_enable'] : true;
  840. $data['server_name'] = ($data['server_name'] !== '') ? $data['server_name'] : $server_name;
  841. $data['server_port'] = ($data['server_port'] !== '') ? $data['server_port'] : $request->server('SERVER_PORT', 0);
  842. $data['server_protocol'] = ($data['server_protocol'] !== '') ? $data['server_protocol'] : ($request->is_secure() ? 'https://' : 'http://');
  843. $data['cookie_secure'] = ($data['cookie_secure'] !== '') ? $data['cookie_secure'] : $request->is_secure();
  844. if ($data['script_path'] === '')
  845. {
  846. $name = htmlspecialchars_decode($request->server('PHP_SELF'));
  847. if (!$name)
  848. {
  849. $name = htmlspecialchars_decode($request->server('REQUEST_URI'));
  850. }
  851. // Replace backslashes and doubled slashes (could happen on some proxy setups)
  852. $name = str_replace(array('\\', '//'), '/', $name);
  853. $data['script_path'] = trim(dirname(dirname($name)));
  854. }
  855. foreach ($this->advanced_config_options as $config_key => $vars)
  856. {
  857. if (!is_array($vars) && strpos($config_key, 'legend') === false)
  858. {
  859. continue;
  860. }
  861. if (strpos($config_key, 'legend') !== false)
  862. {
  863. $template->assign_block_vars('options', array(
  864. 'S_LEGEND' => true,
  865. 'LEGEND' => $lang[$vars])
  866. );
  867. continue;
  868. }
  869. $options = isset($vars['options']) ? $vars['options'] : '';
  870. $template->assign_block_vars('options', array(
  871. 'KEY' => $config_key,
  872. 'TITLE' => $lang[$vars['lang']],
  873. 'S_EXPLAIN' => $vars['explain'],
  874. 'S_LEGEND' => false,
  875. 'TITLE_EXPLAIN' => ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '',
  876. 'CONTENT' => $this->p_master->input_field($config_key, $vars['type'], $data[$config_key], $options),
  877. )
  878. );
  879. }
  880. $config_options = array_merge($this->db_config_options, $this->admin_config_options);
  881. foreach ($config_options as $config_key => $vars)
  882. {
  883. if (!is_array($vars))
  884. {
  885. continue;
  886. }
  887. $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
  888. }
  889. $submit = $lang['NEXT_STEP'];
  890. $url = $this->p_master->module_url . "?mode=$mode&amp;sub=create_table";
  891. $template->assign_vars(array(
  892. 'BODY' => $lang['STAGE_ADVANCED_EXPLAIN'],
  893. 'L_SUBMIT' => $submit,
  894. 'S_HIDDEN' => $s_hidden_fields,
  895. 'U_ACTION' => $url,
  896. ));
  897. }
  898. /**
  899. * Load the contents of the schema into the database and then alter it based on what has been input during the installation
  900. */
  901. function load_schema($mode, $sub)
  902. {
  903. global $db, $lang, $template, $phpbb_root_path, $phpEx, $request;
  904. $this->page_title = $lang['STAGE_CREATE_TABLE'];
  905. $s_hidden_fields = '';
  906. // Obtain any submitted data
  907. $data = $this->get_submitted_data();
  908. if ($data['dbms'] == '')
  909. {
  910. // Someone's been silly and tried calling this page direct
  911. // So we send them back to the start to do it again properly
  912. $this->p_master->redirect("index.$phpEx?mode=install");
  913. }
  914. // HTTP_HOST is having the correct browser url in most cases...
  915. $server_name = strtolower(htmlspecialchars_decode($request->header('Host', $request->server('SERVER_NAME'))));
  916. $referer = strtolower($request->header('Referer'));
  917. // HTTP HOST can carry a port number...
  918. if (strpos($server_name, ':') !== false)
  919. {
  920. $server_name = substr($server_name, 0, strpos($server_name, ':'));
  921. }
  922. $cookie_domain = ($data['server_name'] != '') ? $data['server_name'] : $server_name;
  923. // Try to come up with the best solution for cookie domain...
  924. if (strpos($cookie_domain, 'www.') === 0)
  925. {
  926. $cookie_domain = str_replace('www.', '.', $cookie_domain);
  927. }
  928. // If we get here and the extension isn't loaded it should be safe to just go ahead and load it
  929. $available_dbms = get_available_dbms($data['dbms']);
  930. if (!isset($available_dbms[$data['dbms']]))
  931. {
  932. // Someone's been silly and tried providing a non-existant dbms
  933. $this->p_master->redirect("index.$phpEx?mode=install");
  934. }
  935. $dbms = $available_dbms[$data['dbms']]['DRIVER'];
  936. // Instantiate the database
  937. $db = new $dbms();
  938. $db->sql_connect($data['dbhost'], $data['dbuser'], htmlspecialchars_decode($data['dbpasswd']), $data['dbname'], $data['dbport'], false, false);
  939. // NOTE: trigger_error does not work here.
  940. $db->sql_return_on_error(true);
  941. // If mysql is chosen, we need to adjust the schema filename slightly to reflect the correct version. ;)
  942. if ($data['dbms'] == 'mysql')
  943. {
  944. if (version_compare($db->sql_server_info(true), '4.1.3', '>='))
  945. {
  946. $available_dbms[$data['dbms']]['SCHEMA'] .= '_41';
  947. }
  948. else
  949. {
  950. $available_dbms[$data['dbms']]['SCHEMA'] .= '_40';
  951. }
  952. }
  953. // Ok we have the db info go ahead and read in the relevant schema
  954. // and work on building the table
  955. $dbms_schema = 'schemas/' . $available_dbms[$data['dbms']]['SCHEMA'] . '_schema.sql';
  956. // How should we treat this schema?
  957. $delimiter = $available_dbms[$data['dbms']]['DELIM'];
  958. if (file_exists($dbms_schema))
  959. {
  960. $sql_query = @file_get_contents($dbms_schema);
  961. $sql_query = preg_replace('#phpbb_#i', $data['table_prefix'], $sql_query);
  962. $sql_query = phpbb_remove_comments($sql_query);
  963. $sql_query = split_sql_file($sql_query, $delimiter);
  964. foreach ($sql_query as $sql)
  965. {
  966. // Ignore errors when the functions or types already exist
  967. // to allow installing phpBB twice in the same database with
  968. // a different prefix
  969. $db->sql_query($sql);
  970. }
  971. unset($sql_query);
  972. }
  973. // Ok we have the db info go ahead and work on building the table
  974. if (file_exists('schemas/schema.json'))
  975. {
  976. $db_table_schema = @file_get_contents('schemas/schema.json');
  977. $db_table_schema = json_decode($db_table_schema, true);
  978. }
  979. else
  980. {
  981. global $phpbb_root_path, $phpEx, $table_prefix;
  982. $table_prefix = 'phpbb_';
  983. if (!defined('CONFIG_TABLE'))
  984. {
  985. // We need to include the constants file for the table constants
  986. // when we generate the schema from the migration files.
  987. include($phpbb_root_path . 'includes/constants.' . $phpEx);
  988. }
  989. $finder = new \phpbb\finder(new \phpbb\filesystem(), $phpbb_root_path, null, $phpEx);
  990. $classes = $finder->core_path('phpbb/db/migration/data/')
  991. ->get_classes();
  992. $sqlite_db = new \phpbb\db\driver\sqlite();
  993. $schema_generator = new \phpbb\db\migration\schema_generator($classes, new \phpbb\config\config(array()), $sqlite_db, new \phpbb\db\tools($sqlite_db, true), $phpbb_root_path, $phpEx, $table_prefix);
  994. $db_table_schema = $schema_generator->get_schema();
  995. }
  996. if (!defined('CONFIG_TABLE'))
  997. {
  998. // CONFIG_TABLE is required by sql_create_index() to check the
  999. // length of index names. However table_prefix is not defined
  1000. // here yet, so we need to create the constant ourselves.
  1001. define('CONFIG_TABLE', $data['table_prefix'] . 'config');
  1002. }
  1003. $db_tools = new \phpbb\db\tools($db);
  1004. foreach ($db_table_schema as $table_name => $table_data)
  1005. {
  1006. $db_tools->sql_create_table(
  1007. $data['table_prefix'] . substr($table_name, 6),
  1008. $table_data
  1009. );
  1010. }
  1011. // Ok tables have been built, let's fill in the basic information
  1012. $sql_query = file_get_contents('schemas/schema_data.sql');
  1013. // Deal with any special comments and characters
  1014. switch ($data['dbms'])
  1015. {
  1016. case 'mssql':
  1017. case 'mssql_odbc':
  1018. case 'mssqlnative':
  1019. $sql_query = preg_replace('#\# MSSQL IDENTITY (phpbb_[a-z_]+) (ON|OFF) \##s', 'SET IDENTITY_INSERT \1 \2;', $sql_query);
  1020. break;
  1021. case 'postgres':
  1022. $sql_query = preg_replace('#\# POSTGRES (BEGIN|COMMIT) \##s', '\1; ', $sql_query);
  1023. break;
  1024. case 'mysql':
  1025. case 'mysqli':
  1026. $sql_query = str_replace('\\', '\\\\', $sql_query);
  1027. break;
  1028. }
  1029. // Change prefix
  1030. $sql_query = preg_replace('# phpbb_([^\s]*) #i', ' ' . $data['table_prefix'] . '\1 ', $sql_query);
  1031. // Change language strings...
  1032. $sql_query = preg_replace_callback('#\{L_([A-Z0-9\-_]*)\}#s', 'adjust_language_keys_callback', $sql_query);
  1033. $sql_query = phpbb_remove_comments($sql_query);
  1034. $sql_query = split_sql_file($sql_query, ';');
  1035. foreach ($sql_query as $sql)
  1036. {
  1037. //$sql = trim(str_replace('|', ';', $sql));
  1038. if (!$db->sql_query($sql))
  1039. {
  1040. $error = $db->sql_error();
  1041. $this->p_master->db_error($error['message'], $sql, __LINE__, __FILE__);
  1042. }
  1043. }
  1044. unset($sql_query);
  1045. $current_time = time();
  1046. $user_ip = $request->server('REMOTE_ADDR') ? phpbb_ip_normalise($request->server('REMOTE_ADDR')) : '';
  1047. if ($data['script_path'] !== '/')
  1048. {
  1049. // Adjust destination path (no trailing slash)
  1050. if (substr($data['script_path'], -1) == '/')
  1051. {
  1052. $data['script_path'] = substr($data['script_path'], 0, -1);
  1053. }
  1054. $data['script_path'] = str_replace(array('../', './'), '', $data['script_path']);
  1055. if ($data['script_path'][0] != '/')
  1056. {
  1057. $data['script_path'] = '/' . $data['script_path'];
  1058. }
  1059. }
  1060. // Set default config and post data, this applies to all DB's
  1061. $sql_ary = array(
  1062. 'INSERT INTO ' . $data['table_prefix'] . "config (config_name, config_value)
  1063. VALUES ('board_startdate', '$current_time')",
  1064. 'INSERT INTO ' . $data['table_prefix'] . "config (config_name, config_value)
  1065. VALUES ('default_lang', '" . $db->sql_escape($data['default_lang']) . "')",
  1066. 'UPDATE ' . $data['table_prefix'] . "config
  1067. SET config_value = '" . $db->sql_escape($data['img_imagick']) . "'
  1068. WHERE config_name = 'img_imagick'",
  1069. 'UPDATE ' . $data['table_prefix'] . "config
  1070. SET config_value = '" . $db->sql_escape($data['server_name']) . "'
  1071. WHERE config_name = 'server_name'",
  1072. 'UPDATE ' . $data['table_prefix'] . "config
  1073. SET config_value = '" . $db->sql_escape($data['server_port']) . "'
  1074. WHERE config_name = 'server_port'",
  1075. 'UPDATE ' . $data['table_prefix'] . "config
  1076. SET config_value = '" . $db->sql_escape($data['board_email']) . "'
  1077. WHERE config_name = 'board_email'",
  1078. 'UPDATE ' . $data['table_prefix'] . "config
  1079. SET config_value = '" . $db->sql_escape($data['board_email']) . "'
  1080. WHERE config_name = 'board_contact'",
  1081. 'UPDATE ' . $data['table_prefix'] . "config
  1082. SET config_value = '" . $db->sql_escape($cookie_domain) . "'
  1083. WHERE config_name = 'cookie_domain'",
  1084. 'UPDATE ' . $data['table_prefix'] . "config
  1085. SET config_value = '" . $db->sql_escape($lang['default_dateformat']) . "'
  1086. WHERE config_name = 'default_dateformat'",
  1087. 'UPDATE ' . $data['table_prefix'] . "config
  1088. SET config_value = '" . $db->sql_escape($data['email_enable']) . "'
  1089. WHERE config_name = 'email_enable'",
  1090. 'UPDATE ' . $data['table_prefix'] . "config
  1091. SET config_value = '" . $db->sql_escape($data['smtp_delivery']) . "'
  1092. WHERE config_name = 'smtp_delivery'",
  1093. 'UPDATE ' . $data['table_prefix'] . "config
  1094. SET config_value = '" . $db->sql_escape($data['smtp_host']) . "'
  1095. WHERE config_name = 'smtp_host'",
  1096. 'UPDATE ' . $data['table_prefix'] . "config
  1097. SET config_value = '" . $db->sql_escape($data['smtp_auth']) . "'
  1098. WHERE config_name = 'smtp_auth_method'",
  1099. 'UPDATE ' . $data['table_prefix'] . "config
  1100. SET config_value = '" . $db->sql_escape($data['smtp_user']) . "'
  1101. WHERE config_name = 'smtp_username'",
  1102. 'UPDATE ' . $data['table_prefix'] . "config
  1103. SET config_value = '" . $db->sql_escape($data['smtp_pass']) . "'
  1104. WHERE config_name = 'smtp_password'",
  1105. 'UPDATE ' . $data['table_prefix'] . "config
  1106. SET config_value = '" . $db->sql_escape($data['cookie_secure']) . "'
  1107. WHERE config_name = 'cookie_secure'",
  1108. 'UPDATE ' . $data['table_prefix'] . "config
  1109. SET config_value = '" . $db->sql_escape($data['force_server_vars']) . "'
  1110. WHERE config_name = 'force_server_vars'",
  1111. 'UPDATE ' . $data['table_prefix'] . "config
  1112. SET config_value = '" . $db->sql_escape($data['script_path']) . "'
  1113. WHERE config_name = 'script_path'",
  1114. 'UPDATE ' . $data['table_prefix'] . "config
  1115. SET config_value = '" . $db->sql_escape($data['server_protocol']) . "'
  1116. WHERE config_name = 'server_protocol'",
  1117. 'UPDATE ' . $data['table_prefix'] . "config
  1118. SET config_value = '" . $db->sql_escape($data['admin_name']) . "'
  1119. WHERE config_name = 'newest_username'",
  1120. 'UPDATE ' . $data['table_prefix'] . "config
  1121. SET config_value = '" . md5(mt_rand()) . "'
  1122. WHERE config_name = 'avatar_salt'",
  1123. 'UPDATE ' . $data['table_prefix'] . "config
  1124. SET config_value = '" . md5(mt_rand()) . "'
  1125. WHERE config_name = 'plupload_salt'",
  1126. 'UPDATE ' . $data['table_prefix'] . "users
  1127. SET username = '" . $db->sql_escape($data['admin_name']) . "', user_password='" . $db->sql_escape(md5($data['admin_pass1'])) . "', user_ip = '" . $db->sql_escape($user_ip) . "', user_lang = '" . $db->sql_escape($data['default_lang']) . "', user_email='" . $db->sql_escape($data['board_email']) . "', user_dateformat='" . $db->sql_escape($lang['default_dateformat']) . "', user_email_hash = " . $db->sql_escape(phpbb_email_hash($data['board_email'])) . ", username_clean = '" . $db->sql_escape(utf8_clean_string($data['admin_name'])) . "'
  1128. WHERE username = 'Admin'",
  1129. 'UPDATE ' . $data['table_prefix'] . "moderator_cache
  1130. SET username = '" . $db->sql_escape($data['admin_name']) . "'
  1131. WHERE username = 'Admin'",
  1132. 'UPDATE ' . $data['table_prefix'] . "forums
  1133. SET forum_last_poster_name = '" . $db->sql_escape($data['admin_name']) . "'
  1134. WHERE forum_last_poster_name = 'Admin'",
  1135. 'UPDATE ' . $data['table_prefix'] . "topics
  1136. SET topic_first_poster_name = '" . $db->sql_escape($data['admin_name']) . "', topic_last_poster_name = '" . $db->sql_escape($data['admin_name']) . "'
  1137. WHERE topic_first_poster_name = 'Admin'
  1138. OR topic_last_poster_name = 'Admin'",
  1139. 'UPDATE ' . $data['table_prefix'] . "users
  1140. SET user_regdate = $current_time",
  1141. 'UPDATE ' . $data['table_prefix'] . "posts
  1142. SET post_time = $current_time, poster_ip = '" . $db->sql_escape($user_ip) . "'",
  1143. 'UPDATE ' . $data['table_prefix'] . "topics
  1144. SET topic_time = $current_time, topic_last_post_time = $current_time",
  1145. 'UPDATE ' . $data['table_prefix'] . "forums
  1146. SET forum_last_post_time = $current_time",
  1147. 'UPDATE ' . $data['table_prefix'] . "config
  1148. SET config_value = '" . $db->sql_escape($db->sql_server_info(true)) . "'
  1149. WHERE config_name = 'dbms_version'",
  1150. );
  1151. if (@extension_loaded('gd'))
  1152. {
  1153. $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
  1154. SET config_value = 'core.captcha.plugins.gd'
  1155. WHERE config_name = 'captcha_plugin'";
  1156. $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
  1157. SET config_value = '1'
  1158. WHERE config_name = 'captcha_gd'";
  1159. }
  1160. $ref = substr($referer, strpos($referer, '://') + 3);
  1161. if (!(stripos($ref, $server_name) === 0))
  1162. {
  1163. $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
  1164. SET config_value = '0'
  1165. WHERE config_name = 'referer_validation'";
  1166. }
  1167. // We set a (semi-)unique cookie name to bypass login issues related to the cookie name.
  1168. $cookie_name = 'phpbb3_';
  1169. $rand_str = md5(mt_rand());
  1170. $rand_str = str_replace('0', 'z', base_convert($rand_str, 16, 35));
  1171. $rand_str = substr($rand_str, 0, 5);
  1172. $cookie_name .= strtolower($rand_str);
  1173. $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
  1174. SET config_value = '" . $db->sql_escape($cookie_name) . "'
  1175. WHERE config_name = 'cookie_name'";
  1176. foreach ($sql_ary as $sql)
  1177. {
  1178. //$sql = trim(str_replace('|', ';', $sql));
  1179. if (!$db->sql_query($sql))
  1180. {
  1181. $error = $db->sql_error();
  1182. $this->p_master->db_error($error['message'], $sql, __LINE__, __FILE__);
  1183. }
  1184. }
  1185. $submit = $lang['NEXT_STEP'];
  1186. $url = $this->p_master->module_url . "?mode=$mode&amp;sub=final";
  1187. $template->assign_vars(array(
  1188. 'BODY' => $lang['STAGE_CREATE_TABLE_EXPLAIN'],
  1189. 'L_SUBMIT' => $submit,
  1190. 'S_HIDDEN' => build_hidden_fields($data),
  1191. 'U_ACTION' => $url,
  1192. ));
  1193. }
  1194. /**
  1195. * Build the search index...
  1196. */
  1197. function build_search_index($mode, $sub)
  1198. {
  1199. global $db, $lang, $phpbb_root_path, $phpbb_dispatcher, $phpEx, $config, $auth, $user;
  1200. // Obtain any submitted data
  1201. $data = $this->get_submitted_data();
  1202. $table_prefix = $data['table_prefix'];
  1203. // If we get here and the extension isn't loaded it should be safe to just go ahead and load it
  1204. $available_dbms = get_available_dbms($data['dbms']);
  1205. if (!isset($available_dbms[$data['dbms']]))
  1206. {
  1207. // Someone's been silly and tried providing a non-existant dbms
  1208. $this->p_master->redirect("index.$phpEx?mode=install");
  1209. }
  1210. $dbms = $available_dbms[$data['dbms']]['DRIVER'];
  1211. // Instantiate the database
  1212. $db = new $dbms();
  1213. $db->sql_connect($data['dbhost'], $data['dbuser'], htmlspecialchars_decode($data['dbpasswd']), $data['dbname'], $data['dbport'], false, false);
  1214. // NOTE: trigger_error does not work here.
  1215. $db->sql_return_on_error(true);
  1216. include_once($phpbb_root_path . 'includes/constants.' . $phpEx);
  1217. include_once($phpbb_root_path . 'phpbb/search/fulltext_native.' . $phpEx);
  1218. // We need to fill the config to let internal functions correctly work
  1219. $config = new \phpbb\config\db($db, new \phpbb\cache\driver\null, CONFIG_TABLE);
  1220. set_config(null, null, null, $config);
  1221. set_config_count(null, null, null, $config);
  1222. $error = false;
  1223. $search = new \phpbb\search\fulltext_native($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
  1224. $sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id
  1225. FROM ' . POSTS_TABLE;
  1226. $result = $db->sql_query($sql);
  1227. while ($row = $db->sql_fetchrow($result))
  1228. {
  1229. $search->index('post', $row['post_id'], $row['post_text'], $row['post_subject'], $row['poster_id'], $row['forum_id']);
  1230. }
  1231. $db->sql_freeresult($result);
  1232. }
  1233. /**
  1234. * Populate the module tables
  1235. */
  1236. function add_modules($mode, $sub)
  1237. {
  1238. global $db, $lang, $phpbb_root_path, $phpEx, $phpbb_extension_manager, $config, $phpbb_container;
  1239. // modules require an extension manager
  1240. if (empty($phpbb_extension_manager))
  1241. {
  1242. $phpbb_extension_manager = $phpbb_container->get('ext.manager');
  1243. }
  1244. include_once($phpbb_root_path . 'includes/acp/acp_modules.' . $phpEx);
  1245. $_module = new acp_modules();
  1246. $module_classes = array('acp', 'mcp', 'ucp');
  1247. // Add categories
  1248. foreach ($module_classes as $module_class)
  1249. {
  1250. $categories = array();
  1251. // Set the module class
  1252. $_module->module_class = $module_class;
  1253. foreach ($this->module_categories[$module_class] as $cat_name => $subs)
  1254. {
  1255. $basename = '';
  1256. // Check if this sub-category has a basename. If it has, use it.
  1257. if (isset($this->module_categories_basenames[$cat_name]))
  1258. {
  1259. $basename = $this->module_categories_basenames[$cat_name];
  1260. }
  1261. $module_data = array(
  1262. 'module_basename' => $basename,
  1263. 'module_enabled' => 1,
  1264. 'module_display' => 1,
  1265. 'parent_id' => 0,
  1266. 'module_class' => $module_class,
  1267. 'module_langname' => $cat_name,
  1268. 'module_mode' => '',
  1269. 'module_auth' => '',
  1270. );
  1271. // Add category
  1272. $_module->update_module_data($module_data, true);
  1273. // Check for last sql error happened
  1274. if ($db->get_sql_error_triggered())
  1275. {
  1276. $error = $db->sql_error($db->get_sql_error_sql());
  1277. $this->p_master->db_error($error['message'], $db->get_sql_error_sql(), __LINE__, __FILE__);
  1278. }
  1279. $categories[$cat_name]['id'] = (int) $module_data['module_id'];
  1280. $categories[$cat_name]['parent_id'] = 0;
  1281. // Create sub-categories...
  1282. if (is_array($subs))
  1283. {
  1284. foreach ($subs as $level2_name)
  1285. {
  1286. $basename = '';
  1287. // Check if this sub-category has a basename. If it has, use it.
  1288. if (isset($this->module_categories_basenames[$level2_name]))
  1289. {
  1290. $basename = $this->module_categories_basenames[$level2_name];
  1291. }
  1292. $module_data = array(
  1293. 'module_basename' => $basename,
  1294. 'module_enabled' => 1,
  1295. 'module_display' => 1,
  1296. 'parent_id' => (int) $categories[$cat_name]['id'],
  1297. 'module_class' => $module_class,
  1298. 'module_langname' => $level2_name,
  1299. 'module_mode' => '',
  1300. 'module_auth' => '',
  1301. );
  1302. $_module->update_module_data($m

Large files files are truncated, but you can click here to view the full file