[ Index ]

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


Generated: Tue Apr 7 19:42:26 2020 Cross-referenced by PHPXref 0.7.1