[ Index ]

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


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1