[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
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 . '&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 . '&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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |