[ Index ]

PHP Cross Reference of phpBB-3.1.12-deutsch

title

Body

[close]

/install/ -> install_install.php (source)

   1  <?php
   2  /**
   3  *
   4  * This file is part of the phpBB Forum Software package.
   5  *
   6  * @copyright (c) phpBB Limited <https://www.phpbb.com>
   7  * @license GNU General Public License, version 2 (GPL-2.0)
   8  *
   9  * For full copyright and license information, please see
  10  * the docs/CREDITS.txt file.
  11  *
  12  */
  13  
  14  /**
  15  */
  16  if (!defined('IN_INSTALL'))
  17  {
  18      // Someone has tried to access the file direct. This is not a good idea, so exit
  19      exit;
  20  }
  21  
  22  if (!empty($setmodules))
  23  {
  24      // If phpBB is already installed we do not include this module
  25      if (phpbb_check_installation_exists($phpbb_root_path, $phpEx) && !file_exists($phpbb_root_path . 'cache/install_lock'))
  26      {
  27          return;
  28      }
  29  
  30      $module[] = array(
  31          'module_type'        => 'install',
  32          'module_title'        => 'INSTALL',
  33          'module_filename'    => substr(basename(__FILE__), 0, -strlen($phpEx)-1),
  34          'module_order'        => 10,
  35          'module_subs'        => '',
  36          'module_stages'        => array('INTRO', 'REQUIREMENTS', 'DATABASE', 'ADMINISTRATOR', 'CONFIG_FILE', 'ADVANCED', 'CREATE_TABLE', 'FINAL'),
  37          'module_reqs'        => ''
  38      );
  39  }
  40  
  41  /**
  42  * Installation
  43  */
  44  class install_install extends module
  45  {
  46  	function install_install(&$p_master)
  47      {
  48          $this->p_master = &$p_master;
  49      }
  50  
  51  	function main($mode, $sub)
  52      {
  53          global $lang, $template, $language, $phpbb_root_path, $phpEx;
  54          global $phpbb_container, $cache, $phpbb_log, $request, $phpbb_config_php_file;
  55  
  56          switch ($sub)
  57          {
  58              case 'intro':
  59                  $phpbb_container->get('cache.driver')->purge();
  60  
  61                  $this->page_title = $lang['SUB_INTRO'];
  62  
  63                  $template->assign_vars(array(
  64                      'TITLE'            => $lang['INSTALL_INTRO'],
  65                      'BODY'            => $lang['INSTALL_INTRO_BODY'],
  66                      'L_SUBMIT'        => $lang['NEXT_STEP'],
  67                      'S_LANG_SELECT'    => '<select id="language" name="language">' . $this->p_master->inst_language_select($language) . '</select>',
  68                      'U_ACTION'        => $this->p_master->module_url . "?mode=$mode&amp;sub=requirements&amp;language=$language",
  69                  ));
  70  
  71              break;
  72  
  73              case 'requirements':
  74                  $this->check_server_requirements($mode, $sub);
  75  
  76              break;
  77  
  78              case 'database':
  79                  $this->obtain_database_settings($mode, $sub);
  80  
  81              break;
  82  
  83              case 'administrator':
  84                  $this->obtain_admin_settings($mode, $sub);
  85  
  86              break;
  87  
  88              case 'config_file':
  89                  $this->create_config_file($mode, $sub);
  90  
  91              break;
  92  
  93              case 'advanced':
  94                  $this->obtain_advanced_settings($mode, $sub);
  95  
  96              break;
  97  
  98              case 'create_table':
  99                  $this->load_schema($mode, $sub);
 100              break;
 101  
 102              case 'final':
 103                  // Enable super globals to prevent issues with the new \phpbb\request\request object
 104                  $request->enable_super_globals();
 105  
 106                  // Create a normal container now
 107                  $phpbb_container_builder = new \phpbb\di\container_builder($phpbb_config_php_file, $phpbb_root_path, $phpEx);
 108                  $phpbb_container = $phpbb_container_builder->get_container();
 109  
 110                  // Sets the global variables
 111                  $cache = $phpbb_container->get('cache');
 112                  $phpbb_log = $phpbb_container->get('log');
 113  
 114                  $this->build_search_index($mode, $sub);
 115                  $this->add_modules($mode, $sub);
 116                  $this->add_language($mode, $sub);
 117                  $this->add_bots($mode, $sub);
 118                  $this->email_admin($mode, $sub);
 119                  $this->disable_avatars_if_unwritable();
 120                  $this->populate_migrations($phpbb_container->get('ext.manager'), $phpbb_container->get('migrator'));
 121  
 122                  // Remove the lock file
 123                  @unlink($phpbb_root_path . 'cache/install_lock');
 124  
 125              break;
 126          }
 127  
 128          $this->tpl_name = 'install_install';
 129      }
 130  
 131      /**
 132      * Checks that the server we are installing on meets the requirements for running phpBB
 133      */
 134  	function check_server_requirements($mode, $sub)
 135      {
 136          global $lang, $template, $phpbb_root_path, $phpEx, $language;
 137  
 138          $this->page_title = $lang['STAGE_REQUIREMENTS'];
 139  
 140          $template->assign_vars(array(
 141              'TITLE'        => $lang['REQUIREMENTS_TITLE'],
 142              'BODY'        => $lang['REQUIREMENTS_EXPLAIN'],
 143          ));
 144  
 145          $passed = array('php' => false, 'db' => false, 'files' => false, 'pcre' => false, 'imagesize' => false, 'json' => false,);
 146  
 147          // Test for basic PHP settings
 148          $template->assign_block_vars('checks', array(
 149              'S_LEGEND'            => true,
 150              'LEGEND'            => $lang['PHP_SETTINGS'],
 151              'LEGEND_EXPLAIN'    => $lang['PHP_SETTINGS_EXPLAIN'],
 152          ));
 153  
 154          // Test the minimum and maximum version of PHP
 155          $php_version = PHP_VERSION;
 156  
 157          if ((version_compare($php_version, '5.3.3') < 0) || (version_compare($php_version, '7.0.0-dev', '>=')))
 158          {
 159              $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
 160          }
 161          else
 162          {
 163              $passed['php'] = true;
 164  
 165              // We also give feedback on whether we're running in safe mode
 166              $result = '<strong style="color:green">' . $lang['YES'];
 167              if (@ini_get('safe_mode') == '1' || strtolower(@ini_get('safe_mode')) == 'on')
 168              {
 169                  $result .= ', ' . $lang['PHP_SAFE_MODE'];
 170              }
 171              $result .= '</strong>';
 172          }
 173  
 174          $template->assign_block_vars('checks', array(
 175              'TITLE'            => $lang['PHP_VERSION_REQD'],
 176              'RESULT'        => $result,
 177  
 178              'S_EXPLAIN'        => false,
 179              'S_LEGEND'        => false,
 180          ));
 181  
 182          // Don't check for register_globals on 5.4+
 183          if (version_compare($php_version, '5.4.0-dev') < 0)
 184          {
 185              // Check for register_globals being enabled
 186              if (@ini_get('register_globals') == '1' || strtolower(@ini_get('register_globals')) == 'on')
 187              {
 188                  $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
 189              }
 190              else
 191              {
 192                  $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
 193              }
 194  
 195              $template->assign_block_vars('checks', array(
 196                  'TITLE'            => $lang['PHP_REGISTER_GLOBALS'],
 197                  'TITLE_EXPLAIN'    => $lang['PHP_REGISTER_GLOBALS_EXPLAIN'],
 198                  'RESULT'        => $result,
 199  
 200                  'S_EXPLAIN'        => true,
 201                  'S_LEGEND'        => false,
 202              ));
 203          }
 204  
 205          // Check for url_fopen
 206          if (@ini_get('allow_url_fopen') == '1' || strtolower(@ini_get('allow_url_fopen')) == 'on')
 207          {
 208              $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
 209          }
 210          else
 211          {
 212              $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
 213          }
 214  
 215          $template->assign_block_vars('checks', array(
 216              'TITLE'            => $lang['PHP_URL_FOPEN_SUPPORT'],
 217              'TITLE_EXPLAIN'    => $lang['PHP_URL_FOPEN_SUPPORT_EXPLAIN'],
 218              'RESULT'        => $result,
 219  
 220              'S_EXPLAIN'        => true,
 221              'S_LEGEND'        => false,
 222          ));
 223  
 224          // Check for getimagesize
 225          if (@function_exists('getimagesize'))
 226          {
 227              $passed['imagesize'] = true;
 228              $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
 229          }
 230          else
 231          {
 232              $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
 233          }
 234  
 235          $template->assign_block_vars('checks', array(
 236              'TITLE'            => $lang['PHP_GETIMAGESIZE_SUPPORT'],
 237              'TITLE_EXPLAIN'    => $lang['PHP_GETIMAGESIZE_SUPPORT_EXPLAIN'],
 238              'RESULT'        => $result,
 239  
 240              'S_EXPLAIN'        => true,
 241              'S_LEGEND'        => false,
 242          ));
 243  
 244          // Check for PCRE UTF-8 support
 245          if (@preg_match('//u', ''))
 246          {
 247              $passed['pcre'] = true;
 248              $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
 249          }
 250          else
 251          {
 252              $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
 253          }
 254  
 255          $template->assign_block_vars('checks', array(
 256              'TITLE'            => $lang['PCRE_UTF_SUPPORT'],
 257              'TITLE_EXPLAIN'    => $lang['PCRE_UTF_SUPPORT_EXPLAIN'],
 258              'RESULT'        => $result,
 259  
 260              'S_EXPLAIN'        => true,
 261              'S_LEGEND'        => false,
 262          ));
 263  
 264          // Check for php json support
 265          if (@extension_loaded('json'))
 266          {
 267              $passed['json'] = true;
 268              $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
 269          }
 270          else
 271          {
 272              $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
 273          }
 274  
 275          $template->assign_block_vars('checks', array(
 276              'TITLE'            => $lang['PHP_JSON_SUPPORT'],
 277              'TITLE_EXPLAIN'    => $lang['PHP_JSON_SUPPORT_EXPLAIN'],
 278              'RESULT'        => $result,
 279  
 280              'S_EXPLAIN'        => true,
 281              'S_LEGEND'        => false,
 282          ));
 283  
 284          $passed['mbstring'] = true;
 285          if (@extension_loaded('mbstring'))
 286          {
 287              // Test for available database modules
 288              $template->assign_block_vars('checks', array(
 289                  'S_LEGEND'            => true,
 290                  'LEGEND'            => $lang['MBSTRING_CHECK'],
 291                  'LEGEND_EXPLAIN'    => $lang['MBSTRING_CHECK_EXPLAIN'],
 292              ));
 293  
 294              $checks = array(
 295                  array('func_overload', '&', MB_OVERLOAD_MAIL|MB_OVERLOAD_STRING),
 296                  array('encoding_translation', '!=', 0),
 297                  array('http_input', '!=', array('pass', '')),
 298                  array('http_output', '!=', array('pass', ''))
 299              );
 300  
 301              foreach ($checks as $mb_checks)
 302              {
 303                  $ini_val = @ini_get('mbstring.' . $mb_checks[0]);
 304                  switch ($mb_checks[1])
 305                  {
 306                      case '&':
 307                          if (intval($ini_val) & $mb_checks[2])
 308                          {
 309                              $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
 310                              $passed['mbstring'] = false;
 311                          }
 312                          else
 313                          {
 314                              $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
 315                          }
 316                      break;
 317  
 318                      case '!=':
 319                          if (!is_array($mb_checks[2]) && $ini_val != $mb_checks[2] ||
 320                              is_array($mb_checks[2]) && !in_array($ini_val, $mb_checks[2]))
 321                          {
 322                              $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
 323                              $passed['mbstring'] = false;
 324                          }
 325                          else
 326                          {
 327                              $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
 328                          }
 329                      break;
 330                  }
 331                  $template->assign_block_vars('checks', array(
 332                      'TITLE'            => $lang['MBSTRING_' . strtoupper($mb_checks[0])],
 333                      'TITLE_EXPLAIN'    => $lang['MBSTRING_' . strtoupper($mb_checks[0]) . '_EXPLAIN'],
 334                      'RESULT'        => $result,
 335  
 336                      'S_EXPLAIN'        => true,
 337                      'S_LEGEND'        => false,
 338                  ));
 339              }
 340          }
 341  
 342          // Test for available database modules
 343          $template->assign_block_vars('checks', array(
 344              'S_LEGEND'            => true,
 345              'LEGEND'            => $lang['PHP_SUPPORTED_DB'],
 346              'LEGEND_EXPLAIN'    => $lang['PHP_SUPPORTED_DB_EXPLAIN'],
 347          ));
 348  
 349          $available_dbms = get_available_dbms(false, true);
 350          $passed['db'] = $available_dbms['ANY_DB_SUPPORT'];
 351          unset($available_dbms['ANY_DB_SUPPORT']);
 352  
 353          foreach ($available_dbms as $db_name => $db_ary)
 354          {
 355              if (!$db_ary['AVAILABLE'])
 356              {
 357                  $template->assign_block_vars('checks', array(
 358                      'TITLE'        => $lang['DLL_' . strtoupper($db_name)],
 359                      'RESULT'    => '<span style="color:red">' . $lang['UNAVAILABLE'] . '</span>',
 360  
 361                      'S_EXPLAIN'    => false,
 362                      'S_LEGEND'    => false,
 363                  ));
 364              }
 365              else
 366              {
 367                  $template->assign_block_vars('checks', array(
 368                      'TITLE'        => $lang['DLL_' . strtoupper($db_name)],
 369                      'RESULT'    => '<strong style="color:green">' . $lang['AVAILABLE'] . '</strong>',
 370  
 371                      'S_EXPLAIN'    => false,
 372                      'S_LEGEND'    => false,
 373                  ));
 374              }
 375          }
 376  
 377          // Test for other modules
 378          $template->assign_block_vars('checks', array(
 379              'S_LEGEND'            => true,
 380              'LEGEND'            => $lang['PHP_OPTIONAL_MODULE'],
 381              'LEGEND_EXPLAIN'    => $lang['PHP_OPTIONAL_MODULE_EXPLAIN'],
 382          ));
 383  
 384          foreach ($this->php_dlls_other as $dll)
 385          {
 386              if (!@extension_loaded($dll))
 387              {
 388                  $template->assign_block_vars('checks', array(
 389                      'TITLE'        => $lang['DLL_' . strtoupper($dll)],
 390                      'RESULT'    => '<strong style="color:red">' . $lang['UNAVAILABLE'] . '</strong>',
 391  
 392                      'S_EXPLAIN'    => false,
 393                      'S_LEGEND'    => false,
 394                  ));
 395                  continue;
 396              }
 397  
 398              $template->assign_block_vars('checks', array(
 399                  'TITLE'        => $lang['DLL_' . strtoupper($dll)],
 400                  'RESULT'    => '<strong style="color:green">' . $lang['AVAILABLE'] . '</strong>',
 401  
 402                  'S_EXPLAIN'    => false,
 403                  'S_LEGEND'    => false,
 404              ));
 405          }
 406  
 407          // Can we find ImageMagick anywhere on the system?
 408          $exe = (DIRECTORY_SEPARATOR == '\\') ? '.exe' : '';
 409  
 410          $magic_home = getenv('MAGICK_HOME');
 411          $img_imagick = '';
 412          if (empty($magic_home))
 413          {
 414              $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/');
 415              $path_locations = str_replace('\\', '/', (explode(($exe) ? ';' : ':', getenv('PATH'))));
 416  
 417              $locations = array_merge($path_locations, $locations);
 418              foreach ($locations as $location)
 419              {
 420                  // The path might not end properly, fudge it
 421                  if (substr($location, -1, 1) !== '/')
 422                  {
 423                      $location .= '/';
 424                  }
 425  
 426                  if (@file_exists($location) && @is_readable($location . 'mogrify' . $exe) && @filesize($location . 'mogrify' . $exe) > 3000)
 427                  {
 428                      $img_imagick = str_replace('\\', '/', $location);
 429                      continue;
 430                  }
 431              }
 432          }
 433          else
 434          {
 435              $img_imagick = str_replace('\\', '/', $magic_home);
 436          }
 437  
 438          $template->assign_block_vars('checks', array(
 439              'TITLE'        => $lang['APP_MAGICK'],
 440              'RESULT'    => ($img_imagick) ? '<strong style="color:green">' . $lang['AVAILABLE'] . ', ' . $img_imagick . '</strong>' : '<strong style="color:blue">' . $lang['NO_LOCATION'] . '</strong>',
 441  
 442              'S_EXPLAIN'    => false,
 443              'S_LEGEND'    => false,
 444          ));
 445  
 446          // Check permissions on files/directories we need access to
 447          $template->assign_block_vars('checks', array(
 448              'S_LEGEND'            => true,
 449              'LEGEND'            => $lang['FILES_REQUIRED'],
 450              'LEGEND_EXPLAIN'    => $lang['FILES_REQUIRED_EXPLAIN'],
 451          ));
 452  
 453          $directories = array('cache/', 'files/', 'store/');
 454  
 455          umask(0);
 456  
 457          $passed['files'] = true;
 458          foreach ($directories as $dir)
 459          {
 460              $exists = $write = false;
 461  
 462              // Try to create the directory if it does not exist
 463              if (!file_exists($phpbb_root_path . $dir))
 464              {
 465                  @mkdir($phpbb_root_path . $dir, 0777);
 466                  phpbb_chmod($phpbb_root_path . $dir, CHMOD_READ | CHMOD_WRITE);
 467              }
 468  
 469              // Now really check
 470              if (file_exists($phpbb_root_path . $dir) && is_dir($phpbb_root_path . $dir))
 471              {
 472                  phpbb_chmod($phpbb_root_path . $dir, CHMOD_READ | CHMOD_WRITE);
 473                  $exists = true;
 474              }
 475  
 476              // Now check if it is writable by storing a simple file
 477              $fp = @fopen($phpbb_root_path . $dir . 'test_lock', 'wb');
 478              if ($fp !== false)
 479              {
 480                  $write = true;
 481              }
 482              @fclose($fp);
 483  
 484              @unlink($phpbb_root_path . $dir . 'test_lock');
 485  
 486              $passed['files'] = ($exists && $write && $passed['files']) ? true : false;
 487  
 488              $exists = ($exists) ? '<strong style="color:green">' . $lang['FOUND'] . '</strong>' : '<strong style="color:red">' . $lang['NOT_FOUND'] . '</strong>';
 489              $write = ($write) ? ', <strong style="color:green">' . $lang['WRITABLE'] . '</strong>' : (($exists) ? ', <strong style="color:red">' . $lang['UNWRITABLE'] . '</strong>' : '');
 490  
 491              $template->assign_block_vars('checks', array(
 492                  'TITLE'        => $dir,
 493                  'RESULT'    => $exists . $write,
 494  
 495                  'S_EXPLAIN'    => false,
 496                  'S_LEGEND'    => false,
 497              ));
 498          }
 499  
 500          // Check permissions on files/directories it would be useful access to
 501          $template->assign_block_vars('checks', array(
 502              'S_LEGEND'            => true,
 503              'LEGEND'            => $lang['FILES_OPTIONAL'],
 504              'LEGEND_EXPLAIN'    => $lang['FILES_OPTIONAL_EXPLAIN'],
 505          ));
 506  
 507          $directories = array('config.' . $phpEx, 'images/avatars/upload/');
 508  
 509          foreach ($directories as $dir)
 510          {
 511              $write = $exists = true;
 512              if (file_exists($phpbb_root_path . $dir))
 513              {
 514                  if (!phpbb_is_writable($phpbb_root_path . $dir))
 515                  {
 516                      $write = false;
 517                  }
 518              }
 519              else
 520              {
 521                  $write = $exists = false;
 522              }
 523  
 524              $exists_str = ($exists) ? '<strong style="color:green">' . $lang['FOUND'] . '</strong>' : '<strong style="color:red">' . $lang['NOT_FOUND'] . '</strong>';
 525              $write_str = ($write) ? ', <strong style="color:green">' . $lang['WRITABLE'] . '</strong>' : (($exists) ? ', <strong style="color:red">' . $lang['UNWRITABLE'] . '</strong>' : '');
 526  
 527              $template->assign_block_vars('checks', array(
 528                  'TITLE'        => $dir,
 529                  'RESULT'    => $exists_str . $write_str,
 530  
 531                  'S_EXPLAIN'    => false,
 532                  'S_LEGEND'    => false,
 533              ));
 534          }
 535  
 536          // And finally where do we want to go next (well today is taken isn't it :P)
 537          $s_hidden_fields = ($img_imagick) ? '<input type="hidden" name="img_imagick" value="' . addslashes($img_imagick) . '" />' : '';
 538  
 539          $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    ";
 540          $submit = (!in_array(false, $passed)) ? $lang['INSTALL_START'] : $lang['INSTALL_TEST'];
 541  
 542          $template->assign_vars(array(
 543              'L_SUBMIT'    => $submit,
 544              'S_HIDDEN'    => $s_hidden_fields,
 545              'U_ACTION'    => $url,
 546          ));
 547      }
 548  
 549      /**
 550      * Obtain the information required to connect to the database
 551      */
 552  	function obtain_database_settings($mode, $sub)
 553      {
 554          global $lang, $template, $phpEx;
 555  
 556          $this->page_title = $lang['STAGE_DATABASE'];
 557  
 558          // Obtain any submitted data
 559          $data = $this->get_submitted_data();
 560  
 561          $connect_test = false;
 562          $error = array();
 563          $available_dbms = get_available_dbms(false, true);
 564  
 565          // Has the user opted to test the connection?
 566          if (isset($_POST['testdb']))
 567          {
 568              if (!isset($available_dbms[$data['dbms']]) || !$available_dbms[$data['dbms']]['AVAILABLE'])
 569              {
 570                  $error[] = $lang['INST_ERR_NO_DB'];
 571                  $connect_test = false;
 572              }
 573              else if (!preg_match(get_preg_expression('table_prefix'), $data['table_prefix']))
 574              {
 575                  $error[] = $lang['INST_ERR_DB_INVALID_PREFIX'];
 576                  $connect_test = false;
 577              }
 578              else
 579              {
 580                  $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']);
 581              }
 582  
 583              $template->assign_block_vars('checks', array(
 584                  'S_LEGEND'            => true,
 585                  'LEGEND'            => $lang['DB_CONNECTION'],
 586                  'LEGEND_EXPLAIN'    => false,
 587              ));
 588  
 589              if ($connect_test)
 590              {
 591                  $template->assign_block_vars('checks', array(
 592                      'TITLE'        => $lang['DB_TEST'],
 593                      'RESULT'    => '<strong style="color:green">' . $lang['SUCCESSFUL_CONNECT'] . '</strong>',
 594  
 595                      'S_EXPLAIN'    => false,
 596                      'S_LEGEND'    => false,
 597                  ));
 598              }
 599              else
 600              {
 601                  $template->assign_block_vars('checks', array(
 602                      'TITLE'        => $lang['DB_TEST'],
 603                      'RESULT'    => '<strong style="color:red">' . implode('<br />', $error) . '</strong>',
 604  
 605                      'S_EXPLAIN'    => false,
 606                      'S_LEGEND'    => false,
 607                  ));
 608              }
 609          }
 610  
 611          if (!$connect_test)
 612          {
 613              // Update the list of available DBMS modules to only contain those which can be used
 614              $available_dbms_temp = array();
 615              foreach ($available_dbms as $type => $dbms_ary)
 616              {
 617                  if (!$dbms_ary['AVAILABLE'])
 618                  {
 619                      continue;
 620                  }
 621  
 622                  $available_dbms_temp[$type] = $dbms_ary;
 623              }
 624  
 625              $available_dbms = &$available_dbms_temp;
 626  
 627              // And now for the main part of this page
 628              $data['table_prefix'] = (!empty($data['table_prefix']) ? $data['table_prefix'] : 'phpbb_');
 629  
 630              foreach ($this->db_config_options as $config_key => $vars)
 631              {
 632                  if (!is_array($vars) && strpos($config_key, 'legend') === false)
 633                  {
 634                      continue;
 635                  }
 636  
 637                  if (strpos($config_key, 'legend') !== false)
 638                  {
 639                      $template->assign_block_vars('options', array(
 640                          'S_LEGEND'        => true,
 641                          'LEGEND'        => $lang[$vars])
 642                      );
 643  
 644                      continue;
 645                  }
 646  
 647                  $options = isset($vars['options']) ? $vars['options'] : '';
 648  
 649                  $template->assign_block_vars('options', array(
 650                      'KEY'            => $config_key,
 651                      'TITLE'            => $lang[$vars['lang']],
 652                      'S_EXPLAIN'        => $vars['explain'],
 653                      'S_LEGEND'        => false,
 654                      'TITLE_EXPLAIN'    => ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '',
 655                      'CONTENT'        => $this->p_master->input_field($config_key, $vars['type'], $data[$config_key], $options),
 656                      )
 657                  );
 658              }
 659          }
 660  
 661          // And finally where do we want to go next (well today is taken isn't it :P)
 662          $s_hidden_fields = ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
 663          $s_hidden_fields .= '<input type="hidden" name="language" value="' . $data['language'] . '" />';
 664          if ($connect_test)
 665          {
 666              foreach ($this->db_config_options as $config_key => $vars)
 667              {
 668                  if (!is_array($vars))
 669                  {
 670                      continue;
 671                  }
 672                  $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
 673              }
 674          }
 675  
 676          $url = ($connect_test) ? $this->p_master->module_url . "?mode=$mode&amp;sub=administrator" : $this->p_master->module_url . "?mode=$mode&amp;sub=database";
 677          $s_hidden_fields .= ($connect_test) ? '' : '<input type="hidden" name="testdb" value="true" />';
 678  
 679          $submit = $lang['NEXT_STEP'];
 680  
 681          $template->assign_vars(array(
 682              'L_SUBMIT'    => $submit,
 683              'S_HIDDEN'    => $s_hidden_fields,
 684              'U_ACTION'    => $url,
 685          ));
 686      }
 687  
 688      /**
 689      * Obtain the administrator's name, password and email address
 690      */
 691  	function obtain_admin_settings($mode, $sub)
 692      {
 693          global $lang, $template, $phpEx;
 694  
 695          $this->page_title = $lang['STAGE_ADMINISTRATOR'];
 696  
 697          // Obtain any submitted data
 698          $data = $this->get_submitted_data();
 699  
 700          if ($data['dbms'] == '')
 701          {
 702              // Someone's been silly and tried calling this page direct
 703              // So we send them back to the start to do it again properly
 704              $this->p_master->redirect("index.$phpEx?mode=install");
 705          }
 706  
 707          $s_hidden_fields = ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
 708          $passed = false;
 709  
 710          $data['default_lang'] = ($data['default_lang'] !== '') ? $data['default_lang'] : $data['language'];
 711  
 712          if (isset($_POST['check']))
 713          {
 714              $error = array();
 715  
 716              // Check the entered email address and password
 717              if ($data['admin_name'] == '' || $data['admin_pass1'] == '' || $data['admin_pass2'] == '' || $data['board_email'] == '')
 718              {
 719                  $error[] = $lang['INST_ERR_MISSING_DATA'];
 720              }
 721  
 722              if ($data['admin_pass1'] != $data['admin_pass2'] && $data['admin_pass1'] != '')
 723              {
 724                  $error[] = $lang['INST_ERR_PASSWORD_MISMATCH'];
 725              }
 726  
 727              // Test against the default username rules
 728              if ($data['admin_name'] != '' && utf8_strlen($data['admin_name']) < 3)
 729              {
 730                  $error[] = $lang['INST_ERR_USER_TOO_SHORT'];
 731              }
 732  
 733              if ($data['admin_name'] != '' && utf8_strlen($data['admin_name']) > 20)
 734              {
 735                  $error[] = $lang['INST_ERR_USER_TOO_LONG'];
 736              }
 737  
 738              // Test against the default password rules
 739              if ($data['admin_pass1'] != '' && utf8_strlen($data['admin_pass1']) < 6)
 740              {
 741                  $error[] = $lang['INST_ERR_PASSWORD_TOO_SHORT'];
 742              }
 743  
 744              if ($data['admin_pass1'] != '' && utf8_strlen($data['admin_pass1']) > 30)
 745              {
 746                  $error[] = $lang['INST_ERR_PASSWORD_TOO_LONG'];
 747              }
 748  
 749              if ($data['board_email'] != '' && !preg_match('/^' . get_preg_expression('email') . '$/i', $data['board_email']))
 750              {
 751                  $error[] = $lang['INST_ERR_EMAIL_INVALID'];
 752              }
 753  
 754              $template->assign_block_vars('checks', array(
 755                  'S_LEGEND'            => true,
 756                  'LEGEND'            => $lang['STAGE_ADMINISTRATOR'],
 757                  'LEGEND_EXPLAIN'    => false,
 758              ));
 759  
 760              if (!sizeof($error))
 761              {
 762                  $passed = true;
 763                  $template->assign_block_vars('checks', array(
 764                      'TITLE'        => $lang['ADMIN_TEST'],
 765                      'RESULT'    => '<strong style="color:green">' . $lang['TESTS_PASSED'] . '</strong>',
 766  
 767                      'S_EXPLAIN'    => false,
 768                      'S_LEGEND'    => false,
 769                  ));
 770              }
 771              else
 772              {
 773                  $template->assign_block_vars('checks', array(
 774                      'TITLE'        => $lang['ADMIN_TEST'],
 775                      'RESULT'    => '<strong style="color:red">' . implode('<br />', $error) . '</strong>',
 776  
 777                      'S_EXPLAIN'    => false,
 778                      'S_LEGEND'    => false,
 779                  ));
 780              }
 781          }
 782  
 783          if (!$passed)
 784          {
 785              foreach ($this->admin_config_options as $config_key => $vars)
 786              {
 787                  if (!is_array($vars) && strpos($config_key, 'legend') === false)
 788                  {
 789                      continue;
 790                  }
 791  
 792                  if (strpos($config_key, 'legend') !== false)
 793                  {
 794                      $template->assign_block_vars('options', array(
 795                          'S_LEGEND'        => true,
 796                          'LEGEND'        => $lang[$vars])
 797                      );
 798  
 799                      continue;
 800                  }
 801  
 802                  $options = isset($vars['options']) ? $vars['options'] : '';
 803  
 804                  $template->assign_block_vars('options', array(
 805                      'KEY'            => $config_key,
 806                      'TITLE'            => $lang[$vars['lang']],
 807                      'S_EXPLAIN'        => $vars['explain'],
 808                      'S_LEGEND'        => false,
 809                      'TITLE_EXPLAIN'    => ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '',
 810                      'CONTENT'        => $this->p_master->input_field($config_key, $vars['type'], $data[$config_key], $options),
 811                      )
 812                  );
 813              }
 814          }
 815          else
 816          {
 817              foreach ($this->admin_config_options as $config_key => $vars)
 818              {
 819                  if (!is_array($vars))
 820                  {
 821                      continue;
 822                  }
 823                  $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
 824              }
 825          }
 826  
 827          $s_hidden_fields .= ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
 828          $s_hidden_fields .= '<input type="hidden" name="language" value="' . $data['language'] . '" />';
 829  
 830          foreach ($this->db_config_options as $config_key => $vars)
 831          {
 832              if (!is_array($vars))
 833              {
 834                  continue;
 835              }
 836              $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
 837          }
 838  
 839          $submit = $lang['NEXT_STEP'];
 840  
 841          $url = ($passed) ? $this->p_master->module_url . "?mode=$mode&amp;sub=config_file" : $this->p_master->module_url . "?mode=$mode&amp;sub=administrator";
 842          $s_hidden_fields .= ($passed) ? '' : '<input type="hidden" name="check" value="true" />';
 843  
 844          $template->assign_vars(array(
 845              'L_SUBMIT'    => $submit,
 846              'S_HIDDEN'    => $s_hidden_fields,
 847              'U_ACTION'    => $url,
 848          ));
 849      }
 850  
 851      /**
 852      * Writes the config file to disk, or if unable to do so offers alternative methods
 853      */
 854  	function create_config_file($mode, $sub)
 855      {
 856          global $lang, $template, $phpbb_root_path, $phpEx;
 857  
 858          $this->page_title = $lang['STAGE_CONFIG_FILE'];
 859  
 860          // Obtain any submitted data
 861          $data = $this->get_submitted_data();
 862  
 863          if ($data['dbms'] == '')
 864          {
 865              // Someone's been silly and tried calling this page direct
 866              // So we send them back to the start to do it again properly
 867              $this->p_master->redirect("index.$phpEx?mode=install");
 868          }
 869  
 870          $s_hidden_fields = ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
 871          $s_hidden_fields .= '<input type="hidden" name="language" value="' . $data['language'] . '" />';
 872          $written = false;
 873  
 874          // Create a list of any PHP modules we wish to have loaded
 875          $available_dbms = get_available_dbms($data['dbms']);
 876  
 877          // Create a lock file to indicate that there is an install in progress
 878          $fp = @fopen($phpbb_root_path . 'cache/install_lock', 'wb');
 879          if ($fp === false)
 880          {
 881              // We were unable to create the lock file - abort
 882              $this->p_master->error($lang['UNABLE_WRITE_LOCK'], __LINE__, __FILE__);
 883          }
 884          @fclose($fp);
 885  
 886          @chmod($phpbb_root_path . 'cache/install_lock', 0777);
 887  
 888          // Time to convert the data provided into a config file
 889          $config_data = phpbb_create_config_file_data($data, $available_dbms[$data['dbms']]['DRIVER']);
 890  
 891          // Attempt to write out the config file directly. If it works, this is the easiest way to do it ...
 892          if ((file_exists($phpbb_root_path . 'config.' . $phpEx) && phpbb_is_writable($phpbb_root_path . 'config.' . $phpEx)) || phpbb_is_writable($phpbb_root_path))
 893          {
 894              // Assume it will work ... if nothing goes wrong below
 895              $written = true;
 896  
 897              if (!($fp = @fopen($phpbb_root_path . 'config.' . $phpEx, 'w')))
 898              {
 899                  // Something went wrong ... so let's try another method
 900                  $written = false;
 901              }
 902  
 903              if (!(@fwrite($fp, $config_data)))
 904              {
 905                  // Something went wrong ... so let's try another method
 906                  $written = false;
 907              }
 908  
 909              @fclose($fp);
 910  
 911              if ($written)
 912              {
 913                  // We may revert back to chmod() if we see problems with users not able to change their config.php file directly
 914                  phpbb_chmod($phpbb_root_path . 'config.' . $phpEx, CHMOD_READ);
 915              }
 916          }
 917  
 918          if (isset($_POST['dldone']))
 919          {
 920              // Do a basic check to make sure that the file has been uploaded
 921              // Note that all we check is that the file has _something_ in it
 922              // We don't compare the contents exactly - if they can't upload
 923              // a single file correctly, it's likely they will have other problems....
 924              if (filesize($phpbb_root_path . 'config.' . $phpEx) > 10)
 925              {
 926                  $written = true;
 927              }
 928          }
 929  
 930          $config_options = array_merge($this->db_config_options, $this->admin_config_options);
 931  
 932          foreach ($config_options as $config_key => $vars)
 933          {
 934              if (!is_array($vars))
 935              {
 936                  continue;
 937              }
 938              $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
 939          }
 940  
 941          if (!$written)
 942          {
 943              // OK, so it didn't work let's try the alternatives
 944  
 945              if (isset($_POST['dlconfig']))
 946              {
 947                  // They want a copy of the file to download, so send the relevant headers and dump out the data
 948                  header("Content-Type: text/x-delimtext; name=\"config.$phpEx\"");
 949                  header("Content-disposition: attachment; filename=config.$phpEx");
 950                  echo $config_data;
 951                  exit;
 952              }
 953  
 954              // The option to download the config file is always available, so output it here
 955              $template->assign_vars(array(
 956                  'BODY'                    => $lang['CONFIG_FILE_UNABLE_WRITE'],
 957                  'L_DL_CONFIG'            => $lang['DL_CONFIG'],
 958                  'L_DL_CONFIG_EXPLAIN'    => $lang['DL_CONFIG_EXPLAIN'],
 959                  'L_DL_DONE'                => $lang['DONE'],
 960                  'L_DL_DOWNLOAD'            => $lang['DL_DOWNLOAD'],
 961                  'S_HIDDEN'                => $s_hidden_fields,
 962                  'S_SHOW_DOWNLOAD'        => true,
 963                  'U_ACTION'                => $this->p_master->module_url . "?mode=$mode&amp;sub=config_file",
 964              ));
 965              return;
 966          }
 967          else
 968          {
 969              $template->assign_vars(array(
 970                  'BODY'        => $lang['CONFIG_FILE_WRITTEN'],
 971                  'L_SUBMIT'    => $lang['NEXT_STEP'],
 972                  'S_HIDDEN'    => $s_hidden_fields,
 973                  'U_ACTION'    => $this->p_master->module_url . "?mode=$mode&amp;sub=advanced",
 974              ));
 975              return;
 976          }
 977      }
 978  
 979      /**
 980      * Provide an opportunity to customise some advanced settings during the install
 981      * in case it is necessary for them to be set to access later
 982      */
 983  	function obtain_advanced_settings($mode, $sub)
 984      {
 985          global $lang, $template, $phpEx, $request;
 986  
 987          $this->page_title = $lang['STAGE_ADVANCED'];
 988  
 989          // Obtain any submitted data
 990          $data = $this->get_submitted_data();
 991  
 992          if ($data['dbms'] == '')
 993          {
 994              // Someone's been silly and tried calling this page direct
 995              // So we send them back to the start to do it again properly
 996              $this->p_master->redirect("index.$phpEx?mode=install");
 997          }
 998  
 999          $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                  // Ignore errors when the functions or types already exist
1168                  // to allow installing phpBB twice in the same database with
1169                  // a different prefix
1170                  $db->sql_query($sql);
1171              }
1172              unset($sql_query);
1173          }
1174  
1175          // Ok we have the db info go ahead and work on building the table
1176          if (file_exists('schemas/schema.json'))
1177          {
1178              $db_table_schema = @file_get_contents('schemas/schema.json');
1179              $db_table_schema = json_decode($db_table_schema, true);
1180          }
1181          else
1182          {
1183              global $phpbb_root_path, $phpEx, $table_prefix;
1184              $table_prefix = 'phpbb_';
1185  
1186              if (!defined('CONFIG_TABLE'))
1187              {
1188                  // We need to include the constants file for the table constants
1189                  // when we generate the schema from the migration files.
1190                  include($phpbb_root_path . 'includes/constants.' . $phpEx);
1191              }
1192  
1193              $finder = new \phpbb\finder(new \phpbb\filesystem(), $phpbb_root_path, null, $phpEx);
1194              $classes = $finder->core_path('phpbb/db/migration/data/')
1195                  ->get_classes();
1196  
1197              $sqlite_db = new \phpbb\db\driver\sqlite();
1198              $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);
1199              $db_table_schema = $schema_generator->get_schema();
1200          }
1201  
1202          if (!defined('CONFIG_TABLE'))
1203          {
1204              // CONFIG_TABLE is required by sql_create_index() to check the
1205              // length of index names. However table_prefix is not defined
1206              // here yet, so we need to create the constant ourselves.
1207              define('CONFIG_TABLE', $data['table_prefix'] . 'config');
1208          }
1209  
1210          $db_tools = new \phpbb\db\tools($db);
1211          foreach ($db_table_schema as $table_name => $table_data)
1212          {
1213              $db_tools->sql_create_table(
1214                  $data['table_prefix'] . substr($table_name, 6),
1215                  $table_data
1216              );
1217          }
1218  
1219          // Ok tables have been built, let's fill in the basic information
1220          $sql_query = file_get_contents('schemas/schema_data.sql');
1221  
1222          // Deal with any special comments and characters
1223          switch ($data['dbms'])
1224          {
1225              case 'mssql':
1226              case 'mssql_odbc':
1227              case 'mssqlnative':
1228                  $sql_query = preg_replace('#\# MSSQL IDENTITY (phpbb_[a-z_]+) (ON|OFF) \##s', 'SET IDENTITY_INSERT \1 \2;', $sql_query);
1229              break;
1230  
1231              case 'postgres':
1232                  $sql_query = preg_replace('#\# POSTGRES (BEGIN|COMMIT) \##s', '\1; ', $sql_query);
1233              break;
1234  
1235              case 'mysql':
1236              case 'mysqli':
1237                  $sql_query = str_replace('\\', '\\\\', $sql_query);
1238              break;
1239          }
1240  
1241          // Change prefix
1242          $sql_query = preg_replace('# phpbb_([^\s]*) #i', ' ' . $data['table_prefix'] . '\1 ', $sql_query);
1243  
1244          // Change language strings...
1245          $sql_query = preg_replace_callback('#\{L_([A-Z0-9\-_]*)\}#s', 'adjust_language_keys_callback', $sql_query);
1246  
1247          $sql_query = phpbb_remove_comments($sql_query);
1248          $sql_query = split_sql_file($sql_query, ';');
1249  
1250          foreach ($sql_query as $sql)
1251          {
1252              //$sql = trim(str_replace('|', ';', $sql));
1253              if (!$db->sql_query($sql))
1254              {
1255                  $error = $db->sql_error();
1256                  $this->p_master->db_error($error['message'], $sql, __LINE__, __FILE__);
1257              }
1258          }
1259          unset($sql_query);
1260  
1261          $current_time = time();
1262  
1263          $user_ip = $request->server('REMOTE_ADDR') ? phpbb_ip_normalise($request->server('REMOTE_ADDR')) : '';
1264  
1265          if ($data['script_path'] !== '/')
1266          {
1267              // Adjust destination path (no trailing slash)
1268              if (substr($data['script_path'], -1) == '/')
1269              {
1270                  $data['script_path'] = substr($data['script_path'], 0, -1);
1271              }
1272  
1273              $data['script_path'] = str_replace(array('../', './'), '', $data['script_path']);
1274  
1275              if ($data['script_path'][0] != '/')
1276              {
1277                  $data['script_path'] = '/' . $data['script_path'];
1278              }
1279          }
1280  
1281          // Set default config and post data, this applies to all DB's
1282          $sql_ary = array(
1283              'INSERT INTO ' . $data['table_prefix'] . "config (config_name, config_value)
1284                  VALUES ('board_startdate', '$current_time')",
1285  
1286              'INSERT INTO ' . $data['table_prefix'] . "config (config_name, config_value)
1287                  VALUES ('default_lang', '" . $db->sql_escape($data['default_lang']) . "')",
1288  
1289              'UPDATE ' . $data['table_prefix'] . "config
1290                  SET config_value = '" . $db->sql_escape($data['img_imagick']) . "'
1291                  WHERE config_name = 'img_imagick'",
1292  
1293              'UPDATE ' . $data['table_prefix'] . "config
1294                  SET config_value = '" . $db->sql_escape($data['server_name']) . "'
1295                  WHERE config_name = 'server_name'",
1296  
1297              'UPDATE ' . $data['table_prefix'] . "config
1298                  SET config_value = '" . $db->sql_escape($data['server_port']) . "'
1299                  WHERE config_name = 'server_port'",
1300  
1301              'UPDATE ' . $data['table_prefix'] . "config
1302                  SET config_value = '" . $db->sql_escape($data['board_email']) . "'
1303                  WHERE config_name = 'board_email'",
1304  
1305              'UPDATE ' . $data['table_prefix'] . "config
1306                  SET config_value = '" . $db->sql_escape($data['board_email']) . "'
1307                  WHERE config_name = 'board_contact'",
1308  
1309              'UPDATE ' . $data['table_prefix'] . "config
1310                  SET config_value = '" . $db->sql_escape($cookie_domain) . "'
1311                  WHERE config_name = 'cookie_domain'",
1312  
1313              'UPDATE ' . $data['table_prefix'] . "config
1314                  SET config_value = '" . $db->sql_escape($lang['default_dateformat']) . "'
1315                  WHERE config_name = 'default_dateformat'",
1316  
1317              'UPDATE ' . $data['table_prefix'] . "config
1318                  SET config_value = '" . $db->sql_escape($data['email_enable']) . "'
1319                  WHERE config_name = 'email_enable'",
1320  
1321              'UPDATE ' . $data['table_prefix'] . "config
1322                  SET config_value = '" . $db->sql_escape($data['smtp_delivery']) . "'
1323                  WHERE config_name = 'smtp_delivery'",
1324  
1325              'UPDATE ' . $data['table_prefix'] . "config
1326                  SET config_value = '" . $db->sql_escape($data['smtp_host']) . "'
1327                  WHERE config_name = 'smtp_host'",
1328  
1329              'UPDATE ' . $data['table_prefix'] . "config
1330                  SET config_value = '" . $db->sql_escape($data['smtp_auth']) . "'
1331                  WHERE config_name = 'smtp_auth_method'",
1332  
1333              'UPDATE ' . $data['table_prefix'] . "config
1334                  SET config_value = '" . $db->sql_escape($data['smtp_user']) . "'
1335                  WHERE config_name = 'smtp_username'",
1336  
1337              'UPDATE ' . $data['table_prefix'] . "config
1338                  SET config_value = '" . $db->sql_escape($data['smtp_pass']) . "'
1339                  WHERE config_name = 'smtp_password'",
1340  
1341              'UPDATE ' . $data['table_prefix'] . "config
1342                  SET config_value = '" . $db->sql_escape($data['cookie_secure']) . "'
1343                  WHERE config_name = 'cookie_secure'",
1344  
1345              'UPDATE ' . $data['table_prefix'] . "config
1346                  SET config_value = '" . $db->sql_escape($data['force_server_vars']) . "'
1347                  WHERE config_name = 'force_server_vars'",
1348  
1349              'UPDATE ' . $data['table_prefix'] . "config
1350                  SET config_value = '" . $db->sql_escape($data['script_path']) . "'
1351                  WHERE config_name = 'script_path'",
1352  
1353              'UPDATE ' . $data['table_prefix'] . "config
1354                  SET config_value = '" . $db->sql_escape($data['server_protocol']) . "'
1355                  WHERE config_name = 'server_protocol'",
1356  
1357              'UPDATE ' . $data['table_prefix'] . "config
1358                  SET config_value = '" . $db->sql_escape($data['admin_name']) . "'
1359                  WHERE config_name = 'newest_username'",
1360  
1361              'UPDATE ' . $data['table_prefix'] . "config
1362                  SET config_value = '" . md5(mt_rand()) . "'
1363                  WHERE config_name = 'avatar_salt'",
1364  
1365              'UPDATE ' . $data['table_prefix'] . "config
1366                  SET config_value = '" . md5(mt_rand()) . "'
1367                  WHERE config_name = 'plupload_salt'",
1368  
1369              'UPDATE ' . $data['table_prefix'] . "users
1370                  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'])) . "'
1371                  WHERE username = 'Admin'",
1372  
1373              'UPDATE ' . $data['table_prefix'] . "moderator_cache
1374                  SET username = '" . $db->sql_escape($data['admin_name']) . "'
1375                  WHERE username = 'Admin'",
1376  
1377              'UPDATE ' . $data['table_prefix'] . "forums
1378                  SET forum_last_poster_name = '" . $db->sql_escape($data['admin_name']) . "'
1379                  WHERE forum_last_poster_name = 'Admin'",
1380  
1381              'UPDATE ' . $data['table_prefix'] . "topics
1382                  SET topic_first_poster_name = '" . $db->sql_escape($data['admin_name']) . "', topic_last_poster_name = '" . $db->sql_escape($data['admin_name']) . "'
1383                  WHERE topic_first_poster_name = 'Admin'
1384                      OR topic_last_poster_name = 'Admin'",
1385  
1386              'UPDATE ' . $data['table_prefix'] . "users
1387                  SET user_regdate = $current_time",
1388  
1389              'UPDATE ' . $data['table_prefix'] . "posts
1390                  SET post_time = $current_time, poster_ip = '" . $db->sql_escape($user_ip) . "'",
1391  
1392              'UPDATE ' . $data['table_prefix'] . "topics
1393                  SET topic_time = $current_time, topic_last_post_time = $current_time",
1394  
1395              'UPDATE ' . $data['table_prefix'] . "forums
1396                  SET forum_last_post_time = $current_time",
1397  
1398              'UPDATE ' . $data['table_prefix'] . "config
1399                  SET config_value = '" . $db->sql_escape($db->sql_server_info(true)) . "'
1400                  WHERE config_name = 'dbms_version'",
1401          );
1402  
1403          if (@extension_loaded('gd'))
1404          {
1405              $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
1406                  SET config_value = 'core.captcha.plugins.gd'
1407                  WHERE config_name = 'captcha_plugin'";
1408  
1409              $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
1410                  SET config_value = '1'
1411                  WHERE config_name = 'captcha_gd'";
1412          }
1413  
1414          $ref = substr($referer, strpos($referer, '://') + 3);
1415  
1416          if (!(stripos($ref, $server_name) === 0))
1417          {
1418              $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
1419                  SET config_value = '0'
1420                  WHERE config_name = 'referer_validation'";
1421          }
1422  
1423          // We set a (semi-)unique cookie name to bypass login issues related to the cookie name.
1424          $cookie_name = 'phpbb3_';
1425          $rand_str = md5(mt_rand());
1426          $rand_str = str_replace('0', 'z', base_convert($rand_str, 16, 35));
1427          $rand_str = substr($rand_str, 0, 5);
1428          $cookie_name .= strtolower($rand_str);
1429  
1430          $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
1431              SET config_value = '" . $db->sql_escape($cookie_name) . "'
1432              WHERE config_name = 'cookie_name'";
1433  
1434          foreach ($sql_ary as $sql)
1435          {
1436              //$sql = trim(str_replace('|', ';', $sql));
1437  
1438              if (!$db->sql_query($sql))
1439              {
1440                  $error = $db->sql_error();
1441                  $this->p_master->db_error($error['message'], $sql, __LINE__, __FILE__);
1442              }
1443          }
1444  
1445          $submit = $lang['NEXT_STEP'];
1446  
1447          $url = $this->p_master->module_url . "?mode=$mode&amp;sub=final";
1448  
1449          $template->assign_vars(array(
1450              'BODY'        => $lang['STAGE_CREATE_TABLE_EXPLAIN'],
1451              'L_SUBMIT'    => $submit,
1452              'S_HIDDEN'    => build_hidden_fields($data),
1453              'U_ACTION'    => $url,
1454          ));
1455      }
1456  
1457      /**
1458      * Build the search index...
1459      */
1460  	function build_search_index($mode, $sub)
1461      {
1462          global $db, $lang, $phpbb_root_path, $phpbb_dispatcher, $phpEx, $config, $auth, $user;
1463  
1464          // Obtain any submitted data
1465          $data = $this->get_submitted_data();
1466          $table_prefix = $data['table_prefix'];
1467  
1468          // If we get here and the extension isn't loaded it should be safe to just go ahead and load it
1469          $available_dbms = get_available_dbms($data['dbms']);
1470  
1471          if (!isset($available_dbms[$data['dbms']]))
1472          {
1473              // Someone's been silly and tried providing a non-existant dbms
1474              $this->p_master->redirect("index.$phpEx?mode=install");
1475          }
1476  
1477          $dbms = $available_dbms[$data['dbms']]['DRIVER'];
1478  
1479          // Instantiate the database
1480          $db = new $dbms();
1481          $db->sql_connect($data['dbhost'], $data['dbuser'], htmlspecialchars_decode($data['dbpasswd']), $data['dbname'], $data['dbport'], false, false);
1482  
1483          // NOTE: trigger_error does not work here.
1484          $db->sql_return_on_error(true);
1485  
1486          include_once($phpbb_root_path . 'includes/constants.' . $phpEx);
1487          include_once($phpbb_root_path . 'phpbb/search/fulltext_native.' . $phpEx);
1488  
1489          // We need to fill the config to let internal functions correctly work
1490          $config = new \phpbb\config\db($db, new \phpbb\cache\driver\null, CONFIG_TABLE);
1491          set_config(null, null, null, $config);
1492          set_config_count(null, null, null, $config);
1493  
1494          $error = false;
1495          $search = new \phpbb\search\fulltext_native($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
1496  
1497          $sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id
1498              FROM ' . POSTS_TABLE;
1499          $result = $db->sql_query($sql);
1500  
1501          while ($row = $db->sql_fetchrow($result))
1502          {
1503              $search->index('post', $row['post_id'], $row['post_text'], $row['post_subject'], $row['poster_id'], $row['forum_id']);
1504          }
1505          $db->sql_freeresult($result);
1506      }
1507  
1508      /**
1509      * Populate the module tables
1510      */
1511  	function add_modules($mode, $sub)
1512      {
1513          global $db, $lang, $phpbb_root_path, $phpEx, $phpbb_extension_manager, $config, $phpbb_container;
1514  
1515          // modules require an extension manager
1516          if (empty($phpbb_extension_manager))
1517          {
1518              $phpbb_extension_manager = $phpbb_container->get('ext.manager');
1519          }
1520  
1521          include_once($phpbb_root_path . 'includes/acp/acp_modules.' . $phpEx);
1522  
1523          $_module = new acp_modules();
1524          $module_classes = array('acp', 'mcp', 'ucp');
1525  
1526          // Add categories
1527          foreach ($module_classes as $module_class)
1528          {
1529              $categories = array();
1530  
1531              // Set the module class
1532              $_module->module_class = $module_class;
1533  
1534              foreach ($this->module_categories[$module_class] as $cat_name => $subs)
1535              {
1536                  $basename = '';
1537                  // Check if this sub-category has a basename. If it has, use it.
1538                  if (isset($this->module_categories_basenames[$cat_name]))
1539                  {
1540                      $basename = $this->module_categories_basenames[$cat_name];
1541                  }
1542                  $module_data = array(
1543                      'module_basename'    => $basename,
1544                      'module_enabled'    => 1,
1545                      'module_display'    => 1,
1546                      'parent_id'            => 0,
1547                      'module_class'        => $module_class,
1548                      'module_langname'    => $cat_name,
1549                      'module_mode'        => '',
1550                      'module_auth'        => '',
1551                  );
1552  
1553                  // Add category
1554                  $_module->update_module_data($module_data, true);
1555  
1556                  // Check for last sql error happened
1557                  if ($db->get_sql_error_triggered())
1558                  {
1559                      $error = $db->sql_error($db->get_sql_error_sql());
1560                      $this->p_master->db_error($error['message'], $db->get_sql_error_sql(), __LINE__, __FILE__);
1561                  }
1562  
1563                  $categories[$cat_name]['id'] = (int) $module_data['module_id'];
1564                  $categories[$cat_name]['parent_id'] = 0;
1565  
1566                  // Create sub-categories...
1567                  if (is_array($subs))
1568                  {
1569                      foreach ($subs as $level2_name)
1570                      {
1571                          $basename = '';
1572                          // Check if this sub-category has a basename. If it has, use it.
1573                          if (isset($this->module_categories_basenames[$level2_name]))
1574                          {
1575                              $basename = $this->module_categories_basenames[$level2_name];
1576                          }
1577                          $module_data = array(
1578                              'module_basename'    => $basename,
1579                              'module_enabled'    => 1,
1580                              'module_display'    => 1,
1581                              'parent_id'            => (int) $categories[$cat_name]['id'],
1582                              'module_class'        => $module_class,
1583                              'module_langname'    => $level2_name,
1584                              'module_mode'        => '',
1585                              'module_auth'        => '',
1586                          );
1587  
1588                          $_module->update_module_data($module_data, true);
1589  
1590                          // Check for last sql error happened
1591                          if ($db->get_sql_error_triggered())
1592                          {
1593                              $error = $db->sql_error($db->get_sql_error_sql());
1594                              $this->p_master->db_error($error['message'], $db->get_sql_error_sql(), __LINE__, __FILE__);
1595                          }
1596  
1597                          $categories[$level2_name]['id'] = (int) $module_data['module_id'];
1598                          $categories[$level2_name]['parent_id'] = (int) $categories[$cat_name]['id'];
1599                      }
1600                  }
1601              }
1602  
1603              // Get the modules we want to add... returned sorted by name
1604              $module_info = $_module->get_module_infos('', $module_class);
1605  
1606              foreach ($module_info as $module_basename => $fileinfo)
1607              {
1608                  foreach ($fileinfo['modes'] as $module_mode => $row)
1609                  {
1610                      foreach ($row['cat'] as $cat_name)
1611                      {
1612                          if (!isset($categories[$cat_name]))
1613                          {
1614                              continue;
1615                          }
1616  
1617                          $module_data = array(
1618                              'module_basename'    => $module_basename,
1619                              'module_enabled'    => 1,
1620                              'module_display'    => (isset($row['display'])) ? (int) $row['display'] : 1,
1621                              'parent_id'            => (int) $categories[$cat_name]['id'],
1622                              'module_class'        => $module_class,
1623                              'module_langname'    => $row['title'],
1624                              'module_mode'        => $module_mode,
1625                              'module_auth'        => $row['auth'],
1626                          );
1627  
1628                          $_module->update_module_data($module_data, true);
1629  
1630                          // Check for last sql error happened
1631                          if ($db->get_sql_error_triggered())
1632                          {
1633                              $error = $db->sql_error($db->get_sql_error_sql());
1634                              $this->p_master->db_error($error['message'], $db->get_sql_error_sql(), __LINE__, __FILE__);
1635                          }
1636                      }
1637                  }
1638              }
1639  
1640              // Move some of the modules around since the code above will put them in the wrong place
1641              if ($module_class == 'acp')
1642              {
1643                  // Move main module 4 up...
1644                  $sql = 'SELECT *
1645                      FROM ' . MODULES_TABLE . "
1646                      WHERE module_basename = 'acp_main'
1647                          AND module_class = 'acp'
1648                          AND module_mode = 'main'";
1649                  $result = $db->sql_query($sql);
1650                  $row = $db->sql_fetchrow($result);
1651                  $db->sql_freeresult($result);
1652  
1653                  $_module->move_module_by($row, 'move_up', 4);
1654  
1655                  // Move permissions intro screen module 4 up...
1656                  $sql = 'SELECT *
1657                      FROM ' . MODULES_TABLE . "
1658                      WHERE module_basename = 'acp_permissions'
1659                          AND module_class = 'acp'
1660                          AND module_mode = 'intro'";
1661                  $result = $db->sql_query($sql);
1662                  $row = $db->sql_fetchrow($result);
1663                  $db->sql_freeresult($result);
1664  
1665                  $_module->move_module_by($row, 'move_up', 4);
1666  
1667                  // Move manage users screen module 5 up...
1668                  $sql = 'SELECT *
1669                      FROM ' . MODULES_TABLE . "
1670                      WHERE module_basename = 'acp_users'
1671                          AND module_class = 'acp'
1672                          AND module_mode = 'overview'";
1673                  $result = $db->sql_query($sql);
1674                  $row = $db->sql_fetchrow($result);
1675                  $db->sql_freeresult($result);
1676  
1677                  $_module->move_module_by($row, 'move_up', 5);
1678  
1679                  // Move extension management module 1 up...
1680                  $sql = 'SELECT *
1681                      FROM ' . MODULES_TABLE . "
1682                      WHERE module_langname = 'ACP_EXTENSION_MANAGEMENT'
1683                          AND module_class = 'acp'
1684                          AND module_mode = ''
1685                          AND module_basename = ''";
1686                  $result = $db->sql_query($sql);
1687                  $row = $db->sql_fetchrow($result);
1688                  $db->sql_freeresult($result);
1689  
1690                  $_module->move_module_by($row, 'move_up', 1);
1691              }
1692  
1693              if ($module_class == 'mcp')
1694              {
1695                  // Move pm report details module 3 down...
1696                  $sql = 'SELECT *
1697                      FROM ' . MODULES_TABLE . "
1698                      WHERE module_basename = 'mcp_pm_reports'
1699                          AND module_class = 'mcp'
1700                          AND module_mode = 'pm_report_details'";
1701                  $result = $db->sql_query($sql);
1702                  $row = $db->sql_fetchrow($result);
1703                  $db->sql_freeresult($result);
1704  
1705                  $_module->move_module_by($row, 'move_down', 3);
1706  
1707                  // Move closed pm reports module 3 down...
1708                  $sql = 'SELECT *
1709                      FROM ' . MODULES_TABLE . "
1710                      WHERE module_basename = 'mcp_pm_reports'
1711                          AND module_class = 'mcp'
1712                          AND module_mode = 'pm_reports_closed'";
1713                  $result = $db->sql_query($sql);
1714                  $row = $db->sql_fetchrow($result);
1715                  $db->sql_freeresult($result);
1716  
1717                  $_module->move_module_by($row, 'move_down', 3);
1718  
1719                  // Move open pm reports module 3 down...
1720                  $sql = 'SELECT *
1721                      FROM ' . MODULES_TABLE . "
1722                      WHERE module_basename = 'mcp_pm_reports'
1723                          AND module_class = 'mcp'
1724                          AND module_mode = 'pm_reports'";
1725                  $result = $db->sql_query($sql);
1726                  $row = $db->sql_fetchrow($result);
1727                  $db->sql_freeresult($result);
1728  
1729                  $_module->move_module_by($row, 'move_down', 3);
1730              }
1731  
1732              if ($module_class == 'ucp')
1733              {
1734                  // Move attachment module 4 down...
1735                  $sql = 'SELECT *
1736                      FROM ' . MODULES_TABLE . "
1737                      WHERE module_basename = 'ucp_attachments'
1738                          AND module_class = 'ucp'
1739                          AND module_mode = 'attachments'";
1740                  $result = $db->sql_query($sql);
1741                  $row = $db->sql_fetchrow($result);
1742                  $db->sql_freeresult($result);
1743  
1744                  $_module->move_module_by($row, 'move_down', 4);
1745  
1746                  // Move notification options module 4 down...
1747                  $sql = 'SELECT *
1748                      FROM ' . MODULES_TABLE . "
1749                      WHERE module_basename = 'ucp_notifications'
1750                          AND module_class = 'ucp'
1751                          AND module_mode = 'notification_options'";
1752                  $result = $db->sql_query($sql);
1753                  $row = $db->sql_fetchrow($result);
1754                  $db->sql_freeresult($result);
1755  
1756                  $_module->move_module_by($row, 'move_down', 4);
1757  
1758                  // Move OAuth module 5 down...
1759                  $sql = 'SELECT *
1760                      FROM ' . MODULES_TABLE . "
1761                      WHERE module_basename = 'ucp_auth_link'
1762                          AND module_class = 'ucp'
1763                          AND module_mode = 'auth_link'";
1764                  $result = $db->sql_query($sql);
1765                  $row = $db->sql_fetchrow($result);
1766                  $db->sql_freeresult($result);
1767  
1768                  $_module->move_module_by($row, 'move_down', 5);
1769              }
1770  
1771              // And now for the special ones
1772              // (these are modules which appear in multiple categories and thus get added manually to some for more control)
1773              if (isset($this->module_extras[$module_class]))
1774              {
1775                  foreach ($this->module_extras[$module_class] as $cat_name => $mods)
1776                  {
1777                      $sql = 'SELECT module_id, left_id, right_id
1778                          FROM ' . MODULES_TABLE . "
1779                          WHERE module_langname = '" . $db->sql_escape($cat_name) . "'
1780                              AND module_class = '" . $db->sql_escape($module_class) . "'";
1781                      $result = $db->sql_query_limit($sql, 1);
1782                      $row2 = $db->sql_fetchrow($result);
1783                      $db->sql_freeresult($result);
1784  
1785                      foreach ($mods as $mod_name)
1786                      {
1787                          $sql = 'SELECT *
1788                              FROM ' . MODULES_TABLE . "
1789                              WHERE module_langname = '" . $db->sql_escape($mod_name) . "'
1790                                  AND module_class = '" . $db->sql_escape($module_class) . "'
1791                                  AND module_basename <> ''";
1792                          $result = $db->sql_query_limit($sql, 1);
1793                          $row = $db->sql_fetchrow($result);
1794                          $db->sql_freeresult($result);
1795  
1796                          $module_data = array(
1797                              'module_basename'    => $row['module_basename'],
1798                              'module_enabled'    => (int) $row['module_enabled'],
1799                              'module_display'    => (int) $row['module_display'],
1800                              'parent_id'            => (int) $row2['module_id'],
1801                              'module_class'        => $row['module_class'],
1802                              'module_langname'    => $row['module_langname'],
1803                              'module_mode'        => $row['module_mode'],
1804                              'module_auth'        => $row['module_auth'],
1805                          );
1806  
1807                          $_module->update_module_data($module_data, true);
1808  
1809                          // Check for last sql error happened
1810                          if ($db->get_sql_error_triggered())
1811                          {
1812                              $error = $db->sql_error($db->get_sql_error_sql());
1813                              $this->p_master->db_error($error['message'], $db->get_sql_error_sql(), __LINE__, __FILE__);
1814                          }
1815                      }
1816                  }
1817              }
1818  
1819              $_module->remove_cache_file();
1820          }
1821      }
1822  
1823      /**
1824      * Populate the language tables
1825      */
1826  	function add_language($mode, $sub)
1827      {
1828          global $db, $lang, $phpbb_root_path, $phpEx;
1829  
1830          $dir = @opendir($phpbb_root_path . 'language');
1831  
1832          if (!$dir)
1833          {
1834              $this->error('Unable to access the language directory', __LINE__, __FILE__);
1835          }
1836  
1837          $installed_languages = array();
1838          while (($file = readdir($dir)) !== false)
1839          {
1840              $path = $phpbb_root_path . 'language/' . $file;
1841  
1842              if ($file == '.' || $file == '..' || is_link($path) || is_file($path) || $file == 'CVS')
1843              {
1844                  continue;
1845              }
1846  
1847              if (is_dir($path) && file_exists($path . '/iso.txt'))
1848              {
1849                  $lang_file = file("$path/iso.txt");
1850  
1851                  $lang_pack = array(
1852                      'lang_iso'            => basename($path),
1853                      'lang_dir'            => basename($path),
1854                      'lang_english_name'    => trim(htmlspecialchars($lang_file[0])),
1855                      'lang_local_name'    => trim(htmlspecialchars($lang_file[1], ENT_COMPAT, 'UTF-8')),
1856                      'lang_author'        => trim(htmlspecialchars($lang_file[2], ENT_COMPAT, 'UTF-8')),
1857                  );
1858  
1859                  $db->sql_query('INSERT INTO ' . LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $lang_pack));
1860  
1861                  $installed_languages[] = (int) $db->sql_nextid();
1862                  if ($db->get_sql_error_triggered())
1863                  {
1864                      $error = $db->sql_error($db->get_sql_error_sql());
1865                      $this->p_master->db_error($error['message'], $db->get_sql_error_sql(), __LINE__, __FILE__);
1866                  }
1867              }
1868          }
1869          closedir($dir);
1870  
1871          $sql = 'SELECT *
1872              FROM ' . PROFILE_FIELDS_TABLE;
1873          $result = $db->sql_query($sql);
1874  
1875          $profile_fields = array();
1876          $insert_buffer = new \phpbb\db\sql_insert_buffer($db, PROFILE_LANG_TABLE);
1877          while ($row = $db->sql_fetchrow($result))
1878          {
1879              foreach ($installed_languages as $lang_id)
1880              {
1881                  $insert_buffer->insert(array(
1882                      'field_id'                => $row['field_id'],
1883                      'lang_id'                => $lang_id,
1884                      'lang_name'                => strtoupper(substr($row['field_name'], 6)),// Remove phpbb_ from field name
1885                      'lang_explain'            => '',
1886                      'lang_default_value'    => '',
1887                  ));
1888              }
1889          }
1890          $db->sql_freeresult($result);
1891  
1892          $insert_buffer->flush();
1893      }
1894  
1895      /**
1896      * Add search robots to the database
1897      */
1898  	function add_bots($mode, $sub)
1899      {
1900          global $db, $lang, $phpbb_root_path, $phpEx, $config;
1901  
1902          // Obtain any submitted data
1903          $data = $this->get_submitted_data();
1904  
1905          // We need to fill the config to let internal functions correctly work
1906          $config = new \phpbb\config\db($db, new \phpbb\cache\driver\null, CONFIG_TABLE);
1907          set_config(null, null, null, $config);
1908          set_config_count(null, null, null, $config);
1909  
1910          $sql = 'SELECT group_id
1911              FROM ' . GROUPS_TABLE . "
1912              WHERE group_name = 'BOTS'";
1913          $result = $db->sql_query($sql);
1914          $group_id = (int) $db->sql_fetchfield('group_id');
1915          $db->sql_freeresult($result);
1916  
1917          if (!$group_id)
1918          {
1919              // If we reach this point then something has gone very wrong
1920              $this->p_master->error($lang['NO_GROUP'], __LINE__, __FILE__);
1921          }
1922  
1923          if (!function_exists('user_add'))
1924          {
1925              include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
1926          }
1927  
1928          foreach ($this->bot_list as $bot_name => $bot_ary)
1929          {
1930              $user_row = array(
1931                  'user_type'                => USER_IGNORE,
1932                  'group_id'                => $group_id,
1933                  'username'                => $bot_name,
1934                  'user_regdate'            => time(),
1935                  'user_password'            => '',
1936                  'user_colour'            => '9E8DA7',
1937                  'user_email'            => '',
1938                  'user_lang'                => $data['default_lang'],
1939                  'user_style'            => 1,
1940                  'user_timezone'            => 'UTC',
1941                  'user_dateformat'        => $lang['default_dateformat'],
1942                  'user_allow_massemail'    => 0,
1943                  'user_allow_pm'            => 0,
1944              );
1945  
1946              $user_id = user_add($user_row);
1947  
1948              if (!$user_id)
1949              {
1950                  // If we can't insert this user then continue to the next one to avoid inconsistent data
1951                  $this->p_master->db_error('Unable to insert bot into users table', $db->get_sql_error_sql(), __LINE__, __FILE__, true);
1952                  continue;
1953              }
1954  
1955              $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $db->sql_build_array('INSERT', array(
1956                  'bot_active'    => 1,
1957                  'bot_name'        => (string) $bot_name,
1958                  'user_id'        => (int) $user_id,
1959                  'bot_agent'        => (string) $bot_ary[0],
1960                  'bot_ip'        => (string) $bot_ary[1],
1961              ));
1962  
1963              $db->sql_query($sql);
1964          }
1965      }
1966  
1967      /**
1968      * Sends an email to the board administrator with their password and some useful links
1969      */
1970  	function email_admin($mode, $sub)
1971      {
1972          global $auth, $config, $db, $lang, $template, $user, $phpbb_root_path, $phpbb_admin_path, $phpEx;
1973  
1974          $this->page_title = $lang['STAGE_FINAL'];
1975  
1976          // Obtain any submitted data
1977          $data = $this->get_submitted_data();
1978  
1979          // We need to fill the config to let internal functions correctly work
1980          $config = new \phpbb\config\db($db, new \phpbb\cache\driver\null, CONFIG_TABLE);
1981          set_config(null, null, null, $config);
1982          set_config_count(null, null, null, $config);
1983  
1984          $user->session_begin();
1985          $auth->login($data['admin_name'], $data['admin_pass1'], false, true, true);
1986  
1987          // OK, Now that we've reached this point we can be confident that everything
1988          // is installed and working......I hope :)
1989          // So it's time to send an email to the administrator confirming the details
1990          // they entered
1991  
1992          if ($config['email_enable'])
1993          {
1994              include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
1995  
1996              $messenger = new messenger(false);
1997  
1998              $messenger->template('installed', $data['language']);
1999  
2000              $messenger->to($data['board_email'], $data['admin_name']);
2001  
2002              $messenger->anti_abuse_headers($config, $user);
2003  
2004              $messenger->assign_vars(array(
2005                  'USERNAME'        => htmlspecialchars_decode($data['admin_name']),
2006                  'PASSWORD'        => htmlspecialchars_decode($data['admin_pass1']))
2007              );
2008  
2009              $messenger->send(NOTIFY_EMAIL);
2010          }
2011  
2012          // And finally, add a note to the log
2013          add_log('admin', 'LOG_INSTALL_INSTALLED', $config['version']);
2014  
2015          $template->assign_vars(array(
2016              'TITLE'        => $lang['INSTALL_CONGRATS'],
2017              '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'),
2018              'L_SUBMIT'    => $lang['INSTALL_LOGIN'],
2019              'U_ACTION'    => append_sid($phpbb_admin_path . 'index.' . $phpEx, 'i=send_statistics&amp;mode=send_statistics'),
2020          ));
2021      }
2022  
2023      /**
2024      * Check if the avatar directory is writable and disable avatars
2025      * if it isn't writable.
2026      */
2027  	function disable_avatars_if_unwritable()
2028      {
2029          global $phpbb_root_path;
2030  
2031          if (!phpbb_is_writable($phpbb_root_path . 'images/avatars/upload/'))
2032          {
2033              set_config('allow_avatar', 0);
2034              set_config('allow_avatar_upload', 0);
2035          }
2036      }
2037  
2038      /**
2039      * Populate migrations for the installation
2040      *
2041      * This "installs" all migrations from (root path)/phpbb/db/migrations/data.
2042      * "installs" means it adds all migrations to the migrations table, but does not
2043      * perform any of the actions in the migrations.
2044      *
2045      * @param \phpbb\extension\manager $extension_manager
2046      * @param \phpbb\db\migrator $migrator
2047      */
2048  	function populate_migrations($extension_manager, $migrator)
2049      {
2050          $finder = $extension_manager->get_finder();
2051  
2052          $migrations = $finder
2053              ->core_path('phpbb/db/migration/data/')
2054              ->get_classes();
2055          $migrator->populate_migrations($migrations);
2056      }
2057  
2058      /**
2059      * Generate a list of available mail server authentication methods
2060      */
2061  	function mail_auth_select($selected_method)
2062      {
2063          global $lang;
2064  
2065          $auth_methods = array('PLAIN', 'LOGIN', 'CRAM-MD5', 'DIGEST-MD5', 'POP-BEFORE-SMTP');
2066          $s_smtp_auth_options = '';
2067  
2068          foreach ($auth_methods as $method)
2069          {
2070              $s_smtp_auth_options .= '<option value="' . $method . '"' . (($selected_method == $method) ? ' selected="selected"' : '') . '>' . $lang['SMTP_' . str_replace('-', '_', $method)] . '</option>';
2071          }
2072  
2073          return $s_smtp_auth_options;
2074      }
2075  
2076      /**
2077      * Get submitted data
2078      */
2079  	function get_submitted_data()
2080      {
2081          return array(
2082              'language'        => basename(request_var('language', '')),
2083              'dbms'            => request_var('dbms', ''),
2084              'dbhost'        => request_var('dbhost', '', true),
2085              'dbport'        => request_var('dbport', ''),
2086              'dbuser'        => request_var('dbuser', ''),
2087              'dbpasswd'        => request_var('dbpasswd', '', true),
2088              'dbname'        => request_var('dbname', ''),
2089              'table_prefix'    => request_var('table_prefix', ''),
2090              'default_lang'    => basename(request_var('default_lang', '')),
2091              'admin_name'    => utf8_normalize_nfc(request_var('admin_name', '', true)),
2092              'admin_pass1'    => request_var('admin_pass1', '', true),
2093              'admin_pass2'    => request_var('admin_pass2', '', true),
2094              'board_email'    => strtolower(request_var('board_email', '')),
2095              'img_imagick'    => request_var('img_imagick', ''),
2096              'ftp_path'        => request_var('ftp_path', ''),
2097              'ftp_user'        => request_var('ftp_user', ''),
2098              'ftp_pass'        => request_var('ftp_pass', ''),
2099              'email_enable'    => request_var('email_enable', ''),
2100              'smtp_delivery'    => request_var('smtp_delivery', ''),
2101              'smtp_host'        => request_var('smtp_host', ''),
2102              'smtp_auth'        => request_var('smtp_auth', ''),
2103              'smtp_user'        => request_var('smtp_user', ''),
2104              'smtp_pass'        => request_var('smtp_pass', ''),
2105              'cookie_secure'    => request_var('cookie_secure', ''),
2106              'force_server_vars'    => request_var('force_server_vars', ''),
2107              'server_protocol'    => request_var('server_protocol', ''),
2108              'server_name'    => request_var('server_name', ''),
2109              'server_port'    => request_var('server_port', ''),
2110              'script_path'    => request_var('script_path', ''),
2111          );
2112      }
2113  
2114      /**
2115      * The information below will be used to build the input fields presented to the user
2116      */
2117      var $db_config_options = array(
2118          'legend1'                => 'DB_CONFIG',
2119          'dbms'                    => array('lang' => 'DBMS',            'type' => 'select', 'options' => 'dbms_select(\'{VALUE}\')', 'explain' => false),
2120          'dbhost'                => array('lang' => 'DB_HOST',        'type' => 'text:25:100', 'explain' => true),
2121          'dbport'                => array('lang' => 'DB_PORT',        'type' => 'text:25:100', 'explain' => true),
2122          'dbname'                => array('lang' => 'DB_NAME',        'type' => 'text:25:100', 'explain' => false),
2123          'dbuser'                => array('lang' => 'DB_USERNAME',    'type' => 'text:25:100', 'explain' => false),
2124          'dbpasswd'                => array('lang' => 'DB_PASSWORD',    'type' => 'password:25:100', 'explain' => false),
2125          'table_prefix'            => array('lang' => 'TABLE_PREFIX',    'type' => 'text:25:100', 'explain' => true),
2126      );
2127      var $admin_config_options = array(
2128          'legend1'                => 'ADMIN_CONFIG',
2129          'default_lang'            => array('lang' => 'DEFAULT_LANG',                'type' => 'select', 'options' => '$this->module->inst_language_select(\'{VALUE}\')', 'explain' => false),
2130          'admin_name'            => array('lang' => 'ADMIN_USERNAME',            'type' => 'text:25:100', 'explain' => true),
2131          'admin_pass1'            => array('lang' => 'ADMIN_PASSWORD',            'type' => 'password:25:100', 'explain' => true),
2132          'admin_pass2'            => array('lang' => 'ADMIN_PASSWORD_CONFIRM',    'type' => 'password:25:100', 'explain' => false),
2133          'board_email'            => array('lang' => 'CONTACT_EMAIL',                'type' => 'email:25:100', 'explain' => false),
2134      );
2135      var $advanced_config_options = array(
2136          'legend1'                => 'ACP_EMAIL_SETTINGS',
2137          'email_enable'            => array('lang' => 'ENABLE_EMAIL',        'type' => 'radio:enabled_disabled', 'explain' => true),
2138          'smtp_delivery'            => array('lang' => 'USE_SMTP',            'type' => 'radio:yes_no', 'explain' => true),
2139          'smtp_host'                => array('lang' => 'SMTP_SERVER',        'type' => 'text:25:50', 'explain' => false),
2140          'smtp_auth'                => array('lang' => 'SMTP_AUTH_METHOD',    'type' => 'select', 'options' => '$this->module->mail_auth_select(\'{VALUE}\')', 'explain' => true),
2141          'smtp_user'                => array('lang' => 'SMTP_USERNAME',        'type' => 'text:25:255', 'explain' => true, 'options' => array('autocomplete' => 'off')),
2142          'smtp_pass'                => array('lang' => 'SMTP_PASSWORD',        'type' => 'password:25:255', 'explain' => true, 'options' => array('autocomplete' => 'off')),
2143  
2144          'legend2'                => 'SERVER_URL_SETTINGS',
2145          'cookie_secure'            => array('lang' => 'COOKIE_SECURE',        'type' => 'radio:enabled_disabled', 'explain' => true),
2146          'force_server_vars'        => array('lang' => 'FORCE_SERVER_VARS',    'type' => 'radio:yes_no', 'explain' => true),
2147          'server_protocol'        => array('lang' => 'SERVER_PROTOCOL',    'type' => 'text:10:10', 'explain' => true),
2148          'server_name'            => array('lang' => 'SERVER_NAME',        'type' => 'text:40:255', 'explain' => true),
2149          'server_port'            => array('lang' => 'SERVER_PORT',        'type' => 'text:5:5', 'explain' => true),
2150          'script_path'            => array('lang' => 'SCRIPT_PATH',        'type' => 'text::255', 'explain' => true),
2151      );
2152  
2153      /**
2154      * Specific PHP modules we may require for certain optional or extended features
2155      */
2156      var $php_dlls_other = array('zlib', 'ftp', 'gd', 'xml');
2157  
2158      /**
2159      * A list of the web-crawlers/bots we recognise by default
2160      *
2161      * Candidates but not included:
2162      * 'Accoona [Bot]'                'Accoona-AI-Agent/'
2163      * 'ASPseek [Crawler]'            'ASPseek/'
2164      * 'Boitho [Crawler]'            'boitho.com-dc/'
2165      * 'Bunnybot [Bot]'                'powered by www.buncat.de'
2166      * 'Cosmix [Bot]'                'cfetch/'
2167      * 'Crawler Search [Crawler]'    '.Crawler-Search.de'
2168      * 'Findexa [Crawler]'            'Findexa Crawler ('
2169      * 'GBSpider [Spider]'            'GBSpider v'
2170      * 'genie [Bot]'                    'genieBot ('
2171      * 'Hogsearch [Bot]'                'oegp v. 1.3.0'
2172      * 'Insuranco [Bot]'                'InsurancoBot'
2173      * 'IRLbot [Bot]'                'http://irl.cs.tamu.edu/crawler'
2174      * 'ISC Systems [Bot]'            'ISC Systems iRc Search'
2175      * 'Jyxobot [Bot]'                'Jyxobot/'
2176      * 'Kraehe [Metasuche]'            '-DIE-KRAEHE- META-SEARCH-ENGINE/'
2177      * 'LinkWalker'                    'LinkWalker'
2178      * 'MMSBot [Bot]'                'http://www.mmsweb.at/bot.html'
2179      * 'Naver [Bot]'                    'nhnbot@naver.com)'
2180      * 'NetResearchServer'            'NetResearchServer/'
2181      * 'Nimble [Crawler]'            'NimbleCrawler'
2182      * 'Ocelli [Bot]'                'Ocelli/'
2183      * 'Onsearch [Bot]'                'onCHECK-Robot'
2184      * 'Orange [Spider]'                'OrangeSpider'
2185      * 'Sproose [Bot]'                'http://www.sproose.com/bot'
2186      * 'Susie [Sync]'                '!Susie (http://www.sync2it.com/susie)'
2187      * 'Tbot [Bot]'                    'Tbot/'
2188      * 'Thumbshots [Capture]'        'thumbshots-de-Bot'
2189      * 'Vagabondo [Crawler]'            'http://webagent.wise-guys.nl/'
2190      * 'Walhello [Bot]'                'appie 1.1 (www.walhello.com)'
2191      * 'WissenOnline [Bot]'            'WissenOnline-Bot'
2192      * 'WWWeasel [Bot]'                'WWWeasel Robot v'
2193      * 'Xaldon [Spider]'                'Xaldon WebSpider'
2194      */
2195      var $bot_list = array(
2196          'AdsBot [Google]'            => array('AdsBot-Google', ''),
2197          'Alexa [Bot]'                => array('ia_archiver', ''),
2198          'Alta Vista [Bot]'            => array('Scooter/', ''),
2199          'Ask Jeeves [Bot]'            => array('Ask Jeeves', ''),
2200          'Baidu [Spider]'            => array('Baiduspider', ''),
2201          'Bing [Bot]'                => array('bingbot/', ''),
2202          'Exabot [Bot]'                => array('Exabot', ''),
2203          'FAST Enterprise [Crawler]'    => array('FAST Enterprise Crawler', ''),
2204          'FAST WebCrawler [Crawler]'    => array('FAST-WebCrawler/', ''),
2205          'Francis [Bot]'                => array('http://www.neomo.de/', ''),
2206          'Gigabot [Bot]'                => array('Gigabot/', ''),
2207          'Google Adsense [Bot]'        => array('Mediapartners-Google', ''),
2208          'Google Desktop'            => array('Google Desktop', ''),
2209          'Google Feedfetcher'        => array('Feedfetcher-Google', ''),
2210          'Google [Bot]'                => array('Googlebot', ''),
2211          'Heise IT-Markt [Crawler]'    => array('heise-IT-Markt-Crawler', ''),
2212          'Heritrix [Crawler]'        => array('heritrix/1.', ''),
2213          'IBM Research [Bot]'        => array('ibm.com/cs/crawler', ''),
2214          'ICCrawler - ICjobs'        => array('ICCrawler - ICjobs', ''),
2215          'ichiro [Crawler]'            => array('ichiro/', ''),
2216          'Majestic-12 [Bot]'            => array('MJ12bot/', ''),
2217          'Metager [Bot]'                => array('MetagerBot/', ''),
2218          'MSN NewsBlogs'                => array('msnbot-NewsBlogs/', ''),
2219          'MSN [Bot]'                    => array('msnbot/', ''),
2220          'MSNbot Media'                => array('msnbot-media/', ''),
2221          'Nutch [Bot]'                => array('http://lucene.apache.org/nutch/', ''),
2222          'Online link [Validator]'    => array('online link validator', ''),
2223          'psbot [Picsearch]'            => array('psbot/0', ''),
2224          'Sensis [Crawler]'            => array('Sensis Web Crawler', ''),
2225          'SEO Crawler'                => array('SEO search Crawler/', ''),
2226          'Seoma [Crawler]'            => array('Seoma [SEO Crawler]', ''),
2227          'SEOSearch [Crawler]'        => array('SEOsearch/', ''),
2228          'Snappy [Bot]'                => array('Snappy/1.1 ( http://www.urltrends.com/ )', ''),
2229          'Steeler [Crawler]'            => array('http://www.tkl.iis.u-tokyo.ac.jp/~crawler/', ''),
2230          'Telekom [Bot]'                => array('crawleradmin.t-info@telekom.de', ''),
2231          'TurnitinBot [Bot]'            => array('TurnitinBot/', ''),
2232          'Voyager [Bot]'                => array('voyager/', ''),
2233          'W3 [Sitesearch]'            => array('W3 SiteSearch Crawler', ''),
2234          'W3C [Linkcheck]'            => array('W3C-checklink/', ''),
2235          'W3C [Validator]'            => array('W3C_Validator', ''),
2236          'YaCy [Bot]'                => array('yacybot', ''),
2237          'Yahoo MMCrawler [Bot]'        => array('Yahoo-MMCrawler/', ''),
2238          'Yahoo Slurp [Bot]'            => array('Yahoo! DE Slurp', ''),
2239          'Yahoo [Bot]'                => array('Yahoo! Slurp', ''),
2240          'YahooSeeker [Bot]'            => array('YahooSeeker/', ''),
2241      );
2242  
2243      /**
2244      * Define the module structure so that we can populate the database without
2245      * needing to hard-code module_id values
2246      */
2247      var $module_categories = array(
2248          'acp'    => array(
2249              'ACP_CAT_GENERAL'        => array(
2250                  'ACP_QUICK_ACCESS',
2251                  'ACP_BOARD_CONFIGURATION',
2252                  'ACP_CLIENT_COMMUNICATION',
2253                  'ACP_SERVER_CONFIGURATION',
2254              ),
2255              'ACP_CAT_FORUMS'        => array(
2256                  'ACP_MANAGE_FORUMS',
2257                  'ACP_FORUM_BASED_PERMISSIONS',
2258              ),
2259              'ACP_CAT_POSTING'        => array(
2260                  'ACP_MESSAGES',
2261                  'ACP_ATTACHMENTS',
2262              ),
2263              'ACP_CAT_USERGROUP'        => array(
2264                  'ACP_CAT_USERS',
2265                  'ACP_GROUPS',
2266                  'ACP_USER_SECURITY',
2267              ),
2268              'ACP_CAT_PERMISSIONS'    => array(
2269                  'ACP_GLOBAL_PERMISSIONS',
2270                  'ACP_FORUM_BASED_PERMISSIONS',
2271                  'ACP_PERMISSION_ROLES',
2272                  'ACP_PERMISSION_MASKS',
2273              ),
2274              'ACP_CAT_CUSTOMISE'        => array(
2275                  'ACP_STYLE_MANAGEMENT',
2276                  'ACP_EXTENSION_MANAGEMENT',
2277                  'ACP_LANGUAGE',
2278              ),
2279              'ACP_CAT_MAINTENANCE'    => array(
2280                  'ACP_FORUM_LOGS',
2281                  'ACP_CAT_DATABASE',
2282              ),
2283              'ACP_CAT_SYSTEM'        => array(
2284                  'ACP_AUTOMATION',
2285                  'ACP_GENERAL_TASKS',
2286                  'ACP_MODULE_MANAGEMENT',
2287              ),
2288              'ACP_CAT_DOT_MODS'        => null,
2289          ),
2290          'mcp'    => array(
2291              'MCP_MAIN'        => null,
2292              'MCP_QUEUE'        => null,
2293              'MCP_REPORTS'    => null,
2294              'MCP_NOTES'        => null,
2295              'MCP_WARN'        => null,
2296              'MCP_LOGS'        => null,
2297              'MCP_BAN'        => null,
2298          ),
2299          'ucp'    => array(
2300              'UCP_MAIN'            => null,
2301              'UCP_PROFILE'        => null,
2302              'UCP_PREFS'            => null,
2303              'UCP_PM'            => null,
2304              'UCP_USERGROUPS'    => null,
2305              'UCP_ZEBRA'            => null,
2306          ),
2307      );
2308      var $module_categories_basenames = array(
2309          'UCP_PM' => 'ucp_pm',
2310      );
2311  
2312      var $module_extras = array(
2313          'acp'    => array(
2314              'ACP_QUICK_ACCESS' => array(
2315                  'ACP_MANAGE_USERS',
2316                  'ACP_GROUPS_MANAGE',
2317                  'ACP_MANAGE_FORUMS',
2318                  'ACP_MOD_LOGS',
2319                  'ACP_BOTS',
2320                  'ACP_PHP_INFO',
2321              ),
2322              'ACP_FORUM_BASED_PERMISSIONS' => array(
2323                  'ACP_FORUM_PERMISSIONS',
2324                  'ACP_FORUM_PERMISSIONS_COPY',
2325                  'ACP_FORUM_MODERATORS',
2326                  'ACP_USERS_FORUM_PERMISSIONS',
2327                  'ACP_GROUPS_FORUM_PERMISSIONS',
2328              ),
2329          ),
2330      );
2331  }


Generated: Thu Jan 11 00:25:41 2018 Cross-referenced by PHPXref 0.7.1