[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/includes/acp/ -> acp_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  /**
  15  * @ignore
  16  */
  17  if (!defined('IN_PHPBB'))
  18  {
  19      exit;
  20  }
  21  
  22  class acp_database
  23  {
  24      var $db_tools;
  25      var $u_action;
  26      public $page_title;
  27  
  28  	function main($id, $mode)
  29      {
  30          global $cache, $db, $user, $template, $table_prefix, $request;
  31          global $phpbb_root_path, $phpbb_container, $phpbb_log;
  32  
  33          $this->db_tools = $phpbb_container->get('dbal.tools');
  34  
  35          $user->add_lang('acp/database');
  36  
  37          $this->tpl_name = 'acp_database';
  38          $this->page_title = 'ACP_DATABASE';
  39  
  40          $action    = $request->variable('action', '');
  41  
  42          $form_key = 'acp_database';
  43          add_form_key($form_key);
  44  
  45          $template->assign_vars(array(
  46              'MODE'    => $mode
  47          ));
  48  
  49          switch ($mode)
  50          {
  51              case 'backup':
  52  
  53                  $this->page_title = 'ACP_BACKUP';
  54  
  55                  switch ($action)
  56                  {
  57                      case 'download':
  58                          $type    = $request->variable('type', '');
  59                          $table    = array_intersect($this->db_tools->sql_list_tables(), $request->variable('table', array('')));
  60                          $format    = $request->variable('method', '');
  61  
  62                          if (!count($table))
  63                          {
  64                              trigger_error($user->lang['TABLE_SELECT_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING);
  65                          }
  66  
  67                          if (!check_form_key($form_key))
  68                          {
  69                              trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
  70                          }
  71  
  72                          $store = true;
  73                          $structure = false;
  74                          $schema_data = false;
  75  
  76                          if ($type == 'full' || $type == 'structure')
  77                          {
  78                              $structure = true;
  79                          }
  80  
  81                          if ($type == 'full' || $type == 'data')
  82                          {
  83                              $schema_data = true;
  84                          }
  85  
  86                          @set_time_limit(1200);
  87                          @set_time_limit(0);
  88  
  89                          $time = time();
  90  
  91                          $filename = 'backup_' . $time . '_' . unique_id();
  92  
  93                          /** @var phpbb\db\extractor\extractor_interface $extractor Database extractor */
  94                          $extractor = $phpbb_container->get('dbal.extractor');
  95                          $extractor->init_extractor($format, $filename, $time, false, $store);
  96  
  97                          $extractor->write_start($table_prefix);
  98  
  99                          foreach ($table as $table_name)
 100                          {
 101                              // Get the table structure
 102                              if ($structure)
 103                              {
 104                                  $extractor->write_table($table_name);
 105                              }
 106                              else
 107                              {
 108                                  // We might wanna empty out all that junk :D
 109                                  switch ($db->get_sql_layer())
 110                                  {
 111                                      case 'sqlite3':
 112                                          $extractor->flush('DELETE FROM ' . $table_name . ";\n");
 113                                      break;
 114  
 115                                      case 'mssql_odbc':
 116                                      case 'mssqlnative':
 117                                          $extractor->flush('TRUNCATE TABLE ' . $table_name . "GO\n");
 118                                      break;
 119  
 120                                      case 'oracle':
 121                                          $extractor->flush('TRUNCATE TABLE ' . $table_name . "/\n");
 122                                      break;
 123  
 124                                      default:
 125                                          $extractor->flush('TRUNCATE TABLE ' . $table_name . ";\n");
 126                                      break;
 127                                  }
 128                              }
 129  
 130                              // Data
 131                              if ($schema_data)
 132                              {
 133                                  $extractor->write_data($table_name);
 134                              }
 135                          }
 136  
 137                          $extractor->write_end();
 138  
 139                          $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_DB_BACKUP');
 140  
 141                          trigger_error($user->lang['BACKUP_SUCCESS'] . adm_back_link($this->u_action));
 142                      break;
 143  
 144                      default:
 145                          $tables = $this->db_tools->sql_list_tables();
 146                          asort($tables);
 147                          foreach ($tables as $table_name)
 148                          {
 149                              if (strlen($table_prefix) === 0 || stripos($table_name, $table_prefix) === 0)
 150                              {
 151                                  $template->assign_block_vars('tables', array(
 152                                      'TABLE'    => $table_name
 153                                  ));
 154                              }
 155                          }
 156                          unset($tables);
 157  
 158                          $template->assign_vars(array(
 159                              'U_ACTION'    => $this->u_action . '&amp;action=download'
 160                          ));
 161  
 162                          $available_methods = array('gzip' => 'zlib', 'bzip2' => 'bz2');
 163  
 164                          foreach ($available_methods as $type => $module)
 165                          {
 166                              if (!@extension_loaded($module))
 167                              {
 168                                  continue;
 169                              }
 170  
 171                              $template->assign_block_vars('methods', array(
 172                                  'TYPE'    => $type
 173                              ));
 174                          }
 175  
 176                          $template->assign_block_vars('methods', array(
 177                              'TYPE'    => 'text'
 178                          ));
 179                      break;
 180                  }
 181              break;
 182  
 183              case 'restore':
 184  
 185                  $this->page_title = 'ACP_RESTORE';
 186  
 187                  switch ($action)
 188                  {
 189                      case 'submit':
 190                          $delete = $request->variable('delete', '');
 191                          $file = $request->variable('file', '');
 192  
 193                          $backup_info = $this->get_backup_file($phpbb_root_path . 'store/', $file);
 194  
 195                          if (empty($backup_info) || !is_readable($backup_info['file_name']))
 196                          {
 197                              trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
 198                          }
 199  
 200                          if ($delete)
 201                          {
 202                              if (confirm_box(true))
 203                              {
 204                                  unlink($backup_info['file_name']);
 205                                  $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_DB_DELETE');
 206                                  trigger_error($user->lang['BACKUP_DELETE'] . adm_back_link($this->u_action));
 207                              }
 208                              else
 209                              {
 210                                  confirm_box(false, $user->lang['DELETE_SELECTED_BACKUP'], build_hidden_fields(array('delete' => $delete, 'file' => $file)));
 211                              }
 212                          }
 213                          else if (confirm_box(true))
 214                          {
 215                              switch ($backup_info['extension'])
 216                              {
 217                                  case 'sql':
 218                                      $fp = fopen($backup_info['file_name'], 'rb');
 219                                      $read = 'fread';
 220                                      $seek = 'fseek';
 221                                      $eof = 'feof';
 222                                      $close = 'fclose';
 223                                      $fgetd = 'fgetd';
 224                                  break;
 225  
 226                                  case 'sql.bz2':
 227                                      $fp = bzopen($backup_info['file_name'], 'r');
 228                                      $read = 'bzread';
 229                                      $seek = '';
 230                                      $eof = 'feof';
 231                                      $close = 'bzclose';
 232                                      $fgetd = 'fgetd_seekless';
 233                                  break;
 234  
 235                                  case 'sql.gz':
 236                                      $fp = gzopen($backup_info['file_name'], 'rb');
 237                                      $read = 'gzread';
 238                                      $seek = 'gzseek';
 239                                      $eof = 'gzeof';
 240                                      $close = 'gzclose';
 241                                      $fgetd = 'fgetd';
 242                                  break;
 243  
 244                                  default:
 245                                      trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
 246                                      return;
 247                              }
 248  
 249                              switch ($db->get_sql_layer())
 250                              {
 251                                  case 'mysql':
 252                                  case 'mysql4':
 253                                  case 'mysqli':
 254                                  case 'sqlite3':
 255                                      while (($sql = $fgetd($fp, ";\n", $read, $seek, $eof)) !== false)
 256                                      {
 257                                          $db->sql_query($sql);
 258                                      }
 259                                  break;
 260  
 261                                  case 'postgres':
 262                                      $delim = ";\n";
 263                                      while (($sql = $fgetd($fp, $delim, $read, $seek, $eof)) !== false)
 264                                      {
 265                                          $query = trim($sql);
 266  
 267                                          if (substr($query, 0, 13) == 'CREATE DOMAIN')
 268                                          {
 269                                              list(, , $domain) = explode(' ', $query);
 270                                              $sql = "SELECT domain_name
 271                                                  FROM information_schema.domains
 272                                                  WHERE domain_name = '$domain';";
 273                                              $result = $db->sql_query($sql);
 274                                              if (!$db->sql_fetchrow($result))
 275                                              {
 276                                                  $db->sql_query($query);
 277                                              }
 278                                              $db->sql_freeresult($result);
 279                                          }
 280                                          else
 281                                          {
 282                                              $db->sql_query($query);
 283                                          }
 284  
 285                                          if (substr($query, 0, 4) == 'COPY')
 286                                          {
 287                                              while (($sub = $fgetd($fp, "\n", $read, $seek, $eof)) !== '\.')
 288                                              {
 289                                                  if ($sub === false)
 290                                                  {
 291                                                      trigger_error($user->lang['RESTORE_FAILURE'] . adm_back_link($this->u_action), E_USER_WARNING);
 292                                                  }
 293                                                  pg_put_line($db->get_db_connect_id(), $sub . "\n");
 294                                              }
 295                                              pg_put_line($db->get_db_connect_id(), "\\.\n");
 296                                              pg_end_copy($db->get_db_connect_id());
 297                                          }
 298                                      }
 299                                  break;
 300  
 301                                  case 'oracle':
 302                                      while (($sql = $fgetd($fp, "/\n", $read, $seek, $eof)) !== false)
 303                                      {
 304                                          $db->sql_query($sql);
 305                                      }
 306                                  break;
 307  
 308                                  case 'mssql_odbc':
 309                                  case 'mssqlnative':
 310                                      while (($sql = $fgetd($fp, "GO\n", $read, $seek, $eof)) !== false)
 311                                      {
 312                                          $db->sql_query($sql);
 313                                      }
 314                                  break;
 315                              }
 316  
 317                              $close($fp);
 318  
 319                              // Purge the cache due to updated data
 320                              $cache->purge();
 321  
 322                              $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_DB_RESTORE');
 323                              trigger_error($user->lang['RESTORE_SUCCESS'] . adm_back_link($this->u_action));
 324                              break;
 325                          }
 326                          else
 327                          {
 328                              confirm_box(false, $user->lang['RESTORE_SELECTED_BACKUP'], build_hidden_fields(array('file' => $file)));
 329                          }
 330  
 331                      default:
 332                          $backup_files = $this->get_file_list($phpbb_root_path . 'store/');
 333  
 334                          if (!empty($backup_files))
 335                          {
 336                              krsort($backup_files);
 337  
 338                              foreach ($backup_files as $name => $file)
 339                              {
 340                                  $template->assign_block_vars('files', array(
 341                                      'FILE'        => sha1($file),
 342                                      'NAME'        => $user->format_date($name, 'd-m-Y H:i', true),
 343                                      'SUPPORTED'    => true,
 344                                  ));
 345                              }
 346                          }
 347  
 348                          $template->assign_vars(array(
 349                              'U_ACTION'    => $this->u_action . '&amp;action=submit'
 350                          ));
 351                      break;
 352                  }
 353              break;
 354          }
 355      }
 356  
 357      /**
 358       * Get backup file from file hash
 359       *
 360       * @param string $directory Relative path to directory
 361       * @param string $file_hash Hash of selected file
 362       *
 363       * @return array Backup file data or empty array if unable to find file
 364       */
 365  	protected function get_backup_file($directory, $file_hash)
 366      {
 367          $backup_data = [];
 368  
 369          $file_list = $this->get_file_list($directory);
 370          $supported_extensions = $this->get_supported_extensions();
 371  
 372          foreach ($file_list as $file)
 373          {
 374              preg_match('#^backup_(\d{10,})_(?:[a-z\d]{16}|[a-z\d]{32})\.(sql(?:\.(?:gz|bz2))?)$#i', $file, $matches);
 375              if (sha1($file) === $file_hash && in_array($matches[2], $supported_extensions))
 376              {
 377                  $backup_data = [
 378                      'file_name' => $directory . $file,
 379                      'extension' => $matches[2],
 380                  ];
 381                  break;
 382              }
 383          }
 384  
 385          return $backup_data;
 386      }
 387  
 388      /**
 389       * Get backup file list for directory
 390       *
 391       * @param string $directory Relative path to backup directory
 392       *
 393       * @return array List of backup files in specified directory
 394       */
 395  	protected function get_file_list($directory)
 396      {
 397          $supported_extensions = $this->get_supported_extensions();
 398  
 399          $dh = @opendir($directory);
 400  
 401          $backup_files = [];
 402  
 403          if ($dh)
 404          {
 405              while (($file = readdir($dh)) !== false)
 406              {
 407                  if (preg_match('#^backup_(\d{10,})_(?:[a-z\d]{16}|[a-z\d]{32})\.(sql(?:\.(?:gz|bz2))?)$#i', $file, $matches))
 408                  {
 409                      if (in_array($matches[2], $supported_extensions))
 410                      {
 411                          $backup_files[(int) $matches[1]] = $file;
 412                      }
 413                  }
 414              }
 415              closedir($dh);
 416          }
 417  
 418          return $backup_files;
 419      }
 420  
 421      /**
 422       * Get supported extensions for backup
 423       *
 424       * @return array List of supported extensions
 425       */
 426  	protected function get_supported_extensions()
 427      {
 428          $extensions = ['sql'];
 429          $available_methods = ['sql.gz' => 'zlib', 'sql.bz2' => 'bz2'];
 430  
 431          foreach ($available_methods as $type => $module)
 432          {
 433              if (!@extension_loaded($module))
 434              {
 435                  continue;
 436              }
 437              $extensions[] = $type;
 438          }
 439  
 440          return $extensions;
 441      }
 442  }
 443  
 444  // get how much space we allow for a chunk of data, very similar to phpMyAdmin's way of doing things ;-) (hey, we only do this for MySQL anyway :P)
 445  function get_usable_memory()
 446  {
 447      $val = trim(@ini_get('memory_limit'));
 448  
 449      if (preg_match('/(\\d+)([mkg]?)/i', $val, $regs))
 450      {
 451          $memory_limit = (int) $regs[1];
 452          switch ($regs[2])
 453          {
 454  
 455              case 'k':
 456              case 'K':
 457                  $memory_limit *= 1024;
 458              break;
 459  
 460              case 'm':
 461              case 'M':
 462                  $memory_limit *= 1048576;
 463              break;
 464  
 465              case 'g':
 466              case 'G':
 467                  $memory_limit *= 1073741824;
 468              break;
 469          }
 470  
 471          // how much memory PHP requires at the start of export (it is really a little less)
 472          if ($memory_limit > 6100000)
 473          {
 474              $memory_limit -= 6100000;
 475          }
 476  
 477          // allow us to consume half of the total memory available
 478          $memory_limit /= 2;
 479      }
 480      else
 481      {
 482          // set the buffer to 1M if we have no clue how much memory PHP will give us :P
 483          $memory_limit = 1048576;
 484      }
 485  
 486      return $memory_limit;
 487  }
 488  
 489  function sanitize_data_mssql($text)
 490  {
 491      $data = preg_split('/[\n\t\r\b\f]/', $text);
 492      preg_match_all('/[\n\t\r\b\f]/', $text, $matches);
 493  
 494      $val = array();
 495  
 496      foreach ($data as $value)
 497      {
 498          if (strlen($value))
 499          {
 500              $val[] = "'" . $value . "'";
 501          }
 502          if (count($matches[0]))
 503          {
 504              $val[] = 'char(' . ord(array_shift($matches[0])) . ')';
 505          }
 506      }
 507  
 508      return implode('+', $val);
 509  }
 510  
 511  function sanitize_data_oracle($text)
 512  {
 513  //    $data = preg_split('/[\0\n\t\r\b\f\'"\/\\\]/', $text);
 514  //    preg_match_all('/[\0\n\t\r\b\f\'"\/\\\]/', $text, $matches);
 515      $data = preg_split('/[\0\b\f\'\/]/', $text);
 516      preg_match_all('/[\0\r\b\f\'\/]/', $text, $matches);
 517  
 518      $val = array();
 519  
 520      foreach ($data as $value)
 521      {
 522          if (strlen($value))
 523          {
 524              $val[] = "'" . $value . "'";
 525          }
 526          if (count($matches[0]))
 527          {
 528              $val[] = 'chr(' . ord(array_shift($matches[0])) . ')';
 529          }
 530      }
 531  
 532      return implode('||', $val);
 533  }
 534  
 535  function sanitize_data_generic($text)
 536  {
 537      $data = preg_split('/[\n\t\r\b\f]/', $text);
 538      preg_match_all('/[\n\t\r\b\f]/', $text, $matches);
 539  
 540      $val = array();
 541  
 542      foreach ($data as $value)
 543      {
 544          if (strlen($value))
 545          {
 546              $val[] = "'" . $value . "'";
 547          }
 548          if (count($matches[0]))
 549          {
 550              $val[] = "'" . array_shift($matches[0]) . "'";
 551          }
 552      }
 553  
 554      return implode('||', $val);
 555  }
 556  
 557  // modified from PHP.net
 558  function fgetd(&$fp, $delim, $read, $seek, $eof, $buffer = 8192)
 559  {
 560      $record = '';
 561      $delim_len = strlen($delim);
 562  
 563      while (!$eof($fp))
 564      {
 565          $pos = strpos($record, $delim);
 566          if ($pos === false)
 567          {
 568              $record .= $read($fp, $buffer);
 569              if ($eof($fp) && ($pos = strpos($record, $delim)) !== false)
 570              {
 571                  $seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR);
 572                  return substr($record, 0, $pos);
 573              }
 574          }
 575          else
 576          {
 577              $seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR);
 578              return substr($record, 0, $pos);
 579          }
 580      }
 581  
 582      return false;
 583  }
 584  
 585  function fgetd_seekless(&$fp, $delim, $read, $seek, $eof, $buffer = 8192)
 586  {
 587      static $array = array();
 588      static $record = '';
 589  
 590      if (!count($array))
 591      {
 592          while (!$eof($fp))
 593          {
 594              if (strpos($record, $delim) !== false)
 595              {
 596                  $array = explode($delim, $record);
 597                  $record = array_pop($array);
 598                  break;
 599              }
 600              else
 601              {
 602                  $record .= $read($fp, $buffer);
 603              }
 604          }
 605          if ($eof($fp) && strpos($record, $delim) !== false)
 606          {
 607              $array = explode($delim, $record);
 608              $record = array_pop($array);
 609          }
 610      }
 611  
 612      if (count($array))
 613      {
 614          return array_shift($array);
 615      }
 616  
 617      return false;
 618  }


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