Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

install_install.php

Zuletzt modifiziert: 09.10.2024, 12:51 - Dateigröße: 73.97 KiB


0001  <?php
0002  /**
0003  *
0004  * This file is part of the phpBB Forum Software package.
0005  *
0006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
0007  * @license GNU General Public License, version 2 (GPL-2.0)
0008  *
0009  * For full copyright and license information, please see
0010  * the docs/CREDITS.txt file.
0011  *
0012  */
0013   
0014  /**
0015  */
0016  if (!defined('IN_INSTALL'))
0017  {
0018      // Someone has tried to access the file direct. This is not a good idea, so exit
0019      exit;
0020  }
0021   
0022  if (!empty($setmodules))
0023  {
0024      // If phpBB is already installed we do not include this module
0025      if (phpbb_check_installation_exists($phpbb_root_path, $phpEx) && !file_exists($phpbb_root_path . 'cache/install_lock'))
0026      {
0027          return;
0028      }
0029   
0030      $module[] = array(
0031          'module_type'        => 'install',
0032          'module_title'        => 'INSTALL',
0033          'module_filename'    => substr(basename(__FILE__), 0, -strlen($phpEx)-1),
0034          'module_order'        => 10,
0035          'module_subs'        => '',
0036          'module_stages'        => array('INTRO', 'REQUIREMENTS', 'DATABASE', 'ADMINISTRATOR', 'CONFIG_FILE', 'ADVANCED', 'CREATE_TABLE', 'FINAL'),
0037          'module_reqs'        => ''
0038      );
0039  }
0040   
0041  /**
0042  * Installation
0043  */
0044  class install_install extends module
0045  {
0046      function install_install(&$p_master)
0047      {
0048          $this->p_master = &$p_master;
0049      }
0050   
0051      function main($mode, $sub)
0052      {
0053          global $lang, $template, $language, $phpbb_root_path, $phpEx;
0054          global $phpbb_container, $cache, $phpbb_log, $request, $phpbb_config_php_file;
0055   
0056          switch ($sub)
0057          {
0058              case 'intro':
0059                  $phpbb_container->get('cache.driver')->purge();
0060   
0061                  $this->page_title = $lang['SUB_INTRO'];
0062   
0063                  $template->assign_vars(array(
0064                      'TITLE'            => $lang['INSTALL_INTRO'],
0065                      'BODY'            => $lang['INSTALL_INTRO_BODY'],
0066                      'L_SUBMIT'        => $lang['NEXT_STEP'],
0067                      'S_LANG_SELECT'    => '<select id="language" name="language">' . $this->p_master->inst_language_select($language) . '</select>',
0068                      'U_ACTION'        => $this->p_master->module_url . "?mode=$mode&amp;sub=requirements&amp;language=$language",
0069                  ));
0070   
0071              break;
0072   
0073              case 'requirements':
0074                  $this->check_server_requirements($mode, $sub);
0075   
0076              break;
0077   
0078              case 'database':
0079                  $this->obtain_database_settings($mode, $sub);
0080   
0081              break;
0082   
0083              case 'administrator':
0084                  $this->obtain_admin_settings($mode, $sub);
0085   
0086              break;
0087   
0088              case 'config_file':
0089                  $this->create_config_file($mode, $sub);
0090   
0091              break;
0092   
0093              case 'advanced':
0094                  $this->obtain_advanced_settings($mode, $sub);
0095   
0096              break;
0097   
0098              case 'create_table':
0099                  $this->load_schema($mode, $sub);
0100              break;
0101   
0102              case 'final':
0103                  // Enable super globals to prevent issues with the new \phpbb\request\request object
0104                  $request->enable_super_globals();
0105   
0106                  // Create a normal container now
0107                  $phpbb_container_builder = new \phpbb\di\container_builder($phpbb_config_php_file, $phpbb_root_path, $phpEx);
0108                  $phpbb_container = $phpbb_container_builder->get_container();
0109   
0110                  // Sets the global variables
0111                  $cache = $phpbb_container->get('cache');
0112                  $phpbb_log = $phpbb_container->get('log');
0113   
0114                  $this->build_search_index($mode, $sub);
0115                  $this->add_modules($mode, $sub);
0116                  $this->add_language($mode, $sub);
0117                  $this->add_bots($mode, $sub);
0118                  $this->email_admin($mode, $sub);
0119                  $this->disable_avatars_if_unwritable();
0120                  $this->populate_migrations($phpbb_container->get('ext.manager'), $phpbb_container->get('migrator'));
0121   
0122                  // Remove the lock file
0123                  @unlink($phpbb_root_path . 'cache/install_lock');
0124   
0125              break;
0126          }
0127   
0128          $this->tpl_name = 'install_install';
0129      }
0130   
0131      /**
0132      * Checks that the server we are installing on meets the requirements for running phpBB
0133      */
0134      function check_server_requirements($mode, $sub)
0135      {
0136          global $lang, $template, $phpbb_root_path, $phpEx, $language;
0137   
0138          $this->page_title = $lang['STAGE_REQUIREMENTS'];
0139   
0140          $template->assign_vars(array(
0141              'TITLE'        => $lang['REQUIREMENTS_TITLE'],
0142              'BODY'        => $lang['REQUIREMENTS_EXPLAIN'],
0143          ));
0144   
0145          $passed = array('php' => false, 'db' => false, 'files' => false, 'pcre' => false, 'imagesize' => false, 'json' => false,);
0146   
0147          // Test for basic PHP settings
0148          $template->assign_block_vars('checks', array(
0149              'S_LEGEND'            => true,
0150              'LEGEND'            => $lang['PHP_SETTINGS'],
0151              'LEGEND_EXPLAIN'    => $lang['PHP_SETTINGS_EXPLAIN'],
0152          ));
0153   
0154          // Test the minimum PHP version
0155          $php_version = PHP_VERSION;
0156   
0157          if (version_compare($php_version, '5.3.3') < 0)
0158          {
0159              $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
0160          }
0161          else
0162          {
0163              $passed['php'] = true;
0164   
0165              // We also give feedback on whether we're running in safe mode
0166              $result = '<strong style="color:green">' . $lang['YES'];
0167              if (@ini_get('safe_mode') == '1' || strtolower(@ini_get('safe_mode')) == 'on')
0168              {
0169                  $result .= ', ' . $lang['PHP_SAFE_MODE'];
0170              }
0171              $result .= '</strong>';
0172          }
0173   
0174          $template->assign_block_vars('checks', array(
0175              'TITLE'            => $lang['PHP_VERSION_REQD'],
0176              'RESULT'        => $result,
0177   
0178              'S_EXPLAIN'        => false,
0179              'S_LEGEND'        => false,
0180          ));
0181   
0182          // Don't check for register_globals on 5.4+
0183          if (version_compare($php_version, '5.4.0-dev') < 0)
0184          {
0185              // Check for register_globals being enabled
0186              if (@ini_get('register_globals') == '1' || strtolower(@ini_get('register_globals')) == 'on')
0187              {
0188                  $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
0189              }
0190              else
0191              {
0192                  $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
0193              }
0194   
0195              $template->assign_block_vars('checks', array(
0196                  'TITLE'            => $lang['PHP_REGISTER_GLOBALS'],
0197                  'TITLE_EXPLAIN'    => $lang['PHP_REGISTER_GLOBALS_EXPLAIN'],
0198                  'RESULT'        => $result,
0199   
0200                  'S_EXPLAIN'        => true,
0201                  'S_LEGEND'        => false,
0202              ));
0203          }
0204   
0205          // Check for url_fopen
0206          if (@ini_get('allow_url_fopen') == '1' || strtolower(@ini_get('allow_url_fopen')) == 'on')
0207          {
0208              $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
0209          }
0210          else
0211          {
0212              $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
0213          }
0214   
0215          $template->assign_block_vars('checks', array(
0216              'TITLE'            => $lang['PHP_URL_FOPEN_SUPPORT'],
0217              'TITLE_EXPLAIN'    => $lang['PHP_URL_FOPEN_SUPPORT_EXPLAIN'],
0218              'RESULT'        => $result,
0219   
0220              'S_EXPLAIN'        => true,
0221              'S_LEGEND'        => false,
0222          ));
0223   
0224          // Check for getimagesize
0225          if (@function_exists('getimagesize'))
0226          {
0227              $passed['imagesize'] = true;
0228              $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
0229          }
0230          else
0231          {
0232              $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
0233          }
0234   
0235          $template->assign_block_vars('checks', array(
0236              'TITLE'            => $lang['PHP_GETIMAGESIZE_SUPPORT'],
0237              'TITLE_EXPLAIN'    => $lang['PHP_GETIMAGESIZE_SUPPORT_EXPLAIN'],
0238              'RESULT'        => $result,
0239   
0240              'S_EXPLAIN'        => true,
0241              'S_LEGEND'        => false,
0242          ));
0243   
0244          // Check for PCRE UTF-8 support
0245          if (@preg_match('//u', ''))
0246          {
0247              $passed['pcre'] = true;
0248              $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
0249          }
0250          else
0251          {
0252              $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
0253          }
0254   
0255          $template->assign_block_vars('checks', array(
0256              'TITLE'            => $lang['PCRE_UTF_SUPPORT'],
0257              'TITLE_EXPLAIN'    => $lang['PCRE_UTF_SUPPORT_EXPLAIN'],
0258              'RESULT'        => $result,
0259   
0260              'S_EXPLAIN'        => true,
0261              'S_LEGEND'        => false,
0262          ));
0263   
0264          // Check for php json support
0265          if (@extension_loaded('json'))
0266          {
0267              $passed['json'] = true;
0268              $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
0269          }
0270          else
0271          {
0272              $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
0273          }
0274   
0275          $template->assign_block_vars('checks', array(
0276              'TITLE'            => $lang['PHP_JSON_SUPPORT'],
0277              'TITLE_EXPLAIN'    => $lang['PHP_JSON_SUPPORT_EXPLAIN'],
0278              'RESULT'        => $result,
0279   
0280              'S_EXPLAIN'        => true,
0281              'S_LEGEND'        => false,
0282          ));
0283   
0284          $passed['mbstring'] = true;
0285          if (@extension_loaded('mbstring'))
0286          {
0287              // Test for available database modules
0288              $template->assign_block_vars('checks', array(
0289                  'S_LEGEND'            => true,
0290                  'LEGEND'            => $lang['MBSTRING_CHECK'],
0291                  'LEGEND_EXPLAIN'    => $lang['MBSTRING_CHECK_EXPLAIN'],
0292              ));
0293   
0294              $checks = array(
0295                  array('func_overload', '&', MB_OVERLOAD_MAIL|MB_OVERLOAD_STRING),
0296                  array('encoding_translation', '!=', 0),
0297                  array('http_input', '!=', array('pass', '')),
0298                  array('http_output', '!=', array('pass', ''))
0299              );
0300   
0301              foreach ($checks as $mb_checks)
0302              {
0303                  $ini_val = @ini_get('mbstring.' . $mb_checks[0]);
0304                  switch ($mb_checks[1])
0305                  {
0306                      case '&':
0307                          if (intval($ini_val) & $mb_checks[2])
0308                          {
0309                              $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
0310                              $passed['mbstring'] = false;
0311                          }
0312                          else
0313                          {
0314                              $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
0315                          }
0316                      break;
0317   
0318                      case '!=':
0319                          if (!is_array($mb_checks[2]) && $ini_val != $mb_checks[2] ||
0320                              is_array($mb_checks[2]) && !in_array($ini_val, $mb_checks[2]))
0321                          {
0322                              $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
0323                              $passed['mbstring'] = false;
0324                          }
0325                          else
0326                          {
0327                              $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
0328                          }
0329                      break;
0330                  }
0331                  $template->assign_block_vars('checks', array(
0332                      'TITLE'            => $lang['MBSTRING_' . strtoupper($mb_checks[0])],
0333                      'TITLE_EXPLAIN'    => $lang['MBSTRING_' . strtoupper($mb_checks[0]) . '_EXPLAIN'],
0334                      'RESULT'        => $result,
0335   
0336                      'S_EXPLAIN'        => true,
0337                      'S_LEGEND'        => false,
0338                  ));
0339              }
0340          }
0341   
0342          // Test for available database modules
0343          $template->assign_block_vars('checks', array(
0344              'S_LEGEND'            => true,
0345              'LEGEND'            => $lang['PHP_SUPPORTED_DB'],
0346              'LEGEND_EXPLAIN'    => $lang['PHP_SUPPORTED_DB_EXPLAIN'],
0347          ));
0348   
0349          $available_dbms = get_available_dbms(false, true);
0350          $passed['db'] = $available_dbms['ANY_DB_SUPPORT'];
0351          unset($available_dbms['ANY_DB_SUPPORT']);
0352   
0353          foreach ($available_dbms as $db_name => $db_ary)
0354          {
0355              if (!$db_ary['AVAILABLE'])
0356              {
0357                  $template->assign_block_vars('checks', array(
0358                      'TITLE'        => $lang['DLL_' . strtoupper($db_name)],
0359                      'RESULT'    => '<span style="color:red">' . $lang['UNAVAILABLE'] . '</span>',
0360   
0361                      'S_EXPLAIN'    => false,
0362                      'S_LEGEND'    => false,
0363                  ));
0364              }
0365              else
0366              {
0367                  $template->assign_block_vars('checks', array(
0368                      'TITLE'        => $lang['DLL_' . strtoupper($db_name)],
0369                      'RESULT'    => '<strong style="color:green">' . $lang['AVAILABLE'] . '</strong>',
0370   
0371                      'S_EXPLAIN'    => false,
0372                      'S_LEGEND'    => false,
0373                  ));
0374              }
0375          }
0376   
0377          // Test for other modules
0378          $template->assign_block_vars('checks', array(
0379              'S_LEGEND'            => true,
0380              'LEGEND'            => $lang['PHP_OPTIONAL_MODULE'],
0381              'LEGEND_EXPLAIN'    => $lang['PHP_OPTIONAL_MODULE_EXPLAIN'],
0382          ));
0383   
0384          foreach ($this->php_dlls_other as $dll)
0385          {
0386              if (!@extension_loaded($dll))
0387              {
0388                  $template->assign_block_vars('checks', array(
0389                      'TITLE'        => $lang['DLL_' . strtoupper($dll)],
0390                      'RESULT'    => '<strong style="color:red">' . $lang['UNAVAILABLE'] . '</strong>',
0391   
0392                      'S_EXPLAIN'    => false,
0393                      'S_LEGEND'    => false,
0394                  ));
0395                  continue;
0396              }
0397   
0398              $template->assign_block_vars('checks', array(
0399                  'TITLE'        => $lang['DLL_' . strtoupper($dll)],
0400                  'RESULT'    => '<strong style="color:green">' . $lang['AVAILABLE'] . '</strong>',
0401   
0402                  'S_EXPLAIN'    => false,
0403                  'S_LEGEND'    => false,
0404              ));
0405          }
0406   
0407          // Can we find Imagemagick anywhere on the system?
0408          $exe = (DIRECTORY_SEPARATOR == '\\') ? '.exe' : '';
0409   
0410          $magic_home = getenv('MAGICK_HOME');
0411          $img_imagick = '';
0412          if (empty($magic_home))
0413          {
0414              $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/');
0415              $path_locations = str_replace('\\', '/', (explode(($exe) ? ';' : ':', getenv('PATH'))));
0416   
0417              $locations = array_merge($path_locations, $locations);
0418              foreach ($locations as $location)
0419              {
0420                  // The path might not end properly, fudge it
0421                  if (substr($location, -1, 1) !== '/')
0422                  {
0423                      $location .= '/';
0424                  }
0425   
0426                  if (@file_exists($location) && @is_readable($location . 'mogrify' . $exe) && @filesize($location . 'mogrify' . $exe) > 3000)
0427                  {
0428                      $img_imagick = str_replace('\\', '/', $location);
0429                      continue;
0430                  }
0431              }
0432          }
0433          else
0434          {
0435              $img_imagick = str_replace('\\', '/', $magic_home);
0436          }
0437   
0438          $template->assign_block_vars('checks', array(
0439              'TITLE'        => $lang['APP_MAGICK'],
0440              'RESULT'    => ($img_imagick) ? '<strong style="color:green">' . $lang['AVAILABLE'] . ', ' . $img_imagick . '</strong>' : '<strong style="color:blue">' . $lang['NO_LOCATION'] . '</strong>',
0441   
0442              'S_EXPLAIN'    => false,
0443              'S_LEGEND'    => false,
0444          ));
0445   
0446          // Check permissions on files/directories we need access to
0447          $template->assign_block_vars('checks', array(
0448              'S_LEGEND'            => true,
0449              'LEGEND'            => $lang['FILES_REQUIRED'],
0450              'LEGEND_EXPLAIN'    => $lang['FILES_REQUIRED_EXPLAIN'],
0451          ));
0452   
0453          $directories = array('cache/', 'files/', 'store/');
0454   
0455          umask(0);
0456   
0457          $passed['files'] = true;
0458          foreach ($directories as $dir)
0459          {
0460              $exists = $write = false;
0461   
0462              // Try to create the directory if it does not exist
0463              if (!file_exists($phpbb_root_path . $dir))
0464              {
0465                  @mkdir($phpbb_root_path . $dir, 0777);
0466                  phpbb_chmod($phpbb_root_path . $dir, CHMOD_READ | CHMOD_WRITE);
0467              }
0468   
0469              // Now really check
0470              if (file_exists($phpbb_root_path . $dir) && is_dir($phpbb_root_path . $dir))
0471              {
0472                  phpbb_chmod($phpbb_root_path . $dir, CHMOD_READ | CHMOD_WRITE);
0473                  $exists = true;
0474              }
0475   
0476              // Now check if it is writable by storing a simple file
0477              $fp = @fopen($phpbb_root_path . $dir . 'test_lock', 'wb');
0478              if ($fp !== false)
0479              {
0480                  $write = true;
0481              }
0482              @fclose($fp);
0483   
0484              @unlink($phpbb_root_path . $dir . 'test_lock');
0485   
0486              $passed['files'] = ($exists && $write && $passed['files']) ? true : false;
0487   
0488              $exists = ($exists) ? '<strong style="color:green">' . $lang['FOUND'] . '</strong>' : '<strong style="color:red">' . $lang['NOT_FOUND'] . '</strong>';
0489              $write = ($write) ? ', <strong style="color:green">' . $lang['WRITABLE'] . '</strong>' : (($exists) ? ', <strong style="color:red">' . $lang['UNWRITABLE'] . '</strong>' : '');
0490   
0491              $template->assign_block_vars('checks', array(
0492                  'TITLE'        => $dir,
0493                  'RESULT'    => $exists . $write,
0494   
0495                  'S_EXPLAIN'    => false,
0496                  'S_LEGEND'    => false,
0497              ));
0498          }
0499   
0500          // Check permissions on files/directories it would be useful access to
0501          $template->assign_block_vars('checks', array(
0502              'S_LEGEND'            => true,
0503              'LEGEND'            => $lang['FILES_OPTIONAL'],
0504              'LEGEND_EXPLAIN'    => $lang['FILES_OPTIONAL_EXPLAIN'],
0505          ));
0506   
0507          $directories = array('config.' . $phpEx, 'images/avatars/upload/');
0508   
0509          foreach ($directories as $dir)
0510          {
0511              $write = $exists = true;
0512              if (file_exists($phpbb_root_path . $dir))
0513              {
0514                  if (!phpbb_is_writable($phpbb_root_path . $dir))
0515                  {
0516                      $write = false;
0517                  }
0518              }
0519              else
0520              {
0521                  $write = $exists = false;
0522              }
0523   
0524              $exists_str = ($exists) ? '<strong style="color:green">' . $lang['FOUND'] . '</strong>' : '<strong style="color:red">' . $lang['NOT_FOUND'] . '</strong>';
0525              $write_str = ($write) ? ', <strong style="color:green">' . $lang['WRITABLE'] . '</strong>' : (($exists) ? ', <strong style="color:red">' . $lang['UNWRITABLE'] . '</strong>' : '');
0526   
0527              $template->assign_block_vars('checks', array(
0528                  'TITLE'        => $dir,
0529                  'RESULT'    => $exists_str . $write_str,
0530   
0531                  'S_EXPLAIN'    => false,
0532                  'S_LEGEND'    => false,
0533              ));
0534          }
0535   
0536          // And finally where do we want to go next (well today is taken isn't it :P)
0537          $s_hidden_fields = ($img_imagick) ? '<input type="hidden" name="img_imagick" value="' . addslashes($img_imagick) . '" />' : '';
0538   
0539          $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    ";
0540          $submit = (!in_array(false, $passed)) ? $lang['INSTALL_START'] : $lang['INSTALL_TEST'];
0541   
0542          $template->assign_vars(array(
0543              'L_SUBMIT'    => $submit,
0544              'S_HIDDEN'    => $s_hidden_fields,
0545              'U_ACTION'    => $url,
0546          ));
0547      }
0548   
0549      /**
0550      * Obtain the information required to connect to the database
0551      */
0552      function obtain_database_settings($mode, $sub)
0553      {
0554          global $lang, $template, $phpEx;
0555   
0556          $this->page_title = $lang['STAGE_DATABASE'];
0557   
0558          // Obtain any submitted data
0559          $data = $this->get_submitted_data();
0560   
0561          $connect_test = false;
0562          $error = array();
0563          $available_dbms = get_available_dbms(false, true);
0564   
0565          // Has the user opted to test the connection?
0566          if (isset($_POST['testdb']))
0567          {
0568              if (!isset($available_dbms[$data['dbms']]) || !$available_dbms[$data['dbms']]['AVAILABLE'])
0569              {
0570                  $error[] = $lang['INST_ERR_NO_DB'];
0571                  $connect_test = false;
0572              }
0573              else if (!preg_match(get_preg_expression('table_prefix'), $data['table_prefix']))
0574              {
0575                  $error[] = $lang['INST_ERR_DB_INVALID_PREFIX'];
0576                  $connect_test = false;
0577              }
0578              else
0579              {
0580                  $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']);
0581              }
0582   
0583              $template->assign_block_vars('checks', array(
0584                  'S_LEGEND'            => true,
0585                  'LEGEND'            => $lang['DB_CONNECTION'],
0586                  'LEGEND_EXPLAIN'    => false,
0587              ));
0588   
0589              if ($connect_test)
0590              {
0591                  $template->assign_block_vars('checks', array(
0592                      'TITLE'        => $lang['DB_TEST'],
0593                      'RESULT'    => '<strong style="color:green">' . $lang['SUCCESSFUL_CONNECT'] . '</strong>',
0594   
0595                      'S_EXPLAIN'    => false,
0596                      'S_LEGEND'    => false,
0597                  ));
0598              }
0599              else
0600              {
0601                  $template->assign_block_vars('checks', array(
0602                      'TITLE'        => $lang['DB_TEST'],
0603                      'RESULT'    => '<strong style="color:red">' . implode('<br />', $error) . '</strong>',
0604   
0605                      'S_EXPLAIN'    => false,
0606                      'S_LEGEND'    => false,
0607                  ));
0608              }
0609          }
0610   
0611          if (!$connect_test)
0612          {
0613              // Update the list of available DBMS modules to only contain those which can be used
0614              $available_dbms_temp = array();
0615              foreach ($available_dbms as $type => $dbms_ary)
0616              {
0617                  if (!$dbms_ary['AVAILABLE'])
0618                  {
0619                      continue;
0620                  }
0621   
0622                  $available_dbms_temp[$type] = $dbms_ary;
0623              }
0624   
0625              $available_dbms = &$available_dbms_temp;
0626   
0627              // And now for the main part of this page
0628              $data['table_prefix'] = (!empty($data['table_prefix']) ? $data['table_prefix'] : 'phpbb_');
0629   
0630              foreach ($this->db_config_options as $config_key => $vars)
0631              {
0632                  if (!is_array($vars) && strpos($config_key, 'legend') === false)
0633                  {
0634                      continue;
0635                  }
0636   
0637                  if (strpos($config_key, 'legend') !== false)
0638                  {
0639                      $template->assign_block_vars('options', array(
0640                          'S_LEGEND'        => true,
0641                          'LEGEND'        => $lang[$vars])
0642                      );
0643   
0644                      continue;
0645                  }
0646   
0647                  $options = isset($vars['options']) ? $vars['options'] : '';
0648   
0649                  $template->assign_block_vars('options', array(
0650                      'KEY'            => $config_key,
0651                      'TITLE'            => $lang[$vars['lang']],
0652                      'S_EXPLAIN'        => $vars['explain'],
0653                      'S_LEGEND'        => false,
0654                      'TITLE_EXPLAIN'    => ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '',
0655                      'CONTENT'        => $this->p_master->input_field($config_key, $vars['type'], $data[$config_key], $options),
0656                      )
0657                  );
0658              }
0659          }
0660   
0661          // And finally where do we want to go next (well today is taken isn't it :P)
0662          $s_hidden_fields = ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
0663          $s_hidden_fields .= '<input type="hidden" name="language" value="' . $data['language'] . '" />';
0664          if ($connect_test)
0665          {
0666              foreach ($this->db_config_options as $config_key => $vars)
0667              {
0668                  if (!is_array($vars))
0669                  {
0670                      continue;
0671                  }
0672                  $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
0673              }
0674          }
0675   
0676          $url = ($connect_test) ? $this->p_master->module_url . "?mode=$mode&amp;sub=administrator" : $this->p_master->module_url . "?mode=$mode&amp;sub=database";
0677          $s_hidden_fields .= ($connect_test) ? '' : '<input type="hidden" name="testdb" value="true" />';
0678   
0679          $submit = $lang['NEXT_STEP'];
0680   
0681          $template->assign_vars(array(
0682              'L_SUBMIT'    => $submit,
0683              'S_HIDDEN'    => $s_hidden_fields,
0684              'U_ACTION'    => $url,
0685          ));
0686      }
0687   
0688      /**
0689      * Obtain the administrator's name, password and email address
0690      */
0691      function obtain_admin_settings($mode, $sub)
0692      {
0693          global $lang, $template, $phpEx;
0694   
0695          $this->page_title = $lang['STAGE_ADMINISTRATOR'];
0696   
0697          // Obtain any submitted data
0698          $data = $this->get_submitted_data();
0699   
0700          if ($data['dbms'] == '')
0701          {
0702              // Someone's been silly and tried calling this page direct
0703              // So we send them back to the start to do it again properly
0704              $this->p_master->redirect("index.$phpEx?mode=install");
0705          }
0706   
0707          $s_hidden_fields = ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
0708          $passed = false;
0709   
0710          $data['default_lang'] = ($data['default_lang'] !== '') ? $data['default_lang'] : $data['language'];
0711   
0712          if (isset($_POST['check']))
0713          {
0714              $error = array();
0715   
0716              // Check the entered email address and password
0717              if ($data['admin_name'] == '' || $data['admin_pass1'] == '' || $data['admin_pass2'] == '' || $data['board_email'] == '')
0718              {
0719                  $error[] = $lang['INST_ERR_MISSING_DATA'];
0720              }
0721   
0722              if ($data['admin_pass1'] != $data['admin_pass2'] && $data['admin_pass1'] != '')
0723              {
0724                  $error[] = $lang['INST_ERR_PASSWORD_MISMATCH'];
0725              }
0726   
0727              // Test against the default username rules
0728              if ($data['admin_name'] != '' && utf8_strlen($data['admin_name']) < 3)
0729              {
0730                  $error[] = $lang['INST_ERR_USER_TOO_SHORT'];
0731              }
0732   
0733              if ($data['admin_name'] != '' && utf8_strlen($data['admin_name']) > 20)
0734              {
0735                  $error[] = $lang['INST_ERR_USER_TOO_LONG'];
0736              }
0737   
0738              // Test against the default password rules
0739              if ($data['admin_pass1'] != '' && utf8_strlen($data['admin_pass1']) < 6)
0740              {
0741                  $error[] = $lang['INST_ERR_PASSWORD_TOO_SHORT'];
0742              }
0743   
0744              if ($data['admin_pass1'] != '' && utf8_strlen($data['admin_pass1']) > 30)
0745              {
0746                  $error[] = $lang['INST_ERR_PASSWORD_TOO_LONG'];
0747              }
0748   
0749              if ($data['board_email'] != '' && !preg_match('/^' . get_preg_expression('email') . '$/i', $data['board_email']))
0750              {
0751                  $error[] = $lang['INST_ERR_EMAIL_INVALID'];
0752              }
0753   
0754              $template->assign_block_vars('checks', array(
0755                  'S_LEGEND'            => true,
0756                  'LEGEND'            => $lang['STAGE_ADMINISTRATOR'],
0757                  'LEGEND_EXPLAIN'    => false,
0758              ));
0759   
0760              if (!sizeof($error))
0761              {
0762                  $passed = true;
0763                  $template->assign_block_vars('checks', array(
0764                      'TITLE'        => $lang['ADMIN_TEST'],
0765                      'RESULT'    => '<strong style="color:green">' . $lang['TESTS_PASSED'] . '</strong>',
0766   
0767                      'S_EXPLAIN'    => false,
0768                      'S_LEGEND'    => false,
0769                  ));
0770              }
0771              else
0772              {
0773                  $template->assign_block_vars('checks', array(
0774                      'TITLE'        => $lang['ADMIN_TEST'],
0775                      'RESULT'    => '<strong style="color:red">' . implode('<br />', $error) . '</strong>',
0776   
0777                      'S_EXPLAIN'    => false,
0778                      'S_LEGEND'    => false,
0779                  ));
0780              }
0781          }
0782   
0783          if (!$passed)
0784          {
0785              foreach ($this->admin_config_options as $config_key => $vars)
0786              {
0787                  if (!is_array($vars) && strpos($config_key, 'legend') === false)
0788                  {
0789                      continue;
0790                  }
0791   
0792                  if (strpos($config_key, 'legend') !== false)
0793                  {
0794                      $template->assign_block_vars('options', array(
0795                          'S_LEGEND'        => true,
0796                          'LEGEND'        => $lang[$vars])
0797                      );
0798   
0799                      continue;
0800                  }
0801   
0802                  $options = isset($vars['options']) ? $vars['options'] : '';
0803   
0804                  $template->assign_block_vars('options', array(
0805                      'KEY'            => $config_key,
0806                      'TITLE'            => $lang[$vars['lang']],
0807                      'S_EXPLAIN'        => $vars['explain'],
0808                      'S_LEGEND'        => false,
0809                      'TITLE_EXPLAIN'    => ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '',
0810                      'CONTENT'        => $this->p_master->input_field($config_key, $vars['type'], $data[$config_key], $options),
0811                      )
0812                  );
0813              }
0814          }
0815          else
0816          {
0817              foreach ($this->admin_config_options as $config_key => $vars)
0818              {
0819                  if (!is_array($vars))
0820                  {
0821                      continue;
0822                  }
0823                  $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
0824              }
0825          }
0826   
0827          $s_hidden_fields .= ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
0828          $s_hidden_fields .= '<input type="hidden" name="language" value="' . $data['language'] . '" />';
0829   
0830          foreach ($this->db_config_options as $config_key => $vars)
0831          {
0832              if (!is_array($vars))
0833              {
0834                  continue;
0835              }
0836              $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
0837          }
0838   
0839          $submit = $lang['NEXT_STEP'];
0840   
0841          $url = ($passed) ? $this->p_master->module_url . "?mode=$mode&amp;sub=config_file" : $this->p_master->module_url . "?mode=$mode&amp;sub=administrator";
0842          $s_hidden_fields .= ($passed) ? '' : '<input type="hidden" name="check" value="true" />';
0843   
0844          $template->assign_vars(array(
0845              'L_SUBMIT'    => $submit,
0846              'S_HIDDEN'    => $s_hidden_fields,
0847              'U_ACTION'    => $url,
0848          ));
0849      }
0850   
0851      /**
0852      * Writes the config file to disk, or if unable to do so offers alternative methods
0853      */
0854      function create_config_file($mode, $sub)
0855      {
0856          global $lang, $template, $phpbb_root_path, $phpEx;
0857   
0858          $this->page_title = $lang['STAGE_CONFIG_FILE'];
0859   
0860          // Obtain any submitted data
0861          $data = $this->get_submitted_data();
0862   
0863          if ($data['dbms'] == '')
0864          {
0865              // Someone's been silly and tried calling this page direct
0866              // So we send them back to the start to do it again properly
0867              $this->p_master->redirect("index.$phpEx?mode=install");
0868          }
0869   
0870          $s_hidden_fields = ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
0871          $s_hidden_fields .= '<input type="hidden" name="language" value="' . $data['language'] . '" />';
0872          $written = false;
0873   
0874          // Create a list of any PHP modules we wish to have loaded
0875          $available_dbms = get_available_dbms($data['dbms']);
0876   
0877          // Create a lock file to indicate that there is an install in progress
0878          $fp = @fopen($phpbb_root_path . 'cache/install_lock', 'wb');
0879          if ($fp === false)
0880          {
0881              // We were unable to create the lock file - abort
0882              $this->p_master->error($lang['UNABLE_WRITE_LOCK'], __LINE__, __FILE__);
0883          }
0884          @fclose($fp);
0885   
0886          @chmod($phpbb_root_path . 'cache/install_lock', 0777);
0887   
0888          // Time to convert the data provided into a config file
0889          $config_data = phpbb_create_config_file_data($data, $available_dbms[$data['dbms']]['DRIVER']);
0890   
0891          // Attempt to write out the config file directly. If it works, this is the easiest way to do it ...
0892          if ((file_exists($phpbb_root_path . 'config.' . $phpEx) && phpbb_is_writable($phpbb_root_path . 'config.' . $phpEx)) || phpbb_is_writable($phpbb_root_path))
0893          {
0894              // Assume it will work ... if nothing goes wrong below
0895              $written = true;
0896   
0897              if (!($fp = @fopen($phpbb_root_path . 'config.' . $phpEx, 'w')))
0898              {
0899                  // Something went wrong ... so let's try another method
0900                  $written = false;
0901              }
0902   
0903              if (!(@fwrite($fp, $config_data)))
0904              {
0905                  // Something went wrong ... so let's try another method
0906                  $written = false;
0907              }
0908   
0909              @fclose($fp);
0910   
0911              if ($written)
0912              {
0913                  // We may revert back to chmod() if we see problems with users not able to change their config.php file directly
0914                  phpbb_chmod($phpbb_root_path . 'config.' . $phpEx, CHMOD_READ);
0915              }
0916          }
0917   
0918          if (isset($_POST['dldone']))
0919          {
0920              // Do a basic check to make sure that the file has been uploaded
0921              // Note that all we check is that the file has _something_ in it
0922              // We don't compare the contents exactly - if they can't upload
0923              // a single file correctly, it's likely they will have other problems....
0924              if (filesize($phpbb_root_path . 'config.' . $phpEx) > 10)
0925              {
0926                  $written = true;
0927              }
0928          }
0929   
0930          $config_options = array_merge($this->db_config_options, $this->admin_config_options);
0931   
0932          foreach ($config_options as $config_key => $vars)
0933          {
0934              if (!is_array($vars))
0935              {
0936                  continue;
0937              }
0938              $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
0939          }
0940   
0941          if (!$written)
0942          {
0943              // OK, so it didn't work let's try the alternatives
0944   
0945              if (isset($_POST['dlconfig']))
0946              {
0947                  // They want a copy of the file to download, so send the relevant headers and dump out the data
0948                  header("Content-Type: text/x-delimtext; name=\"config.$phpEx\"");
0949                  header("Content-disposition: attachment; filename=config.$phpEx");
0950                  echo $config_data;
0951                  exit;
0952              }
0953   
0954              // The option to download the config file is always available, so output it here
0955              $template->assign_vars(array(
0956                  'BODY'                    => $lang['CONFIG_FILE_UNABLE_WRITE'],
0957                  'L_DL_CONFIG'            => $lang['DL_CONFIG'],
0958                  'L_DL_CONFIG_EXPLAIN'    => $lang['DL_CONFIG_EXPLAIN'],
0959                  'L_DL_DONE'                => $lang['DONE'],
0960                  'L_DL_DOWNLOAD'            => $lang['DL_DOWNLOAD'],
0961                  'S_HIDDEN'                => $s_hidden_fields,
0962                  'S_SHOW_DOWNLOAD'        => true,
0963                  'U_ACTION'                => $this->p_master->module_url . "?mode=$mode&amp;sub=config_file",
0964              ));
0965              return;
0966          }
0967          else
0968          {
0969              $template->assign_vars(array(
0970                  'BODY'        => $lang['CONFIG_FILE_WRITTEN'],
0971                  'L_SUBMIT'    => $lang['NEXT_STEP'],
0972                  'S_HIDDEN'    => $s_hidden_fields,
0973                  'U_ACTION'    => $this->p_master->module_url . "?mode=$mode&amp;sub=advanced",
0974              ));
0975              return;
0976          }
0977      }
0978   
0979      /**
0980      * Provide an opportunity to customise some advanced settings during the install
0981      * in case it is necessary for them to be set to access later
0982      */
0983      function obtain_advanced_settings($mode, $sub)
0984      {
0985          global $lang, $template, $phpEx, $request;
0986   
0987          $this->page_title = $lang['STAGE_ADVANCED'];
0988   
0989          // Obtain any submitted data
0990          $data = $this->get_submitted_data();
0991   
0992          if ($data['dbms'] == '')
0993          {
0994              // Someone's been silly and tried calling this page direct
0995              // So we send them back to the start to do it again properly
0996              $this->p_master->redirect("index.$phpEx?mode=install");
0997          }
0998   
0999          $s_hidden_fields = ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
1000          $s_hidden_fields .= '<input type="hidden" name="language" value="' . $data['language'] . '" />';
1001   
1002          // HTTP_HOST is having the correct browser url in most cases...
1003          $server_name = strtolower(htmlspecialchars_decode($request->header('Host', $request->server('SERVER_NAME'))));
1004   
1005          // HTTP HOST can carry a port number...
1006          if (strpos($server_name, ':') !== false)
1007          {
1008              $server_name = substr($server_name, 0, strpos($server_name, ':'));
1009          }
1010   
1011          $data['email_enable'] = ($data['email_enable'] !== '') ? $data['email_enable'] : true;
1012          $data['server_name'] = ($data['server_name'] !== '') ? $data['server_name'] : $server_name;
1013          $data['server_port'] = ($data['server_port'] !== '') ? $data['server_port'] : $request->server('SERVER_PORT', 0);
1014          $data['server_protocol'] = ($data['server_protocol'] !== '') ? $data['server_protocol'] : ($request->is_secure() ? 'https://' : 'http://');
1015          $data['cookie_secure'] = ($data['cookie_secure'] !== '') ? $data['cookie_secure'] : $request->is_secure();
1016   
1017          if ($data['script_path'] === '')
1018          {
1019              $name = htmlspecialchars_decode($request->server('PHP_SELF'));
1020              if (!$name)
1021              {
1022                  $name = htmlspecialchars_decode($request->server('REQUEST_URI'));
1023              }
1024   
1025              // Replace backslashes and doubled slashes (could happen on some proxy setups)
1026              $name = str_replace(array('\\', '//'), '/', $name);
1027              $data['script_path'] = trim(dirname(dirname($name)));
1028          }
1029   
1030          foreach ($this->advanced_config_options as $config_key => $vars)
1031          {
1032              if (!is_array($vars) && strpos($config_key, 'legend') === false)
1033              {
1034                  continue;
1035              }
1036   
1037              if (strpos($config_key, 'legend') !== false)
1038              {
1039                  $template->assign_block_vars('options', array(
1040                      'S_LEGEND'        => true,
1041                      'LEGEND'        => $lang[$vars])
1042                  );
1043   
1044                  continue;
1045              }
1046   
1047              $options = isset($vars['options']) ? $vars['options'] : '';
1048   
1049              $template->assign_block_vars('options', array(
1050                  'KEY'            => $config_key,
1051                  'TITLE'            => $lang[$vars['lang']],
1052                  'S_EXPLAIN'        => $vars['explain'],
1053                  'S_LEGEND'        => false,
1054                  'TITLE_EXPLAIN'    => ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '',
1055                  'CONTENT'        => $this->p_master->input_field($config_key, $vars['type'], $data[$config_key], $options),
1056                  )
1057              );
1058          }
1059   
1060          $config_options = array_merge($this->db_config_options, $this->admin_config_options);
1061          foreach ($config_options as $config_key => $vars)
1062          {
1063              if (!is_array($vars))
1064              {
1065                  continue;
1066              }
1067              $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
1068          }
1069   
1070          $submit = $lang['NEXT_STEP'];
1071   
1072          $url = $this->p_master->module_url . "?mode=$mode&amp;sub=create_table";
1073   
1074          $template->assign_vars(array(
1075              'BODY'        => $lang['STAGE_ADVANCED_EXPLAIN'],
1076              'L_SUBMIT'    => $submit,
1077              'S_HIDDEN'    => $s_hidden_fields,
1078              'U_ACTION'    => $url,
1079          ));
1080      }
1081   
1082      /**
1083      * Load the contents of the schema into the database and then alter it based on what has been input during the installation
1084      */
1085      function load_schema($mode, $sub)
1086      {
1087          global $db, $lang, $template, $phpbb_root_path, $phpEx, $request;
1088   
1089          $this->page_title = $lang['STAGE_CREATE_TABLE'];
1090          $s_hidden_fields = '';
1091   
1092          // Obtain any submitted data
1093          $data = $this->get_submitted_data();
1094   
1095          if ($data['dbms'] == '')
1096          {
1097              // Someone's been silly and tried calling this page direct
1098              // So we send them back to the start to do it again properly
1099              $this->p_master->redirect("index.$phpEx?mode=install");
1100          }
1101   
1102          // HTTP_HOST is having the correct browser url in most cases...
1103          $server_name = strtolower(htmlspecialchars_decode($request->header('Host', $request->server('SERVER_NAME'))));
1104          $referer = strtolower($request->header('Referer'));
1105   
1106          // HTTP HOST can carry a port number...
1107          if (strpos($server_name, ':') !== false)
1108          {
1109              $server_name = substr($server_name, 0, strpos($server_name, ':'));
1110          }
1111   
1112          $cookie_domain = ($data['server_name'] != '') ? $data['server_name'] : $server_name;
1113   
1114          // Try to come up with the best solution for cookie domain...
1115          if (strpos($cookie_domain, 'www.') === 0)
1116          {
1117              $cookie_domain = str_replace('www.', '.', $cookie_domain);
1118          }
1119   
1120          // If we get here and the extension isn't loaded it should be safe to just go ahead and load it
1121          $available_dbms = get_available_dbms($data['dbms']);
1122   
1123          if (!isset($available_dbms[$data['dbms']]))
1124          {
1125              // Someone's been silly and tried providing a non-existant dbms
1126              $this->p_master->redirect("index.$phpEx?mode=install");
1127          }
1128   
1129          $dbms = $available_dbms[$data['dbms']]['DRIVER'];
1130   
1131          // Instantiate the database
1132          $db = new $dbms();
1133          $db->sql_connect($data['dbhost'], $data['dbuser'], htmlspecialchars_decode($data['dbpasswd']), $data['dbname'], $data['dbport'], false, false);
1134   
1135          // NOTE: trigger_error does not work here.
1136          $db->sql_return_on_error(true);
1137   
1138          // If mysql is chosen, we need to adjust the schema filename slightly to reflect the correct version. ;)
1139          if ($data['dbms'] == 'mysql')
1140          {
1141              if (version_compare($db->sql_server_info(true), '4.1.3', '>='))
1142              {
1143                  $available_dbms[$data['dbms']]['SCHEMA'] .= '_41';
1144              }
1145              else
1146              {
1147                  $available_dbms[$data['dbms']]['SCHEMA'] .= '_40';
1148              }
1149          }
1150   
1151          // Ok we have the db info go ahead and read in the relevant schema
1152          // and work on building the table
1153          $dbms_schema = 'schemas/' . $available_dbms[$data['dbms']]['SCHEMA'] . '_schema.sql';
1154   
1155          // How should we treat this schema?
1156          $delimiter = $available_dbms[$data['dbms']]['DELIM'];
1157   
1158          if (file_exists($dbms_schema))
1159          {
1160              $sql_query = @file_get_contents($dbms_schema);
1161              $sql_query = preg_replace('#phpbb_#i', $data['table_prefix'], $sql_query);
1162              $sql_query = phpbb_remove_comments($sql_query);
1163              $sql_query = split_sql_file($sql_query, $delimiter);
1164   
1165              foreach ($sql_query as $sql)
1166              {
1167                  //$sql = trim(str_replace('|', ';', $sql));
1168                  if (!$db->sql_query($sql))
1169                  {
1170                      $error = $db->sql_error();
1171                      $this->p_master->db_error($error['message'], $sql, __LINE__, __FILE__);
1172                  }
1173              }
1174              unset($sql_query);
1175          }
1176   
1177          // Ok we have the db info go ahead and work on building the table
1178          if (file_exists('schemas/schema.json'))
1179          {
1180              $db_table_schema = @file_get_contents('schemas/schema.json');
1181              $db_table_schema = json_decode($db_table_schema, true);
1182          }
1183          else
1184          {
1185              global $phpbb_root_path, $phpEx, $table_prefix;
1186              $table_prefix = 'phpbb_';
1187   
1188              if (!defined('CONFIG_TABLE'))
1189              {
1190                  // We need to include the constants file for the table constants
1191                  // when we generate the schema from the migration files.
1192                  include($phpbb_root_path . 'includes/constants.' . $phpEx);
1193              }
1194   
1195              $finder = new \phpbb\finder(new \phpbb\filesystem(), $phpbb_root_path, null, $phpEx);
1196              $classes = $finder->core_path('phpbb/db/migration/data/')
1197                  ->get_classes();
1198   
1199              $sqlite_db = new \phpbb\db\driver\sqlite();
1200              $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);
1201              $db_table_schema = $schema_generator->get_schema();
1202          }
1203   
1204          if (!defined('CONFIG_TABLE'))
1205          {
1206              // CONFIG_TABLE is required by sql_create_index() to check the
1207              // length of index names. However table_prefix is not defined
1208              // here yet, so we need to create the constant ourselves.
1209              define('CONFIG_TABLE', $data['table_prefix'] . 'config');
1210          }
1211   
1212          $db_tools = new \phpbb\db\tools($db);
1213          foreach ($db_table_schema as $table_name => $table_data)
1214          {
1215              $db_tools->sql_create_table(
1216                  $data['table_prefix'] . substr($table_name, 6),
1217                  $table_data
1218              );
1219          }
1220   
1221          // Ok tables have been built, let's fill in the basic information
1222          $sql_query = file_get_contents('schemas/schema_data.sql');
1223   
1224          // Deal with any special comments and characters
1225          switch ($data['dbms'])
1226          {
1227              case 'mssql':
1228              case 'mssql_odbc':
1229              case 'mssqlnative':
1230                  $sql_query = preg_replace('#\# MSSQL IDENTITY (phpbb_[a-z_]+) (ON|OFF) \##s', 'SET IDENTITY_INSERT \1 \2;', $sql_query);
1231              break;
1232   
1233              case 'postgres':
1234                  $sql_query = preg_replace('#\# POSTGRES (BEGIN|COMMIT) \##s', '\1; ', $sql_query);
1235              break;
1236   
1237              case 'mysql':
1238              case 'mysqli':
1239                  $sql_query = str_replace('\\', '\\\\', $sql_query);
1240              break;
1241          }
1242   
1243          // Change prefix
1244          $sql_query = preg_replace('# phpbb_([^\s]*) #i', ' ' . $data['table_prefix'] . '\1 ', $sql_query);
1245   
1246          // Change language strings...
1247          $sql_query = preg_replace_callback('#\{L_([A-Z0-9\-_]*)\}#s', 'adjust_language_keys_callback', $sql_query);
1248   
1249          $sql_query = phpbb_remove_comments($sql_query);
1250          $sql_query = split_sql_file($sql_query, ';');
1251   
1252          foreach ($sql_query as $sql)
1253          {
1254              //$sql = trim(str_replace('|', ';', $sql));
1255              if (!$db->sql_query($sql))
1256              {
1257                  $error = $db->sql_error();
1258                  $this->p_master->db_error($error['message'], $sql, __LINE__, __FILE__);
1259              }
1260          }
1261          unset($sql_query);
1262   
1263          $current_time = time();
1264   
1265          $user_ip = $request->server('REMOTE_ADDR') ? phpbb_ip_normalise($request->server('REMOTE_ADDR')) : '';
1266   
1267          if ($data['script_path'] !== '/')
1268          {
1269              // Adjust destination path (no trailing slash)
1270              if (substr($data['script_path'], -1) == '/')
1271              {
1272                  $data['script_path'] = substr($data['script_path'], 0, -1);
1273              }
1274   
1275              $data['script_path'] = str_replace(array('../', './'), '', $data['script_path']);
1276   
1277              if ($data['script_path'][0] != '/')
1278              {
1279                  $data['script_path'] = '/' . $data['script_path'];
1280              }
1281          }
1282   
1283          // Set default config and post data, this applies to all DB's
1284          $sql_ary = array(
1285              'INSERT INTO ' . $data['table_prefix'] . "config (config_name, config_value)
1286                  VALUES ('board_startdate', '$current_time')",
1287   
1288              'INSERT INTO ' . $data['table_prefix'] . "config (config_name, config_value)
1289                  VALUES ('default_lang', '" . $db->sql_escape($data['default_lang']) . "')",
1290   
1291              'UPDATE ' . $data['table_prefix'] . "config
1292                  SET config_value = '" . $db->sql_escape($data['img_imagick']) . "'
1293                  WHERE config_name = 'img_imagick'",
1294   
1295              'UPDATE ' . $data['table_prefix'] . "config
1296                  SET config_value = '" . $db->sql_escape($data['server_name']) . "'
1297                  WHERE config_name = 'server_name'",
1298   
1299              'UPDATE ' . $data['table_prefix'] . "config
1300                  SET config_value = '" . $db->sql_escape($data['server_port']) . "'
1301                  WHERE config_name = 'server_port'",
1302   
1303              'UPDATE ' . $data['table_prefix'] . "config
1304                  SET config_value = '" . $db->sql_escape($data['board_email']) . "'
1305                  WHERE config_name = 'board_email'",
1306   
1307              'UPDATE ' . $data['table_prefix'] . "config
1308                  SET config_value = '" . $db->sql_escape($data['board_email']) . "'
1309                  WHERE config_name = 'board_contact'",
1310   
1311              'UPDATE ' . $data['table_prefix'] . "config
1312                  SET config_value = '" . $db->sql_escape($cookie_domain) . "'
1313                  WHERE config_name = 'cookie_domain'",
1314   
1315              'UPDATE ' . $data['table_prefix'] . "config
1316                  SET config_value = '" . $db->sql_escape($lang['default_dateformat']) . "'
1317                  WHERE config_name = 'default_dateformat'",
1318   
1319              'UPDATE ' . $data['table_prefix'] . "config
1320                  SET config_value = '" . $db->sql_escape($data['email_enable']) . "'
1321                  WHERE config_name = 'email_enable'",
1322   
1323              'UPDATE ' . $data['table_prefix'] . "config
1324                  SET config_value = '" . $db->sql_escape($data['smtp_delivery']) . "'
1325                  WHERE config_name = 'smtp_delivery'",
1326   
1327              'UPDATE ' . $data['table_prefix'] . "config
1328                  SET config_value = '" . $db->sql_escape($data['smtp_host']) . "'
1329                  WHERE config_name = 'smtp_host'",
1330   
1331              'UPDATE ' . $data['table_prefix'] . "config
1332                  SET config_value = '" . $db->sql_escape($data['smtp_auth']) . "'
1333                  WHERE config_name = 'smtp_auth_method'",
1334   
1335              'UPDATE ' . $data['table_prefix'] . "config
1336                  SET config_value = '" . $db->sql_escape($data['smtp_user']) . "'
1337                  WHERE config_name = 'smtp_username'",
1338   
1339              'UPDATE ' . $data['table_prefix'] . "config
1340                  SET config_value = '" . $db->sql_escape($data['smtp_pass']) . "'
1341                  WHERE config_name = 'smtp_password'",
1342   
1343              'UPDATE ' . $data['table_prefix'] . "config
1344                  SET config_value = '" . $db->sql_escape($data['cookie_secure']) . "'
1345                  WHERE config_name = 'cookie_secure'",
1346   
1347              'UPDATE ' . $data['table_prefix'] . "config
1348                  SET config_value = '" . $db->sql_escape($data['force_server_vars']) . "'
1349                  WHERE config_name = 'force_server_vars'",
1350   
1351              'UPDATE ' . $data['table_prefix'] . "config
1352                  SET config_value = '" . $db->sql_escape($data['script_path']) . "'
1353                  WHERE config_name = 'script_path'",
1354   
1355              'UPDATE ' . $data['table_prefix'] . "config
1356                  SET config_value = '" . $db->sql_escape($data['server_protocol']) . "'
1357                  WHERE config_name = 'server_protocol'",
1358   
1359              'UPDATE ' . $data['table_prefix'] . "config
1360                  SET config_value = '" . $db->sql_escape($data['admin_name']) . "'
1361                  WHERE config_name = 'newest_username'",
1362   
1363              'UPDATE ' . $data['table_prefix'] . "config
1364                  SET config_value = '" . md5(mt_rand()) . "'
1365                  WHERE config_name = 'avatar_salt'",
1366   
1367              'UPDATE ' . $data['table_prefix'] . "config
1368                  SET config_value = '" . md5(mt_rand()) . "'
1369                  WHERE config_name = 'plupload_salt'",
1370   
1371              'UPDATE ' . $data['table_prefix'] . "users
1372                  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'])) . "'
1373                  WHERE username = 'Admin'",
1374   
1375              'UPDATE ' . $data['table_prefix'] . "moderator_cache
1376                  SET username = '" . $db->sql_escape($data['admin_name']) . "'
1377                  WHERE username = 'Admin'",
1378   
1379              'UPDATE ' . $data['table_prefix'] . "forums
1380                  SET forum_last_poster_name = '" . $db->sql_escape($data['admin_name']) . "'
1381                  WHERE forum_last_poster_name = 'Admin'",
1382   
1383              'UPDATE ' . $data['table_prefix'] . "topics
1384                  SET topic_first_poster_name = '" . $db->sql_escape($data['admin_name']) . "', topic_last_poster_name = '" . $db->sql_escape($data['admin_name']) . "'
1385                  WHERE topic_first_poster_name = 'Admin'
1386                      OR topic_last_poster_name = 'Admin'",
1387   
1388              'UPDATE ' . $data['table_prefix'] . "users
1389                  SET user_regdate = $current_time",
1390   
1391              'UPDATE ' . $data['table_prefix'] . "posts
1392                  SET post_time = $current_time, poster_ip = '" . $db->sql_escape($user_ip) . "'",
1393   
1394              'UPDATE ' . $data['table_prefix'] . "topics
1395                  SET topic_time = $current_time, topic_last_post_time = $current_time",
1396   
1397              'UPDATE ' . $data['table_prefix'] . "forums
1398                  SET forum_last_post_time = $current_time",
1399   
1400              'UPDATE ' . $data['table_prefix'] . "config
1401                  SET config_value = '" . $db->sql_escape($db->sql_server_info(true)) . "'
1402                  WHERE config_name = 'dbms_version'",
1403          );
1404   
1405          if (@extension_loaded('gd'))
1406          {
1407              $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
1408                  SET config_value = 'core.captcha.plugins.gd'
1409                  WHERE config_name = 'captcha_plugin'";
1410   
1411              $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
1412                  SET config_value = '1'
1413                  WHERE config_name = 'captcha_gd'";
1414          }
1415   
1416          $ref = substr($referer, strpos($referer, '://') + 3);
1417   
1418          if (!(stripos($ref, $server_name) === 0))
1419          {
1420              $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
1421                  SET config_value = '0'
1422                  WHERE config_name = 'referer_validation'";
1423          }
1424   
1425          // We set a (semi-)unique cookie name to bypass login issues related to the cookie name.
1426          $cookie_name = 'phpbb3_';
1427          $rand_str = md5(mt_rand());
1428          $rand_str = str_replace('0', 'z', base_convert($rand_str, 16, 35));
1429          $rand_str = substr($rand_str, 0, 5);
1430          $cookie_name .= strtolower($rand_str);
1431   
1432          $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
1433              SET config_value = '" . $db->sql_escape($cookie_name) . "'
1434              WHERE config_name = 'cookie_name'";
1435   
1436          foreach ($sql_ary as $sql)
1437          {
1438              //$sql = trim(str_replace('|', ';', $sql));
1439   
1440              if (!$db->sql_query($sql))
1441              {
1442                  $error = $db->sql_error();
1443                  $this->p_master->db_error($error['message'], $sql, __LINE__, __FILE__);
1444              }
1445          }
1446   
1447          $submit = $lang['NEXT_STEP'];
1448   
1449          $url = $this->p_master->module_url . "?mode=$mode&amp;sub=final";
1450   
1451          $template->assign_vars(array(
1452              'BODY'        => $lang['STAGE_CREATE_TABLE_EXPLAIN'],
1453              'L_SUBMIT'    => $submit,
1454              'S_HIDDEN'    => build_hidden_fields($data),
1455              'U_ACTION'    => $url,
1456          ));
1457      }
1458   
1459      /**
1460      * Build the search index...
1461      */
1462      function build_search_index($mode, $sub)
1463      {
1464          global $db, $lang, $phpbb_root_path, $phpEx, $config, $auth, $user;
1465   
1466          // Obtain any submitted data
1467          $data = $this->get_submitted_data();
1468          $table_prefix = $data['table_prefix'];
1469   
1470          // If we get here and the extension isn't loaded it should be safe to just go ahead and load it
1471          $available_dbms = get_available_dbms($data['dbms']);
1472   
1473          if (!isset($available_dbms[$data['dbms']]))
1474          {
1475              // Someone's been silly and tried providing a non-existant dbms
1476              $this->p_master->redirect("index.$phpEx?mode=install");
1477          }
1478   
1479          $dbms = $available_dbms[$data['dbms']]['DRIVER'];
1480   
1481          // Instantiate the database
1482          $db = new $dbms();
1483          $db->sql_connect($data['dbhost'], $data['dbuser'], htmlspecialchars_decode($data['dbpasswd']), $data['dbname'], $data['dbport'], false, false);
1484   
1485          // NOTE: trigger_error does not work here.
1486          $db->sql_return_on_error(true);
1487   
1488          include_once($phpbb_root_path . 'includes/constants.' . $phpEx);
1489          include_once($phpbb_root_path . 'phpbb/search/fulltext_native.' . $phpEx);
1490   
1491          // We need to fill the config to let internal functions correctly work
1492          $config = new \phpbb\config\db($db, new \phpbb\cache\driver\null, CONFIG_TABLE);
1493          set_config(null, null, null, $config);
1494          set_config_count(null, null, null, $config);
1495   
1496          $error = false;
1497          $search = new \phpbb\search\fulltext_native($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user);
1498   
1499          $sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id
1500              FROM ' . POSTS_TABLE;
1501          $result = $db->sql_query($sql);
1502   
1503          while ($row = $db->sql_fetchrow($result))
1504          {
1505              $search->index('post', $row['post_id'], $row['post_text'], $row['post_subject'], $row['poster_id'], $row['forum_id']);
1506          }
1507          $db->sql_freeresult($result);
1508      }
1509   
1510      /**
1511      * Populate the module tables
1512      */
1513      function add_modules($mode, $sub)
1514      {
1515          global $db, $lang, $phpbb_root_path, $phpEx, $phpbb_extension_manager, $config, $phpbb_container;
1516   
1517          // modules require an extension manager
1518          if (empty($phpbb_extension_manager))
1519          {
1520              $phpbb_extension_manager = $phpbb_container->get('ext.manager');
1521          }
1522   
1523          include_once($phpbb_root_path . 'includes/acp/acp_modules.' . $phpEx);
1524   
1525          $_module = new acp_modules();
1526          $module_classes = array('acp', 'mcp', 'ucp');
1527   
1528          // Add categories
1529          foreach ($module_classes as $module_class)
1530          {
1531              $categories = array();
1532   
1533              // Set the module class
1534              $_module->module_class = $module_class;
1535   
1536              foreach ($this->module_categories[$module_class] as $cat_name => $subs)
1537              {
1538                  $basename = '';
1539                  // Check if this sub-category has a basename. If it has, use it.
1540                  if (isset($this->module_categories_basenames[$cat_name]))
1541                  {
1542                      $basename = $this->module_categories_basenames[$cat_name];
1543                  }
1544                  $module_data = array(
1545                      'module_basename'    => $basename,
1546                      'module_enabled'    => 1,
1547                      'module_display'    => 1,
1548                      'parent_id'            => 0,
1549                      'module_class'        => $module_class,
1550                      'module_langname'    => $cat_name,
1551                      'module_mode'        => '',
1552                      'module_auth'        => '',
1553                  );
1554   
1555                  // Add category
1556                  $_module->update_module_data($module_data, true);
1557   
1558                  // Check for last sql error happened
1559                  if ($db->get_sql_error_triggered())
1560                  {
1561                      $error = $db->sql_error($db->get_sql_error_sql());
1562                      $this->p_master->db_error($error['message'], $db->get_sql_error_sql(), __LINE__, __FILE__);
1563                  }
1564   
1565                  $categories[$cat_name]['id'] = (int) $module_data['module_id'];
1566                  $categories[$cat_name]['parent_id'] = 0;
1567   
1568                  // Create sub-categories...
1569                  if (is_array($subs))
1570                  {
1571                      foreach ($subs as $level2_name)
1572                      {
1573                          $basename = '';
1574                          // Check if this sub-category has a basename. If it has, use it.
1575                          if (isset($this->module_categories_basenames[$level2_name]))
1576                          {
1577                              $basename = $this->module_categories_basenames[$level2_name];
1578                          }
1579                          $module_data = array(
1580                              'module_basename'    => $basename,
1581                              'module_enabled'    => 1,
1582                              'module_display'    => 1,
1583                              'parent_id'            => (int) $categories[$cat_name]['id'],
1584                              'module_class'        => $module_class,
1585                              'module_langname'    => $level2_name,
1586                              'module_mode'        => '',
1587                              'module_auth'        => '',
1588                          );
1589   
1590                          $_module->update_module_data($module_data, true);
1591   
1592                          // Check for last sql error happened
1593                          if ($db->get_sql_error_triggered())
1594                          {
1595                              $error = $db->sql_error($db->get_sql_error_sql());
1596                              $this->p_master->db_error($error['message'], $db->get_sql_error_sql(), __LINE__, __FILE__);
1597                          }
1598   
1599                          $categories[$level2_name]['id'] = (int) $module_data['module_id'];
1600                          $categories[$level2_name]['parent_id'] = (int) $categories[$cat_name]['id'];
1601                      }
1602                  }
1603              }
1604   
1605              // Get the modules we want to add... returned sorted by name
1606              $module_info = $_module->get_module_infos('', $module_class);
1607   
1608              foreach ($module_info as $module_basename => $fileinfo)
1609              {
1610                  foreach ($fileinfo['modes'] as $module_mode => $row)
1611                  {
1612                      foreach ($row['cat'] as $cat_name)
1613                      {
1614                          if (!isset($categories[$cat_name]))
1615                          {
1616                              continue;
1617                          }
1618   
1619                          $module_data = array(
1620                              'module_basename'    => $module_basename,
1621                              'module_enabled'    => 1,
1622                              'module_display'    => (isset($row['display'])) ? (int) $row['display'] : 1,
1623                              'parent_id'            => (int) $categories[$cat_name]['id'],
1624                              'module_class'        => $module_class,
1625                              'module_langname'    => $row['title'],
1626                              'module_mode'        => $module_mode,
1627                              'module_auth'        => $row['auth'],
1628                          );
1629   
1630                          $_module->update_module_data($module_data, true);
1631   
1632                          // Check for last sql error happened
1633                          if ($db->get_sql_error_triggered())
1634                          {
1635                              $error = $db->sql_error($db->get_sql_error_sql());
1636                              $this->p_master->db_error($error['message'], $db->get_sql_error_sql(), __LINE__, __FILE__);
1637                          }
1638                      }
1639                  }
1640              }
1641   
1642              // Move some of the modules around since the code above will put them in the wrong place
1643              if ($module_class == 'acp')
1644              {
1645                  // Move main module 4 up...
1646                  $sql = 'SELECT *
1647                      FROM ' . MODULES_TABLE . "
1648                      WHERE module_basename = 'acp_main'
1649                          AND module_class = 'acp'
1650                          AND module_mode = 'main'";
1651                  $result = $db->sql_query($sql);
1652                  $row = $db->sql_fetchrow($result);
1653                  $db->sql_freeresult($result);
1654   
1655                  $_module->move_module_by($row, 'move_up', 4);
1656   
1657                  // Move permissions intro screen module 4 up...
1658                  $sql = 'SELECT *
1659                      FROM ' . MODULES_TABLE . "
1660                      WHERE module_basename = 'acp_permissions'
1661                          AND module_class = 'acp'
1662                          AND module_mode = 'intro'";
1663                  $result = $db->sql_query($sql);
1664                  $row = $db->sql_fetchrow($result);
1665                  $db->sql_freeresult($result);
1666   
1667                  $_module->move_module_by($row, 'move_up', 4);
1668   
1669                  // Move manage users screen module 5 up...
1670                  $sql = 'SELECT *
1671                      FROM ' . MODULES_TABLE . "
1672                      WHERE module_basename = 'acp_users'
1673                          AND module_class = 'acp'
1674                          AND module_mode = 'overview'";
1675                  $result = $db->sql_query($sql);
1676                  $row = $db->sql_fetchrow($result);
1677                  $db->sql_freeresult($result);
1678   
1679                  $_module->move_module_by($row, 'move_up', 5);
1680   
1681                  // Move extension management module 1 up...
1682                  $sql = 'SELECT *
1683                      FROM ' . MODULES_TABLE . "
1684                      WHERE module_langname = 'ACP_EXTENSION_MANAGEMENT'
1685                          AND module_class = 'acp'
1686                          AND module_mode = ''
1687                          AND module_basename = ''";
1688                  $result = $db->sql_query($sql);
1689                  $row = $db->sql_fetchrow($result);
1690                  $db->sql_freeresult($result);
1691   
1692                  $_module->move_module_by($row, 'move_up', 1);
1693              }
1694   
1695              if ($module_class == 'mcp')
1696              {
1697                  // Move pm report details module 3 down...
1698                  $sql = 'SELECT *
1699                      FROM ' . MODULES_TABLE . "
1700                      WHERE module_basename = 'mcp_pm_reports'
1701                          AND module_class = 'mcp'
1702                          AND module_mode = 'pm_report_details'";
1703                  $result = $db->sql_query($sql);
1704                  $row = $db->sql_fetchrow($result);
1705                  $db->sql_freeresult($result);
1706   
1707                  $_module->move_module_by($row, 'move_down', 3);
1708   
1709                  // Move closed pm reports module 3 down...
1710                  $sql = 'SELECT *
1711                      FROM ' . MODULES_TABLE . "
1712                      WHERE module_basename = 'mcp_pm_reports'
1713                          AND module_class = 'mcp'
1714                          AND module_mode = 'pm_reports_closed'";
1715                  $result = $db->sql_query($sql);
1716                  $row = $db->sql_fetchrow($result);
1717                  $db->sql_freeresult($result);
1718   
1719                  $_module->move_module_by($row, 'move_down', 3);
1720   
1721                  // Move open pm reports module 3 down...
1722                  $sql = 'SELECT *
1723                      FROM ' . MODULES_TABLE . "
1724                      WHERE module_basename = 'mcp_pm_reports'
1725                          AND module_class = 'mcp'
1726                          AND module_mode = 'pm_reports'";
1727                  $result = $db->sql_query($sql);
1728                  $row = $db->sql_fetchrow($result);
1729                  $db->sql_freeresult($result);
1730   
1731                  $_module->move_module_by($row, 'move_down', 3);
1732              }
1733   
1734              if ($module_class == 'ucp')
1735              {
1736                  // Move attachment module 4 down...
1737                  $sql = 'SELECT *
1738                      FROM ' . MODULES_TABLE . "
1739                      WHERE module_basename = 'ucp_attachments'
1740                          AND module_class = 'ucp'
1741                          AND module_mode = 'attachments'";
1742                  $result = $db->sql_query($sql);
1743                  $row = $db->sql_fetchrow($result);
1744                  $db->sql_freeresult($result);
1745   
1746                  $_module->move_module_by($row, 'move_down', 4);
1747   
1748                  // Move notification options module 4 down...
1749                  $sql = 'SELECT *
1750                      FROM ' . MODULES_TABLE . "
1751                      WHERE module_basename = 'ucp_notifications'
1752                          AND module_class = 'ucp'
1753                          AND module_mode = 'notification_options'";
1754                  $result = $db->sql_query($sql);
1755                  $row = $db->sql_fetchrow($result);
1756                  $db->sql_freeresult($result);
1757   
1758                  $_module->move_module_by($row, 'move_down', 4);
1759   
1760                  // Move OAuth module 5 down...
1761                  $sql = 'SELECT *
1762                      FROM ' . MODULES_TABLE . "
1763                      WHERE module_basename = 'ucp_auth_link'
1764                          AND module_class = 'ucp'
1765                          AND module_mode = 'auth_link'";
1766                  $result = $db->sql_query($sql);
1767                  $row = $db->sql_fetchrow($result);
1768                  $db->sql_freeresult($result);
1769   
1770                  $_module->move_module_by($row, 'move_down', 5);
1771              }
1772   
1773              // And now for the special ones
1774              // (these are modules which appear in multiple categories and thus get added manually to some for more control)
1775              if (isset($this->module_extras[$module_class]))
1776              {
1777                  foreach ($this->module_extras[$module_class] as $cat_name => $mods)
1778                  {
1779                      $sql = 'SELECT module_id, left_id, right_id
1780                          FROM ' . MODULES_TABLE . "
1781                          WHERE module_langname = '" . $db->sql_escape($cat_name) . "'
1782                              AND module_class = '" . $db->sql_escape($module_class) . "'";
1783                      $result = $db->sql_query_limit($sql, 1);
1784                      $row2 = $db->sql_fetchrow($result);
1785                      $db->sql_freeresult($result);
1786   
1787                      foreach ($mods as $mod_name)
1788                      {
1789                          $sql = 'SELECT *
1790                              FROM ' . MODULES_TABLE . "
1791                              WHERE module_langname = '" . $db->sql_escape($mod_name) . "'
1792                                  AND module_class = '" . $db->sql_escape($module_class) . "'
1793                                  AND module_basename <> ''";
1794                          $result = $db->sql_query_limit($sql, 1);
1795                          $row = $db->sql_fetchrow($result);
1796                          $db->sql_freeresult($result);
1797   
1798                          $module_data = array(
1799                              'module_basename'    => $row['module_basename'],
1800                              'module_enabled'    => (int) $row['module_enabled'],
1801                              'module_display'    => (int) $row['module_display'],
1802                              'parent_id'            => (int) $row2['module_id'],
1803                              'module_class'        => $row['module_class'],
1804                              'module_langname'    => $row['module_langname'],
1805                              'module_mode'        => $row['module_mode'],
1806                              'module_auth'        => $row['module_auth'],
1807                          );
1808   
1809                          $_module->update_module_data($module_data, true);
1810   
1811                          // Check for last sql error happened
1812                          if ($db->get_sql_error_triggered())
1813                          {
1814                              $error = $db->sql_error($db->get_sql_error_sql());
1815                              $this->p_master->db_error($error['message'], $db->get_sql_error_sql(), __LINE__, __FILE__);
1816                          }
1817                      }
1818                  }
1819              }
1820   
1821              $_module->remove_cache_file();
1822          }
1823      }
1824   
1825      /**
1826      * Populate the language tables
1827      */
1828      function add_language($mode, $sub)
1829      {
1830          global $db, $lang, $phpbb_root_path, $phpEx;
1831   
1832          $dir = @opendir($phpbb_root_path . 'language');
1833   
1834          if (!$dir)
1835          {
1836              $this->error('Unable to access the language directory', __LINE__, __FILE__);
1837          }
1838   
1839          $installed_languages = array();
1840          while (($file = readdir($dir)) !== false)
1841          {
1842              $path = $phpbb_root_path . 'language/' . $file;
1843   
1844              if ($file == '.' || $file == '..' || is_link($path) || is_file($path) || $file == 'CVS')
1845              {
1846                  continue;
1847              }
1848   
1849              if (is_dir($path) && file_exists($path . '/iso.txt'))
1850              {
1851                  $lang_file = file("$path/iso.txt");
1852   
1853                  $lang_pack = array(
1854                      'lang_iso'            => basename($path),
1855                      'lang_dir'            => basename($path),
1856                      'lang_english_name'    => trim(htmlspecialchars($lang_file[0])),
1857                      'lang_local_name'    => trim(htmlspecialchars($lang_file[1], ENT_COMPAT, 'UTF-8')),
1858                      'lang_author'        => trim(htmlspecialchars($lang_file[2], ENT_COMPAT, 'UTF-8')),
1859                  );
1860   
1861                  $db->sql_query('INSERT INTO ' . LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $lang_pack));
1862   
1863                  $installed_languages[] = (int) $db->sql_nextid();
1864                  if ($db->get_sql_error_triggered())
1865                  {
1866                      $error = $db->sql_error($db->get_sql_error_sql());
1867                      $this->p_master->db_error($error['message'], $db->get_sql_error_sql(), __LINE__, __FILE__);
1868                  }
1869              }
1870          }
1871          closedir($dir);
1872   
1873          $sql = 'SELECT *
1874              FROM ' . PROFILE_FIELDS_TABLE;
1875          $result = $db->sql_query($sql);
1876   
1877          $profile_fields = array();
1878          $insert_buffer = new \phpbb\db\sql_insert_buffer($db, PROFILE_LANG_TABLE);
1879          while ($row = $db->sql_fetchrow($result))
1880          {
1881              foreach ($installed_languages as $lang_id)
1882              {
1883                  $insert_buffer->insert(array(
1884                      'field_id'                => $row['field_id'],
1885                      'lang_id'                => $lang_id,
1886                      'lang_name'                => strtoupper(substr($row['field_name'], 6)),// Remove phpbb_ from field name
1887                      'lang_explain'            => '',
1888                      'lang_default_value'    => '',
1889                  ));
1890              }
1891          }
1892          $db->sql_freeresult($result);
1893   
1894          $insert_buffer->flush();
1895      }
1896   
1897      /**
1898      * Add search robots to the database
1899      */
1900      function add_bots($mode, $sub)
1901      {
1902          global $db, $lang, $phpbb_root_path, $phpEx, $config;
1903   
1904          // Obtain any submitted data
1905          $data = $this->get_submitted_data();
1906   
1907          // We need to fill the config to let internal functions correctly work
1908          $config = new \phpbb\config\db($db, new \phpbb\cache\driver\null, CONFIG_TABLE);
1909          set_config(null, null, null, $config);
1910          set_config_count(null, null, null, $config);
1911   
1912          $sql = 'SELECT group_id
1913              FROM ' . GROUPS_TABLE . "
1914              WHERE group_name = 'BOTS'";
1915          $result = $db->sql_query($sql);
1916          $group_id = (int) $db->sql_fetchfield('group_id');
1917          $db->sql_freeresult($result);
1918   
1919          if (!$group_id)
1920          {
1921              // If we reach this point then something has gone very wrong
1922              $this->p_master->error($lang['NO_GROUP'], __LINE__, __FILE__);
1923          }
1924   
1925          if (!function_exists('user_add'))
1926          {
1927              include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
1928          }
1929   
1930          foreach ($this->bot_list as $bot_name => $bot_ary)
1931          {
1932              $user_row = array(
1933                  'user_type'                => USER_IGNORE,
1934                  'group_id'                => $group_id,
1935                  'username'                => $bot_name,
1936                  'user_regdate'            => time(),
1937                  'user_password'            => '',
1938                  'user_colour'            => '9E8DA7',
1939                  'user_email'            => '',
1940                  'user_lang'                => $data['default_lang'],
1941                  'user_style'            => 1,
1942                  'user_timezone'            => 'UTC',
1943                  'user_dateformat'        => $lang['default_dateformat'],
1944                  'user_allow_massemail'    => 0,
1945                  'user_allow_pm'            => 0,
1946              );
1947   
1948              $user_id = user_add($user_row);
1949   
1950              if (!$user_id)
1951              {
1952                  // If we can't insert this user then continue to the next one to avoid inconsistent data
1953                  $this->p_master->db_error('Unable to insert bot into users table', $db->get_sql_error_sql(), __LINE__, __FILE__, true);
1954                  continue;
1955              }
1956   
1957              $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $db->sql_build_array('INSERT', array(
1958                  'bot_active'    => 1,
1959                  'bot_name'        => (string) $bot_name,
1960                  'user_id'        => (int) $user_id,
1961                  'bot_agent'        => (string) $bot_ary[0],
1962                  'bot_ip'        => (string) $bot_ary[1],
1963              ));
1964   
1965              $result = $db->sql_query($sql);
1966          }
1967      }
1968   
1969      /**
1970      * Sends an email to the board administrator with their password and some useful links
1971      */
1972      function email_admin($mode, $sub)
1973      {
1974          global $auth, $config, $db, $lang, $template, $user, $phpbb_root_path, $phpbb_admin_path, $phpEx;
1975   
1976          $this->page_title = $lang['STAGE_FINAL'];
1977   
1978          // Obtain any submitted data
1979          $data = $this->get_submitted_data();
1980   
1981          // We need to fill the config to let internal functions correctly work
1982          $config = new \phpbb\config\db($db, new \phpbb\cache\driver\null, CONFIG_TABLE);
1983          set_config(null, null, null, $config);
1984          set_config_count(null, null, null, $config);
1985   
1986          $user->session_begin();
1987          $auth->login($data['admin_name'], $data['admin_pass1'], false, true, true);
1988   
1989          // OK, Now that we've reached this point we can be confident that everything
1990          // is installed and working......I hope :)
1991          // So it's time to send an email to the administrator confirming the details
1992          // they entered
1993   
1994          if ($config['email_enable'])
1995          {
1996              include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
1997   
1998              $messenger = new messenger(false);
1999   
2000              $messenger->template('installed', $data['language']);
2001   
2002              $messenger->to($data['board_email'], $data['admin_name']);
2003   
2004              $messenger->anti_abuse_headers($config, $user);
2005   
2006              $messenger->assign_vars(array(
2007                  'USERNAME'        => htmlspecialchars_decode($data['admin_name']),
2008                  'PASSWORD'        => htmlspecialchars_decode($data['admin_pass1']))
2009              );
2010   
2011              $messenger->send(NOTIFY_EMAIL);
2012          }
2013   
2014          // And finally, add a note to the log
2015          add_log('admin', 'LOG_INSTALL_INSTALLED', $config['version']);
2016   
2017          $template->assign_vars(array(
2018              'TITLE'        => $lang['INSTALL_CONGRATS'],
2019              'BODY'        => sprintf($lang['INSTALL_CONGRATS_EXPLAIN'], $config['version'], append_sid($phpbb_root_path . 'install/index.' . $phpEx, 'mode=convert&amp;language=' . $data['language']), '../docs/README.html'),
2020              'L_SUBMIT'    => $lang['INSTALL_LOGIN'],
2021              'U_ACTION'    => append_sid($phpbb_admin_path . 'index.' . $phpEx, 'i=send_statistics&amp;mode=send_statistics'),
2022          ));
2023      }
2024   
2025      /**
2026      * Check if the avatar directory is writable and disable avatars
2027      * if it isn't writable.
2028      */
2029      function disable_avatars_if_unwritable()
2030      {
2031          global $phpbb_root_path;
2032   
2033          if (!phpbb_is_writable($phpbb_root_path . 'images/avatars/upload/'))
2034          {
2035              set_config('allow_avatar', 0);
2036              set_config('allow_avatar_upload', 0);
2037          }
2038      }
2039   
2040      /**
2041      * Populate migrations for the installation
2042      *
2043      * This "installs" all migrations from (root path)/phpbb/db/migrations/data.
2044      * "installs" means it adds all migrations to the migrations table, but does not
2045      * perform any of the actions in the migrations.
2046      *
2047      * @param \phpbb\extension\manager $extension_manager
2048      * @param \phpbb\db\migrator $migrator
2049      */
2050      function populate_migrations($extension_manager, $migrator)
2051      {
2052          $finder = $extension_manager->get_finder();
2053   
2054          $migrations = $finder
2055              ->core_path('phpbb/db/migration/data/')
2056              ->get_classes();
2057          $migrator->populate_migrations($migrations);
2058      }
2059   
2060      /**
2061      * Generate a list of available mail server authentication methods
2062      */
2063      function mail_auth_select($selected_method)
2064      {
2065          global $lang;
2066   
2067          $auth_methods = array('PLAIN', 'LOGIN', 'CRAM-MD5', 'DIGEST-MD5', 'POP-BEFORE-SMTP');
2068          $s_smtp_auth_options = '';
2069   
2070          foreach ($auth_methods as $method)
2071          {
2072              $s_smtp_auth_options .= '<option value="' . $method . '"' . (($selected_method == $method) ? ' selected="selected"' : '') . '>' . $lang['SMTP_' . str_replace('-', '_', $method)] . '</option>';
2073          }
2074   
2075          return $s_smtp_auth_options;
2076      }
2077   
2078      /**
2079      * Get submitted data
2080      */
2081      function get_submitted_data()
2082      {
2083          return array(
2084              'language'        => basename(request_var('language', '')),
2085              'dbms'            => request_var('dbms', ''),
2086              'dbhost'        => request_var('dbhost', ''),
2087              'dbport'        => request_var('dbport', ''),
2088              'dbuser'        => request_var('dbuser', ''),
2089              'dbpasswd'        => request_var('dbpasswd', '', true),
2090              'dbname'        => request_var('dbname', ''),
2091              'table_prefix'    => request_var('table_prefix', ''),
2092              'default_lang'    => basename(request_var('default_lang', '')),
2093              'admin_name'    => utf8_normalize_nfc(request_var('admin_name', '', true)),
2094              'admin_pass1'    => request_var('admin_pass1', '', true),
2095              'admin_pass2'    => request_var('admin_pass2', '', true),
2096              'board_email'    => strtolower(request_var('board_email', '')),
2097              'img_imagick'    => request_var('img_imagick', ''),
2098              'ftp_path'        => request_var('ftp_path', ''),
2099              'ftp_user'        => request_var('ftp_user', ''),
2100              'ftp_pass'        => request_var('ftp_pass', ''),
2101              'email_enable'    => request_var('email_enable', ''),
2102              'smtp_delivery'    => request_var('smtp_delivery', ''),
2103              'smtp_host'        => request_var('smtp_host', ''),
2104              'smtp_auth'        => request_var('smtp_auth', ''),
2105              'smtp_user'        => request_var('smtp_user', ''),
2106              'smtp_pass'        => request_var('smtp_pass', ''),
2107              'cookie_secure'    => request_var('cookie_secure', ''),
2108              'force_server_vars'    => request_var('force_server_vars', ''),
2109              'server_protocol'    => request_var('server_protocol', ''),
2110              'server_name'    => request_var('server_name', ''),
2111              'server_port'    => request_var('server_port', ''),
2112              'script_path'    => request_var('script_path', ''),
2113          );
2114      }
2115   
2116      /**
2117      * The information below will be used to build the input fields presented to the user
2118      */
2119      var $db_config_options = array(
2120          'legend1'                => 'DB_CONFIG',
2121          'dbms'                    => array('lang' => 'DBMS',            'type' => 'select', 'options' => 'dbms_select(\'{VALUE}\')', 'explain' => false),
2122          'dbhost'                => array('lang' => 'DB_HOST',        'type' => 'text:25:100', 'explain' => true),
2123          'dbport'                => array('lang' => 'DB_PORT',        'type' => 'text:25:100', 'explain' => true),
2124          'dbname'                => array('lang' => 'DB_NAME',        'type' => 'text:25:100', 'explain' => false),
2125          'dbuser'                => array('lang' => 'DB_USERNAME',    'type' => 'text:25:100', 'explain' => false),
2126          'dbpasswd'                => array('lang' => 'DB_PASSWORD',    'type' => 'password:25:100', 'explain' => false),
2127          'table_prefix'            => array('lang' => 'TABLE_PREFIX',    'type' => 'text:25:100', 'explain' => true),
2128      );
2129      var $admin_config_options = array(
2130          'legend1'                => 'ADMIN_CONFIG',
2131          'default_lang'            => array('lang' => 'DEFAULT_LANG',                'type' => 'select', 'options' => '$this->module->inst_language_select(\'{VALUE}\')', 'explain' => false),
2132          'admin_name'            => array('lang' => 'ADMIN_USERNAME',            'type' => 'text:25:100', 'explain' => true),
2133          'admin_pass1'            => array('lang' => 'ADMIN_PASSWORD',            'type' => 'password:25:100', 'explain' => true),
2134          'admin_pass2'            => array('lang' => 'ADMIN_PASSWORD_CONFIRM',    'type' => 'password:25:100', 'explain' => false),
2135          'board_email'            => array('lang' => 'CONTACT_EMAIL',                'type' => 'email:25:100', 'explain' => false),
2136      );
2137      var $advanced_config_options = array(
2138          'legend1'                => 'ACP_EMAIL_SETTINGS',
2139          'email_enable'            => array('lang' => 'ENABLE_EMAIL',        'type' => 'radio:enabled_disabled', 'explain' => true),
2140          'smtp_delivery'            => array('lang' => 'USE_SMTP',            'type' => 'radio:yes_no', 'explain' => true),
2141          'smtp_host'                => array('lang' => 'SMTP_SERVER',        'type' => 'text:25:50', 'explain' => false),
2142          'smtp_auth'                => array('lang' => 'SMTP_AUTH_METHOD',    'type' => 'select', 'options' => '$this->module->mail_auth_select(\'{VALUE}\')', 'explain' => true),
2143          'smtp_user'                => array('lang' => 'SMTP_USERNAME',        'type' => 'text:25:255', 'explain' => true, 'options' => array('autocomplete' => 'off')),
2144          'smtp_pass'                => array('lang' => 'SMTP_PASSWORD',        'type' => 'password:25:255', 'explain' => true, 'options' => array('autocomplete' => 'off')),
2145   
2146          'legend2'                => 'SERVER_URL_SETTINGS',
2147          'cookie_secure'            => array('lang' => 'COOKIE_SECURE',        'type' => 'radio:enabled_disabled', 'explain' => true),
2148          'force_server_vars'        => array('lang' => 'FORCE_SERVER_VARS',    'type' => 'radio:yes_no', 'explain' => true),
2149          'server_protocol'        => array('lang' => 'SERVER_PROTOCOL',    'type' => 'text:10:10', 'explain' => true),
2150          'server_name'            => array('lang' => 'SERVER_NAME',        'type' => 'text:40:255', 'explain' => true),
2151          'server_port'            => array('lang' => 'SERVER_PORT',        'type' => 'text:5:5', 'explain' => true),
2152          'script_path'            => array('lang' => 'SCRIPT_PATH',        'type' => 'text::255', 'explain' => true),
2153      );
2154   
2155      /**
2156      * Specific PHP modules we may require for certain optional or extended features
2157      */
2158      var $php_dlls_other = array('zlib', 'ftp', 'gd', 'xml');
2159   
2160      /**
2161      * A list of the web-crawlers/bots we recognise by default
2162      *
2163      * Candidates but not included:
2164      * 'Accoona [Bot]'                'Accoona-AI-Agent/'
2165      * 'ASPseek [Crawler]'            'ASPseek/'
2166      * 'Boitho [Crawler]'            'boitho.com-dc/'
2167      * 'Bunnybot [Bot]'                'powered by www.buncat.de'
2168      * 'Cosmix [Bot]'                'cfetch/'
2169      * 'Crawler Search [Crawler]'    '.Crawler-Search.de'
2170      * 'Findexa [Crawler]'            'Findexa Crawler ('
2171      * 'GBSpider [Spider]'            'GBSpider v'
2172      * 'genie [Bot]'                    'genieBot ('
2173      * 'Hogsearch [Bot]'                'oegp v. 1.3.0'
2174      * 'Insuranco [Bot]'                'InsurancoBot'
2175      * 'IRLbot [Bot]'                'http://irl.cs.tamu.edu/crawler'
2176      * 'ISC Systems [Bot]'            'ISC Systems iRc Search'
2177      * 'Jyxobot [Bot]'                'Jyxobot/'
2178      * 'Kraehe [Metasuche]'            '-DIE-KRAEHE- META-SEARCH-ENGINE/'
2179      * 'LinkWalker'                    'LinkWalker'
2180      * 'MMSBot [Bot]'                'http://www.mmsweb.at/bot.html'
2181      * 'Naver [Bot]'                    'nhnbot@naver.com)'
2182      * 'NetResearchServer'            'NetResearchServer/'
2183      * 'Nimble [Crawler]'            'NimbleCrawler'
2184      * 'Ocelli [Bot]'                'Ocelli/'
2185      * 'Onsearch [Bot]'                'onCHECK-Robot'
2186      * 'Orange [Spider]'                'OrangeSpider'
2187      * 'Sproose [Bot]'                'http://www.sproose.com/bot'
2188      * 'Susie [Sync]'                '!Susie (http://www.sync2it.com/susie)'
2189      * 'Tbot [Bot]'                    'Tbot/'
2190      * 'Thumbshots [Capture]'        'thumbshots-de-Bot'
2191      * 'Vagabondo [Crawler]'            'http://webagent.wise-guys.nl/'
2192      * 'Walhello [Bot]'                'appie 1.1 (www.walhello.com)'
2193      * 'WissenOnline [Bot]'            'WissenOnline-Bot'
2194      * 'WWWeasel [Bot]'                'WWWeasel Robot v'
2195      * 'Xaldon [Spider]'                'Xaldon WebSpider'
2196      */
2197      var $bot_list = array(
2198          'AdsBot [Google]'            => array('AdsBot-Google', ''),
2199          'Alexa [Bot]'                => array('ia_archiver', ''),
2200          'Alta Vista [Bot]'            => array('Scooter/', ''),
2201          'Ask Jeeves [Bot]'            => array('Ask Jeeves', ''),
2202          'Baidu [Spider]'            => array('Baiduspider', ''),
2203          'Bing [Bot]'                => array('bingbot/', ''),
2204          'Exabot [Bot]'                => array('Exabot', ''),
2205          'FAST Enterprise [Crawler]'    => array('FAST Enterprise Crawler', ''),
2206          'FAST WebCrawler [Crawler]'    => array('FAST-WebCrawler/', ''),
2207          'Francis [Bot]'                => array('http://www.neomo.de/', ''),
2208          'Gigabot [Bot]'                => array('Gigabot/', ''),
2209          'Google Adsense [Bot]'        => array('Mediapartners-Google', ''),
2210          'Google Desktop'            => array('Google Desktop', ''),
2211          'Google Feedfetcher'        => array('Feedfetcher-Google', ''),
2212          'Google [Bot]'                => array('Googlebot', ''),
2213          'Heise IT-Markt [Crawler]'    => array('heise-IT-Markt-Crawler', ''),
2214          'Heritrix [Crawler]'        => array('heritrix/1.', ''),
2215          'IBM Research [Bot]'        => array('ibm.com/cs/crawler', ''),
2216          'ICCrawler - ICjobs'        => array('ICCrawler - ICjobs', ''),
2217          'ichiro [Crawler]'            => array('ichiro/', ''),
2218          'Majestic-12 [Bot]'            => array('MJ12bot/', ''),
2219          'Metager [Bot]'                => array('MetagerBot/', ''),
2220          'MSN NewsBlogs'                => array('msnbot-NewsBlogs/', ''),
2221          'MSN [Bot]'                    => array('msnbot/', ''),
2222          'MSNbot Media'                => array('msnbot-media/', ''),
2223          'Nutch [Bot]'                => array('http://lucene.apache.org/nutch/', ''),
2224          'Online link [Validator]'    => array('online link validator', ''),
2225          'psbot [Picsearch]'            => array('psbot/0', ''),
2226          'Sensis [Crawler]'            => array('Sensis Web Crawler', ''),
2227          'SEO Crawler'                => array('SEO search Crawler/', ''),
2228          'Seoma [Crawler]'            => array('Seoma [SEO Crawler]', ''),
2229          'SEOSearch [Crawler]'        => array('SEOsearch/', ''),
2230          'Snappy [Bot]'                => array('Snappy/1.1 ( http://www.urltrends.com/ )', ''),
2231          'Steeler [Crawler]'            => array('http://www.tkl.iis.u-tokyo.ac.jp/~crawler/', ''),
2232          'Telekom [Bot]'                => array('crawleradmin.t-info@telekom.de', ''),
2233          'TurnitinBot [Bot]'            => array('TurnitinBot/', ''),
2234          'Voyager [Bot]'                => array('voyager/', ''),
2235          'W3 [Sitesearch]'            => array('W3 SiteSearch Crawler', ''),
2236          'W3C [Linkcheck]'            => array('W3C-checklink/', ''),
2237          'W3C [Validator]'            => array('W3C_Validator', ''),
2238          'YaCy [Bot]'                => array('yacybot', ''),
2239          'Yahoo MMCrawler [Bot]'        => array('Yahoo-MMCrawler/', ''),
2240          'Yahoo Slurp [Bot]'            => array('Yahoo! DE Slurp', ''),
2241          'Yahoo [Bot]'                => array('Yahoo! Slurp', ''),
2242          'YahooSeeker [Bot]'            => array('YahooSeeker/', ''),
2243      );
2244   
2245      /**
2246      * Define the module structure so that we can populate the database without
2247      * needing to hard-code module_id values
2248      */
2249      var $module_categories = array(
2250          'acp'    => array(
2251              'ACP_CAT_GENERAL'        => array(
2252                  'ACP_QUICK_ACCESS',
2253                  'ACP_BOARD_CONFIGURATION',
2254                  'ACP_CLIENT_COMMUNICATION',
2255                  'ACP_SERVER_CONFIGURATION',
2256              ),
2257              'ACP_CAT_FORUMS'        => array(
2258                  'ACP_MANAGE_FORUMS',
2259                  'ACP_FORUM_BASED_PERMISSIONS',
2260              ),
2261              'ACP_CAT_POSTING'        => array(
2262                  'ACP_MESSAGES',
2263                  'ACP_ATTACHMENTS',
2264              ),
2265              'ACP_CAT_USERGROUP'        => array(
2266                  'ACP_CAT_USERS',
2267                  'ACP_GROUPS',
2268                  'ACP_USER_SECURITY',
2269              ),
2270              'ACP_CAT_PERMISSIONS'    => array(
2271                  'ACP_GLOBAL_PERMISSIONS',
2272                  'ACP_FORUM_BASED_PERMISSIONS',
2273                  'ACP_PERMISSION_ROLES',
2274                  'ACP_PERMISSION_MASKS',
2275              ),
2276              'ACP_CAT_CUSTOMISE'        => array(
2277                  'ACP_STYLE_MANAGEMENT',
2278                  'ACP_EXTENSION_MANAGEMENT',
2279                  'ACP_LANGUAGE',
2280              ),
2281              'ACP_CAT_MAINTENANCE'    => array(
2282                  'ACP_FORUM_LOGS',
2283                  'ACP_CAT_DATABASE',
2284              ),
2285              'ACP_CAT_SYSTEM'        => array(
2286                  'ACP_AUTOMATION',
2287                  'ACP_GENERAL_TASKS',
2288                  'ACP_MODULE_MANAGEMENT',
2289              ),
2290              'ACP_CAT_DOT_MODS'        => null,
2291          ),
2292          'mcp'    => array(
2293              'MCP_MAIN'        => null,
2294              'MCP_QUEUE'        => null,
2295              'MCP_REPORTS'    => null,
2296              'MCP_NOTES'        => null,
2297              'MCP_WARN'        => null,
2298              'MCP_LOGS'        => null,
2299              'MCP_BAN'        => null,
2300          ),
2301          'ucp'    => array(
2302              'UCP_MAIN'            => null,
2303              'UCP_PROFILE'        => null,
2304              'UCP_PREFS'            => null,
2305              'UCP_PM'            => null,
2306              'UCP_USERGROUPS'    => null,
2307              'UCP_ZEBRA'            => null,
2308          ),
2309      );
2310      var $module_categories_basenames = array(
2311          'UCP_PM' => 'ucp_pm',
2312      );
2313   
2314      var $module_extras = array(
2315          'acp'    => array(
2316              'ACP_QUICK_ACCESS' => array(
2317                  'ACP_MANAGE_USERS',
2318                  'ACP_GROUPS_MANAGE',
2319                  'ACP_MANAGE_FORUMS',
2320                  'ACP_MOD_LOGS',
2321                  'ACP_BOTS',
2322                  'ACP_PHP_INFO',
2323              ),
2324              'ACP_FORUM_BASED_PERMISSIONS' => array(
2325                  'ACP_FORUM_PERMISSIONS',
2326                  'ACP_FORUM_PERMISSIONS_COPY',
2327                  'ACP_FORUM_MODERATORS',
2328                  'ACP_USERS_FORUM_PERMISSIONS',
2329                  'ACP_GROUPS_FORUM_PERMISSIONS',
2330              ),
2331          ),
2332      );
2333  }
2334