Verzeichnisstruktur phpBB-3.2.0
- Veröffentlicht
- 06.01.2017
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
acp_database.php
001 <?php
002 /**
003 *
004 * This file is part of the phpBB Forum Software package.
005 *
006 * @copyright (c) phpBB Limited <https://www.phpbb.com>
007 * @license GNU General Public License, version 2 (GPL-2.0)
008 *
009 * For full copyright and license information, please see
010 * the docs/CREDITS.txt file.
011 *
012 */
013
014 /**
015 * @ignore
016 */
017 if (!defined('IN_PHPBB'))
018 {
019 exit;
020 }
021
022 class acp_database
023 {
024 var $db_tools;
025 var $u_action;
026
027 function main($id, $mode)
028 {
029 global $cache, $db, $user, $template, $table_prefix, $request;
030 global $phpbb_root_path, $phpbb_container, $phpbb_log;
031
032 $this->db_tools = $phpbb_container->get('dbal.tools');
033
034 $user->add_lang('acp/database');
035
036 $this->tpl_name = 'acp_database';
037 $this->page_title = 'ACP_DATABASE';
038
039 $action = $request->variable('action', '');
040
041 $form_key = 'acp_database';
042 add_form_key($form_key);
043
044 $template->assign_vars(array(
045 'MODE' => $mode
046 ));
047
048 switch ($mode)
049 {
050 case 'backup':
051
052 $this->page_title = 'ACP_BACKUP';
053
054 switch ($action)
055 {
056 case 'download':
057 $type = $request->variable('type', '');
058 $table = array_intersect($this->db_tools->sql_list_tables(), $request->variable('table', array('')));
059 $format = $request->variable('method', '');
060 $where = $request->variable('where', '');
061
062 if (!sizeof($table))
063 {
064 trigger_error($user->lang['TABLE_SELECT_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING);
065 }
066
067 if (!check_form_key($form_key))
068 {
069 trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
070 }
071
072 $store = $download = $structure = $schema_data = false;
073
074 if ($where == 'store_and_download' || $where == 'store')
075 {
076 $store = true;
077 }
078
079 if ($where == 'store_and_download' || $where == 'download')
080 {
081 $download = true;
082 }
083
084 if ($type == 'full' || $type == 'structure')
085 {
086 $structure = true;
087 }
088
089 if ($type == 'full' || $type == 'data')
090 {
091 $schema_data = true;
092 }
093
094 @set_time_limit(1200);
095 @set_time_limit(0);
096
097 $time = time();
098
099 $filename = 'backup_' . $time . '_' . unique_id();
100
101 $extractor = $phpbb_container->get('dbal.extractor');
102 $extractor->init_extractor($format, $filename, $time, $download, $store);
103
104 $extractor->write_start($table_prefix);
105
106 foreach ($table as $table_name)
107 {
108 // Get the table structure
109 if ($structure)
110 {
111 $extractor->write_table($table_name);
112 }
113 else
114 {
115 // We might wanna empty out all that junk :D
116 switch ($db->get_sql_layer())
117 {
118 case 'sqlite3':
119 $extractor->flush('DELETE FROM ' . $table_name . ";\n");
120 break;
121
122 case 'mssql_odbc':
123 case 'mssqlnative':
124 $extractor->flush('TRUNCATE TABLE ' . $table_name . "GO\n");
125 break;
126
127 case 'oracle':
128 $extractor->flush('TRUNCATE TABLE ' . $table_name . "/\n");
129 break;
130
131 default:
132 $extractor->flush('TRUNCATE TABLE ' . $table_name . ";\n");
133 break;
134 }
135 }
136
137 // Data
138 if ($schema_data)
139 {
140 $extractor->write_data($table_name);
141 }
142 }
143
144 $extractor->write_end();
145
146 $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_DB_BACKUP');
147
148 if ($download == true)
149 {
150 exit;
151 }
152
153 trigger_error($user->lang['BACKUP_SUCCESS'] . adm_back_link($this->u_action));
154 break;
155
156 default:
157 $tables = $this->db_tools->sql_list_tables();
158 asort($tables);
159 foreach ($tables as $table_name)
160 {
161 if (strlen($table_prefix) === 0 || stripos($table_name, $table_prefix) === 0)
162 {
163 $template->assign_block_vars('tables', array(
164 'TABLE' => $table_name
165 ));
166 }
167 }
168 unset($tables);
169
170 $template->assign_vars(array(
171 'U_ACTION' => $this->u_action . '&action=download'
172 ));
173
174 $available_methods = array('gzip' => 'zlib', 'bzip2' => 'bz2');
175
176 foreach ($available_methods as $type => $module)
177 {
178 if (!@extension_loaded($module))
179 {
180 continue;
181 }
182
183 $template->assign_block_vars('methods', array(
184 'TYPE' => $type
185 ));
186 }
187
188 $template->assign_block_vars('methods', array(
189 'TYPE' => 'text'
190 ));
191 break;
192 }
193 break;
194
195 case 'restore':
196
197 $this->page_title = 'ACP_RESTORE';
198
199 switch ($action)
200 {
201 case 'submit':
202 $delete = $request->variable('delete', '');
203 $file = $request->variable('file', '');
204 $download = $request->variable('download', '');
205
206 if (!preg_match('#^backup_\d{10,}_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches))
207 {
208 trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
209 }
210
211 $file_name = $phpbb_root_path . 'store/' . $matches[0];
212
213 if (!file_exists($file_name) || !is_readable($file_name))
214 {
215 trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
216 }
217
218 if ($delete)
219 {
220 if (confirm_box(true))
221 {
222 unlink($file_name);
223 $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_DB_DELETE');
224 trigger_error($user->lang['BACKUP_DELETE'] . adm_back_link($this->u_action));
225 }
226 else
227 {
228 confirm_box(false, $user->lang['DELETE_SELECTED_BACKUP'], build_hidden_fields(array('delete' => $delete, 'file' => $file)));
229 }
230 }
231 else if ($download || confirm_box(true))
232 {
233 if ($download)
234 {
235 $name = $matches[0];
236
237 switch ($matches[1])
238 {
239 case 'sql':
240 $mimetype = 'text/x-sql';
241 break;
242 case 'sql.bz2':
243 $mimetype = 'application/x-bzip2';
244 break;
245 case 'sql.gz':
246 $mimetype = 'application/x-gzip';
247 break;
248 }
249
250 header('Cache-Control: private, no-cache');
251 header("Content-Type: $mimetype; name=\"$name\"");
252 header("Content-disposition: attachment; filename=$name");
253
254 @set_time_limit(0);
255
256 $fp = @fopen($file_name, 'rb');
257
258 if ($fp !== false)
259 {
260 while (!feof($fp))
261 {
262 echo fread($fp, 8192);
263 }
264 fclose($fp);
265 }
266
267 flush();
268 exit;
269 }
270
271 switch ($matches[1])
272 {
273 case 'sql':
274 $fp = fopen($file_name, 'rb');
275 $read = 'fread';
276 $seek = 'fseek';
277 $eof = 'feof';
278 $close = 'fclose';
279 $fgetd = 'fgetd';
280 break;
281
282 case 'sql.bz2':
283 $fp = bzopen($file_name, 'r');
284 $read = 'bzread';
285 $seek = '';
286 $eof = 'feof';
287 $close = 'bzclose';
288 $fgetd = 'fgetd_seekless';
289 break;
290
291 case 'sql.gz':
292 $fp = gzopen($file_name, 'rb');
293 $read = 'gzread';
294 $seek = 'gzseek';
295 $eof = 'gzeof';
296 $close = 'gzclose';
297 $fgetd = 'fgetd';
298 break;
299 }
300
301 switch ($db->get_sql_layer())
302 {
303 case 'mysql':
304 case 'mysql4':
305 case 'mysqli':
306 case 'sqlite3':
307 while (($sql = $fgetd($fp, ";\n", $read, $seek, $eof)) !== false)
308 {
309 $db->sql_query($sql);
310 }
311 break;
312
313 case 'postgres':
314 $delim = ";\n";
315 while (($sql = $fgetd($fp, $delim, $read, $seek, $eof)) !== false)
316 {
317 $query = trim($sql);
318
319 if (substr($query, 0, 13) == 'CREATE DOMAIN')
320 {
321 list(, , $domain) = explode(' ', $query);
322 $sql = "SELECT domain_name
323 FROM information_schema.domains
324 WHERE domain_name = '$domain';";
325 $result = $db->sql_query($sql);
326 if (!$db->sql_fetchrow($result))
327 {
328 $db->sql_query($query);
329 }
330 $db->sql_freeresult($result);
331 }
332 else
333 {
334 $db->sql_query($query);
335 }
336
337 if (substr($query, 0, 4) == 'COPY')
338 {
339 while (($sub = $fgetd($fp, "\n", $read, $seek, $eof)) !== '\.')
340 {
341 if ($sub === false)
342 {
343 trigger_error($user->lang['RESTORE_FAILURE'] . adm_back_link($this->u_action), E_USER_WARNING);
344 }
345 pg_put_line($db->get_db_connect_id(), $sub . "\n");
346 }
347 pg_put_line($db->get_db_connect_id(), "\\.\n");
348 pg_end_copy($db->get_db_connect_id());
349 }
350 }
351 break;
352
353 case 'oracle':
354 while (($sql = $fgetd($fp, "/\n", $read, $seek, $eof)) !== false)
355 {
356 $db->sql_query($sql);
357 }
358 break;
359
360 case 'mssql_odbc':
361 case 'mssqlnative':
362 while (($sql = $fgetd($fp, "GO\n", $read, $seek, $eof)) !== false)
363 {
364 $db->sql_query($sql);
365 }
366 break;
367 }
368
369 $close($fp);
370
371 // Purge the cache due to updated data
372 $cache->purge();
373
374 $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_DB_RESTORE');
375 trigger_error($user->lang['RESTORE_SUCCESS'] . adm_back_link($this->u_action));
376 break;
377 }
378 else if (!$download)
379 {
380 confirm_box(false, $user->lang['RESTORE_SELECTED_BACKUP'], build_hidden_fields(array('file' => $file)));
381 }
382
383 default:
384 $methods = array('sql');
385 $available_methods = array('sql.gz' => 'zlib', 'sql.bz2' => 'bz2');
386
387 foreach ($available_methods as $type => $module)
388 {
389 if (!@extension_loaded($module))
390 {
391 continue;
392 }
393 $methods[] = $type;
394 }
395
396 $dir = $phpbb_root_path . 'store/';
397 $dh = @opendir($dir);
398
399 $backup_files = array();
400
401 if ($dh)
402 {
403 while (($file = readdir($dh)) !== false)
404 {
405 if (preg_match('#^backup_(\d{10,})_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches))
406 {
407 if (in_array($matches[2], $methods))
408 {
409 $backup_files[(int) $matches[1]] = $file;
410 }
411 }
412 }
413 closedir($dh);
414 }
415
416 if (!empty($backup_files))
417 {
418 krsort($backup_files);
419
420 foreach ($backup_files as $name => $file)
421 {
422 $template->assign_block_vars('files', array(
423 'FILE' => $file,
424 'NAME' => $user->format_date($name, 'd-m-Y H:i:s', true),
425 'SUPPORTED' => true,
426 ));
427 }
428 }
429
430 $template->assign_vars(array(
431 'U_ACTION' => $this->u_action . '&action=submit'
432 ));
433 break;
434 }
435 break;
436 }
437 }
438 }
439
440 // 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)
441 function get_usable_memory()
442 {
443 $val = trim(@ini_get('memory_limit'));
444
445 if (preg_match('/(\\d+)([mkg]?)/i', $val, $regs))
446 {
447 $memory_limit = (int) $regs[1];
448 switch ($regs[2])
449 {
450
451 case 'k':
452 case 'K':
453 $memory_limit *= 1024;
454 break;
455
456 case 'm':
457 case 'M':
458 $memory_limit *= 1048576;
459 break;
460
461 case 'g':
462 case 'G':
463 $memory_limit *= 1073741824;
464 break;
465 }
466
467 // how much memory PHP requires at the start of export (it is really a little less)
468 if ($memory_limit > 6100000)
469 {
470 $memory_limit -= 6100000;
471 }
472
473 // allow us to consume half of the total memory available
474 $memory_limit /= 2;
475 }
476 else
477 {
478 // set the buffer to 1M if we have no clue how much memory PHP will give us :P
479 $memory_limit = 1048576;
480 }
481
482 return $memory_limit;
483 }
484
485 function sanitize_data_mssql($text)
486 {
487 $data = preg_split('/[\n\t\r\b\f]/', $text);
488 preg_match_all('/[\n\t\r\b\f]/', $text, $matches);
489
490 $val = array();
491
492 foreach ($data as $value)
493 {
494 if (strlen($value))
495 {
496 $val[] = "'" . $value . "'";
497 }
498 if (sizeof($matches[0]))
499 {
500 $val[] = 'char(' . ord(array_shift($matches[0])) . ')';
501 }
502 }
503
504 return implode('+', $val);
505 }
506
507 function sanitize_data_oracle($text)
508 {
509 // $data = preg_split('/[\0\n\t\r\b\f\'"\/\\\]/', $text);
510 // preg_match_all('/[\0\n\t\r\b\f\'"\/\\\]/', $text, $matches);
511 $data = preg_split('/[\0\b\f\'\/]/', $text);
512 preg_match_all('/[\0\r\b\f\'\/]/', $text, $matches);
513
514 $val = array();
515
516 foreach ($data as $value)
517 {
518 if (strlen($value))
519 {
520 $val[] = "'" . $value . "'";
521 }
522 if (sizeof($matches[0]))
523 {
524 $val[] = 'chr(' . ord(array_shift($matches[0])) . ')';
525 }
526 }
527
528 return implode('||', $val);
529 }
530
531 function sanitize_data_generic($text)
532 {
533 $data = preg_split('/[\n\t\r\b\f]/', $text);
534 preg_match_all('/[\n\t\r\b\f]/', $text, $matches);
535
536 $val = array();
537
538 foreach ($data as $value)
539 {
540 if (strlen($value))
541 {
542 $val[] = "'" . $value . "'";
543 }
544 if (sizeof($matches[0]))
545 {
546 $val[] = "'" . array_shift($matches[0]) . "'";
547 }
548 }
549
550 return implode('||', $val);
551 }
552
553 // modified from PHP.net
554 function fgetd(&$fp, $delim, $read, $seek, $eof, $buffer = 8192)
555 {
556 $record = '';
557 $delim_len = strlen($delim);
558
559 while (!$eof($fp))
560 {
561 $pos = strpos($record, $delim);
562 if ($pos === false)
563 {
564 $record .= $read($fp, $buffer);
565 if ($eof($fp) && ($pos = strpos($record, $delim)) !== false)
566 {
567 $seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR);
568 return substr($record, 0, $pos);
569 }
570 }
571 else
572 {
573 $seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR);
574 return substr($record, 0, $pos);
575 }
576 }
577
578 return false;
579 }
580
581 function fgetd_seekless(&$fp, $delim, $read, $seek, $eof, $buffer = 8192)
582 {
583 static $array = array();
584 static $record = '';
585
586 if (!sizeof($array))
587 {
588 while (!$eof($fp))
589 {
590 if (strpos($record, $delim) !== false)
591 {
592 $array = explode($delim, $record);
593 $record = array_pop($array);
594 break;
595 }
596 else
597 {
598 $record .= $read($fp, $buffer);
599 }
600 }
601 if ($eof($fp) && strpos($record, $delim) !== false)
602 {
603 $array = explode($delim, $record);
604 $record = array_pop($array);
605 }
606 }
607
608 if (sizeof($array))
609 {
610 return array_shift($array);
611 }
612
613 return false;
614 }
615