[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/phpbb/install/helper/ -> database.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  namespace phpbb\install\helper;
  15  
  16  use phpbb\install\exception\invalid_dbms_exception;
  17  
  18  /**
  19   * Database related general functionality for installer
  20   */
  21  class database
  22  {
  23      /**
  24       * @var \phpbb\filesystem\filesystem_interface
  25       */
  26      protected $filesystem;
  27  
  28      /**
  29       * @var string
  30       */
  31      protected $phpbb_root_path;
  32  
  33      /**
  34       * @var array
  35       */
  36      protected $supported_dbms = array(
  37          // Note: php 5.5 alpha 2 deprecated mysql.
  38          // Keep mysqli before mysql in this list.
  39          'mysqli'    => array(
  40              'LABEL'            => 'MySQL with MySQLi Extension',
  41              'SCHEMA'        => 'mysql_41',
  42              'MODULE'        => 'mysqli',
  43              'DELIM'            => ';',
  44              'DRIVER'        => 'phpbb\db\driver\mysqli',
  45              'AVAILABLE'        => true,
  46              '2.0.x'            => true,
  47          ),
  48          'mysql'        => array(
  49              'LABEL'            => 'MySQL',
  50              'SCHEMA'        => 'mysql',
  51              'MODULE'        => 'mysql',
  52              'DELIM'            => ';',
  53              'DRIVER'        => 'phpbb\db\driver\mysql',
  54              'AVAILABLE'        => true,
  55              '2.0.x'            => true,
  56          ),
  57          'mssql_odbc'=>    array(
  58              'LABEL'            => 'MS SQL Server [ ODBC ]',
  59              'SCHEMA'        => 'mssql',
  60              'MODULE'        => 'odbc',
  61              'DELIM'            => ';',
  62              'DRIVER'        => 'phpbb\db\driver\mssql_odbc',
  63              'AVAILABLE'        => true,
  64              '2.0.x'            => true,
  65          ),
  66          'mssqlnative'        => array(
  67              'LABEL'            => 'MS SQL Server 2005+ [ Native ]',
  68              'SCHEMA'        => 'mssql',
  69              'MODULE'        => 'sqlsrv',
  70              'DELIM'            => ';',
  71              'DRIVER'        => 'phpbb\db\driver\mssqlnative',
  72              'AVAILABLE'        => true,
  73              '2.0.x'            => false,
  74          ),
  75          'oracle'    =>    array(
  76              'LABEL'            => 'Oracle',
  77              'SCHEMA'        => 'oracle',
  78              'MODULE'        => 'oci8',
  79              'DELIM'            => ';',
  80              'DRIVER'        => 'phpbb\db\driver\oracle',
  81              'AVAILABLE'        => true,
  82              '2.0.x'            => false,
  83          ),
  84          'postgres' => array(
  85              'LABEL'            => 'PostgreSQL 8.3+',
  86              'SCHEMA'        => 'postgres',
  87              'MODULE'        => 'pgsql',
  88              'DELIM'            => ';',
  89              'DRIVER'        => 'phpbb\db\driver\postgres',
  90              'AVAILABLE'        => true,
  91              '2.0.x'            => true,
  92          ),
  93          'sqlite3'        => array(
  94              'LABEL'            => 'SQLite3',
  95              'SCHEMA'        => 'sqlite',
  96              'MODULE'        => 'sqlite3',
  97              'DELIM'            => ';',
  98              'DRIVER'        => 'phpbb\db\driver\sqlite3',
  99              'AVAILABLE'        => true,
 100              '2.0.x'            => false,
 101          ),
 102      );
 103  
 104      /**
 105       * Constructor
 106       *
 107       * @param \phpbb\filesystem\filesystem_interface    $filesystem            Filesystem interface
 108       * @param string                                    $phpbb_root_path    Path to phpBB's root
 109       */
 110  	public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path)
 111      {
 112          $this->filesystem        = $filesystem;
 113          $this->phpbb_root_path    = $phpbb_root_path;
 114      }
 115  
 116      /**
 117       * Returns an array of available DBMS supported by phpBB
 118       *
 119       * If a DBMS is specified it will only return data for that DBMS
 120       * and will load its extension if necessary.
 121       *
 122       * @param    mixed    $dbms                name of the DBMS that's info is required or false for all DBMS info
 123       * @param    bool    $return_unavailable    set it to true if you expect unavailable but supported DBMS
 124       *                                         returned as well
 125       * @param    bool    $only_20x_options    set it to true if you only want to recover 2.0.x options
 126       *
 127       * @return    array    Array of available and supported DBMS
 128       */
 129  	public function get_available_dbms($dbms = false, $return_unavailable = false, $only_20x_options = false)
 130      {
 131          $available_dbms = $this->supported_dbms;
 132  
 133          if ($dbms)
 134          {
 135              if (isset($this->supported_dbms[$dbms]))
 136              {
 137                  $available_dbms = array($dbms => $this->supported_dbms[$dbms]);
 138              }
 139              else
 140              {
 141                  return array();
 142              }
 143          }
 144  
 145          $any_dbms_available = false;
 146          foreach ($available_dbms as $db_name => $db_array)
 147          {
 148              if ($only_20x_options && !$db_array['2.0.x'])
 149              {
 150                  if ($return_unavailable)
 151                  {
 152                      $available_dbms[$db_name]['AVAILABLE'] = false;
 153                  }
 154                  else
 155                  {
 156                      unset($available_dbms[$db_name]);
 157                  }
 158  
 159                  continue;
 160              }
 161  
 162              $dll = $db_array['MODULE'];
 163              if (!@extension_loaded($dll))
 164              {
 165                  if ($return_unavailable)
 166                  {
 167                      $available_dbms[$db_name]['AVAILABLE'] = false;
 168                  }
 169                  else
 170                  {
 171                      unset($available_dbms[$db_name]);
 172                  }
 173  
 174                  continue;
 175              }
 176  
 177              $any_dbms_available = true;
 178          }
 179  
 180          if ($return_unavailable)
 181          {
 182              $available_dbms['ANY_DB_SUPPORT'] = $any_dbms_available;
 183          }
 184  
 185          return $available_dbms;
 186      }
 187  
 188      /**
 189       * Removes "/* style" as well as "# style" comments from $input.
 190       *
 191       * @param string $sql_query    Input string
 192       *
 193       * @return string Input string with comments removed
 194       */
 195  	public function remove_comments($sql_query)
 196      {
 197          // Remove /* */ comments (http://ostermiller.org/findcomment.html)
 198          $sql_query = preg_replace('#/\*(.|[\r\n])*?\*/#', "\n", $sql_query);
 199  
 200          // Remove # style comments
 201          $sql_query = preg_replace('/\n{2,}/', "\n", preg_replace('/^#.*$/m', "\n", $sql_query));
 202  
 203          return $sql_query;
 204      }
 205  
 206      /**
 207       * split_sql_file() will split an uploaded sql file into single sql statements.
 208       *
 209       * Note: expects trim() to have already been run on $sql.
 210       *
 211       * @param    string    $sql        SQL statements
 212       * @param    string    $delimiter    Delimiter between sql statements
 213       *
 214       * @return array Array of sql statements
 215       */
 216  	public function split_sql_file($sql, $delimiter)
 217      {
 218          $sql = str_replace("\r" , '', $sql);
 219          $data = preg_split('/' . preg_quote($delimiter, '/') . '$/m', $sql);
 220  
 221          $data = array_map('trim', $data);
 222  
 223          // The empty case
 224          $end_data = end($data);
 225  
 226          if (empty($end_data))
 227          {
 228              unset($data[key($data)]);
 229          }
 230  
 231          return $data;
 232      }
 233  
 234      /**
 235       * Validates table prefix
 236       *
 237       * @param string    $dbms            The selected dbms
 238       * @param string    $table_prefix    The table prefix to validate
 239       *
 240       * @return bool|array    true if table prefix is valid, array of errors otherwise
 241       *
 242       * @throws \phpbb\install\exception\invalid_dbms_exception When $dbms is not a valid
 243       */
 244  	public function validate_table_prefix($dbms, $table_prefix)
 245      {
 246          $errors = array();
 247  
 248          if (!preg_match('#^[a-zA-Z][a-zA-Z0-9_]*$#', $table_prefix))
 249          {
 250              $errors[] = array(
 251                  'title' => 'INST_ERR_DB_INVALID_PREFIX',
 252              );
 253          }
 254  
 255          // Do dbms specific checks
 256          $dbms_info = $this->get_available_dbms($dbms);
 257          switch ($dbms_info[$dbms]['SCHEMA'])
 258          {
 259              case 'mysql':
 260              case 'mysql_41':
 261                  $prefix_length = 36;
 262              break;
 263              case 'mssql':
 264                  $prefix_length = 90;
 265              break;
 266              case 'oracle':
 267                  $prefix_length = 6;
 268              break;
 269              case 'postgres':
 270                  $prefix_length = 36;
 271              break;
 272              case 'sqlite':
 273                  $prefix_length = 200;
 274              break;
 275              default:
 276                  throw new invalid_dbms_exception();
 277              break;
 278          }
 279  
 280          // Check the prefix length to ensure that index names are not too long
 281          if (strlen($table_prefix) > $prefix_length)
 282          {
 283              $errors[] = array(
 284                  'title' => array('INST_ERR_PREFIX_TOO_LONG', $prefix_length),
 285              );
 286          }
 287  
 288          return (empty($errors)) ? true : $errors;
 289      }
 290  
 291      /**
 292       * Check if the user provided database parameters are correct
 293       *
 294       * This function checks the database connection data and also checks for
 295       * any other problems that could cause an error during the installation
 296       * such as if there is any database table names conflicting.
 297       *
 298       * Note: The function assumes that $table_prefix has been already validated
 299       * with validate_table_prefix().
 300       *
 301       * @param string    $dbms            Selected database type
 302       * @param string    $dbhost            Database host address
 303       * @param int        $dbport            Database port number
 304       * @param string    $dbuser            Database username
 305       * @param string    $dbpass            Database password
 306       * @param string    $dbname            Database name
 307       * @param string    $table_prefix    Database table prefix
 308       *
 309       * @return array|bool    Returns true if test is successful, array of errors otherwise
 310       */
 311  	public function check_database_connection($dbms, $dbhost, $dbport, $dbuser, $dbpass, $dbname, $table_prefix)
 312      {
 313          $dbms_info = $this->get_available_dbms($dbms);
 314          $dbms_info = $dbms_info[$dbms];
 315          $errors = array();
 316  
 317          // Instantiate it and set return on error true
 318          /** @var \phpbb\db\driver\driver_interface $db */
 319          $db = new $dbms_info['DRIVER'];
 320          $db->sql_return_on_error(true);
 321  
 322          // Check that we actually have a database name before going any further
 323          if (!in_array($dbms_info['SCHEMA'], array('sqlite', 'oracle'), true) && $dbname === '')
 324          {
 325              $errors[] = array(
 326                  'title' => 'INST_ERR_DB_NO_NAME',
 327              );
 328          }
 329  
 330          // Make sure we don't have a daft user who thinks having the SQLite database in the forum directory is a good idea
 331          if ($dbms_info['SCHEMA'] === 'sqlite'
 332              && stripos($this->filesystem->realpath($dbhost), $this->filesystem->realpath($this->phpbb_root_path) === 0))
 333          {
 334              $errors[] = array(
 335                  'title' =>'INST_ERR_DB_FORUM_PATH',
 336              );
 337          }
 338  
 339          // Check if SQLite database is writable
 340          if ($dbms_info['SCHEMA'] === 'sqlite'
 341              && (($this->filesystem->exists($dbhost) && !$this->filesystem->is_writable($dbhost)) || !$this->filesystem->is_writable(pathinfo($dbhost, PATHINFO_DIRNAME))))
 342          {
 343              $errors[] = array(
 344                  'title' =>'INST_ERR_DB_NO_WRITABLE',
 345              );
 346          }
 347  
 348          // Try to connect to db
 349          if (is_array($db->sql_connect($dbhost, $dbuser, $dbpass, $dbname, $dbport, false, true)))
 350          {
 351              $db_error = $db->sql_error();
 352              $errors[] = array(
 353                  'title' => 'INST_ERR_DB_CONNECT',
 354                  'description' => ($db_error['message']) ? utf8_convert_message($db_error['message']) : 'INST_ERR_DB_NO_ERROR',
 355              );
 356          }
 357          else
 358          {
 359              // Check if there is any table name collisions
 360              $temp_prefix = strtolower($table_prefix);
 361              $table_ary = array(
 362                  $temp_prefix . 'attachments',
 363                  $temp_prefix . 'config',
 364                  $temp_prefix . 'sessions',
 365                  $temp_prefix . 'topics',
 366                  $temp_prefix . 'users',
 367              );
 368  
 369              $db_tools_factory = new \phpbb\db\tools\factory();
 370              $db_tools = $db_tools_factory->get($db);
 371              $tables = $db_tools->sql_list_tables();
 372              $tables = array_map('strtolower', $tables);
 373              $table_intersect = array_intersect($tables, $table_ary);
 374  
 375              if (count($table_intersect))
 376              {
 377                  $errors[] = array(
 378                      'title' => 'INST_ERR_PREFIX',
 379                  );
 380              }
 381  
 382              // Check if database version is supported
 383              switch ($dbms)
 384              {
 385                  case 'mysqli':
 386                      if (version_compare($db->sql_server_info(true), '4.1.3', '<'))
 387                      {
 388                          $errors[] = array(
 389                              'title' => 'INST_ERR_DB_NO_MYSQLI',
 390                          );
 391                      }
 392                  break;
 393                  case 'sqlite3':
 394                      if (version_compare($db->sql_server_info(true), '3.6.15', '<'))
 395                      {
 396                          $errors[] = array(
 397                              'title' => 'INST_ERR_DB_NO_SQLITE3',
 398                          );
 399                      }
 400                  break;
 401                  case 'oracle':
 402                      $sql = "SELECT *
 403                          FROM NLS_DATABASE_PARAMETERS
 404                          WHERE PARAMETER = 'NLS_RDBMS_VERSION'
 405                              OR PARAMETER = 'NLS_CHARACTERSET'";
 406                      $result = $db->sql_query($sql);
 407  
 408                      while ($row = $db->sql_fetchrow($result))
 409                      {
 410                          $stats[$row['parameter']] = $row['value'];
 411                      }
 412                      $db->sql_freeresult($result);
 413  
 414                      if (version_compare($stats['NLS_RDBMS_VERSION'], '9.2', '<') && $stats['NLS_CHARACTERSET'] !== 'UTF8')
 415                      {
 416                          $errors[] = array(
 417                              'title' => 'INST_ERR_DB_NO_ORACLE',
 418                          );
 419                      }
 420                  break;
 421                  case 'postgres':
 422                      $sql = "SHOW server_encoding;";
 423                      $result = $db->sql_query($sql);
 424                      $row = $db->sql_fetchrow($result);
 425                      $db->sql_freeresult($result);
 426  
 427                      if ($row['server_encoding'] !== 'UNICODE' && $row['server_encoding'] !== 'UTF8')
 428                      {
 429                          $errors[] = array(
 430                              'title' => 'INST_ERR_DB_NO_POSTGRES',
 431                          );
 432                      }
 433                  break;
 434              }
 435          }
 436  
 437          return (empty($errors)) ? true : $errors;
 438      }
 439  }


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1