Documentation TYPO3 par Ameos |
00001 <?php 00002 /* $Id: export.php,v 2.27.2.1 2005/09/14 17:06:22 lem9 Exp $ */ 00003 // vim: expandtab sw=4 ts=4 sts=4: 00004 00008 require_once('./libraries/grab_globals.lib.php'); 00009 require_once('./libraries/common.lib.php'); 00010 require_once('./libraries/zip.lib.php'); 00011 00012 PMA_checkParameters(array('what')); 00013 00014 // What type of export are we doing? 00015 if ($what == 'excel') { 00016 $type = 'csv'; 00017 } else { 00018 $type = $what; 00019 } 00020 00021 // Get the functions specific to the export type 00022 require('./libraries/export/' . PMA_securePath($type) . '.php'); 00023 00024 // Generate error url 00025 if ($export_type == 'server') { 00026 $err_url = 'server_export.php?' . PMA_generate_common_url(); 00027 } elseif ($export_type == 'database') { 00028 $err_url = 'db_details_export.php?' . PMA_generate_common_url($db); 00029 } else { 00030 $err_url = 'tbl_properties_export.php?' . PMA_generate_common_url($db, $table); 00031 } 00032 00036 @set_time_limit($cfg['ExecTimeLimit']); 00037 00038 // Start with empty buffer 00039 $dump_buffer = ''; 00040 $dump_buffer_len = 0; 00041 00042 // We send fake headers to avoid browser timeout when buffering 00043 $time_start = time(); 00044 00045 00054 function PMA_exportOutputHandler($line) 00055 { 00056 global $time_start, $dump_buffer, $dump_buffer_len, $save_filename; 00057 00058 // Kanji encoding convert feature 00059 if ($GLOBALS['output_kanji_conversion']) { 00060 $line = PMA_kanji_str_conv($line, $GLOBALS['knjenc'], isset($GLOBALS['xkana']) ? $GLOBALS['xkana'] : ''); 00061 } 00062 // If we have to buffer data, we will perform everything at once at the end 00063 if ($GLOBALS['buffer_needed']) { 00064 00065 $dump_buffer .= $line; 00066 if ($GLOBALS['onfly_compression']) { 00067 00068 $dump_buffer_len += strlen($line); 00069 00070 if ($dump_buffer_len > $GLOBALS['memory_limit']) { 00071 if ($GLOBALS['output_charset_conversion']) { 00072 $dump_buffer = PMA_convert_string($GLOBALS['charset'], $GLOBALS['charset_of_file'], $dump_buffer); 00073 } 00074 // as bzipped 00075 if ($GLOBALS['compression'] == 'bzip' && @function_exists('bzcompress')) { 00076 $dump_buffer = bzcompress($dump_buffer); 00077 } 00078 // as a gzipped file 00079 else if ($GLOBALS['compression'] == 'gzip' && @function_exists('gzencode')) { 00080 // without the optional parameter level because it bug 00081 $dump_buffer = gzencode($dump_buffer); 00082 } 00083 if ($GLOBALS['save_on_server']) { 00084 $write_result = @fwrite($GLOBALS['file_handle'], $dump_buffer); 00085 if (!$write_result || ($write_result != strlen($dump_buffer))) { 00086 $GLOBALS['message'] = sprintf($GLOBALS['strNoSpace'], htmlspecialchars($save_filename)); 00087 $GLOBALS['show_error_header'] = TRUE; 00088 return FALSE; 00089 } 00090 } else { 00091 echo $dump_buffer; 00092 } 00093 $dump_buffer = ''; 00094 $dump_buffer_len = 0; 00095 } 00096 } else { 00097 $time_now = time(); 00098 if ($time_start >= $time_now + 30) { 00099 $time_start = $time_now; 00100 header('X-pmaPing: Pong'); 00101 } // end if 00102 } 00103 } else { 00104 if ($GLOBALS['asfile']) { 00105 if ($GLOBALS['save_on_server'] && strlen($line) > 0) { 00106 $write_result = @fwrite($GLOBALS['file_handle'], $line); 00107 if (!$write_result || ($write_result != strlen($line))) { 00108 $GLOBALS['message'] = sprintf($GLOBALS['strNoSpace'], htmlspecialchars($save_filename)); 00109 $GLOBALS['show_error_header'] = TRUE; 00110 return FALSE; 00111 } 00112 $time_now = time(); 00113 if ($time_start >= $time_now + 30) { 00114 $time_start = $time_now; 00115 header('X-pmaPing: Pong'); 00116 } // end if 00117 } else { 00118 // We export as file - output normally 00119 if ($GLOBALS['output_charset_conversion']) { 00120 $line = PMA_convert_string($GLOBALS['charset'], $GLOBALS['charset_of_file'], $line); 00121 } 00122 echo $line; 00123 } 00124 } else { 00125 // We export as html - replace special chars 00126 echo htmlspecialchars($line); 00127 } 00128 } 00129 return TRUE; 00130 } // end of the 'PMA_exportOutputHandler()' function 00131 00132 // Will we save dump on server? 00133 $save_on_server = isset($cfg['SaveDir']) && !empty($cfg['SaveDir']) && !empty($onserver); 00134 00135 // Ensure compressed formats are associated with the download feature 00136 if (empty($asfile)) { 00137 if ($save_on_server) { 00138 $asfile = TRUE; 00139 } elseif (isset($compression) && ($compression == 'zip' | $compression == 'gzip' | $compression == 'bzip')) { 00140 $asfile = TRUE; 00141 } else { 00142 $asfile = FALSE; 00143 } 00144 } else { 00145 $asfile = TRUE; 00146 } 00147 00148 // Defines the default <CR><LF> format. For SQL always use \n as MySQL wants this on all platforms. 00149 if ($what == 'sql') { 00150 $crlf = "\n"; 00151 } else { 00152 $crlf = PMA_whichCrlf(); 00153 } 00154 00155 $output_kanji_conversion = function_exists('PMA_kanji_str_conv') && $type != 'xls'; 00156 00157 // Do we need to convert charset? 00158 $output_charset_conversion = $asfile && 00159 $cfg['AllowAnywhereRecoding'] && $allow_recoding 00160 && isset($charset_of_file) && $charset_of_file != $charset 00161 && $type != 'xls'; 00162 00163 // Set whether we will need buffering 00164 $buffer_needed = isset($compression) && ($compression == 'zip' | $compression == 'gzip' | $compression == 'bzip'); 00165 00166 // Use on fly compression? 00167 $onfly_compression = $GLOBALS['cfg']['CompressOnFly'] && isset($compression) && ($compression == 'gzip' | $compression == 'bzip'); 00168 if ($onfly_compression) { 00169 $memory_limit = trim(@ini_get('memory_limit')); 00170 // 2 MB as default 00171 if (empty($memory_limit)) $memory_limit = 2 * 1024 * 1024; 00172 00173 if (strtolower(substr($memory_limit, -1)) == 'm') $memory_limit = (int)substr($memory_limit, 0, -1) * 1024 * 1024; 00174 elseif (strtolower(substr($memory_limit, -1)) == 'k') $memory_limit = (int)substr($memory_limit, 0, -1) * 1024; 00175 elseif (strtolower(substr($memory_limit, -1)) == 'g') $memory_limit = (int)substr($memory_limit, 0, -1) * 1024 * 1024 * 1024; 00176 else $memory_limit = (int)$memory_limit; 00177 00178 // Some of memory is needed for other thins and as treshold. 00179 // Nijel: During export I had allocated (see memory_get_usage function) 00180 // approx 1.2MB so this comes from that. 00181 if ($memory_limit > 1500000) $memory_limit -= 1500000; 00182 00183 // Some memory is needed for compression, assume 1/3 00184 $memory_limit *= 2/3; 00185 } 00186 00187 // Generate filename and mime type if needed 00188 if ($asfile) { 00189 $pma_uri_parts = parse_url($cfg['PmaAbsoluteUri']); 00190 if ($export_type == 'server') { 00191 if (isset($remember_template)) { 00192 setcookie('pma_server_filename_template', $filename_template , 0, $GLOBALS['cookie_path'], '' , $GLOBALS['is_https']); 00193 } 00194 $filename = str_replace('__SERVER__', $GLOBALS['cfg']['Server']['host'], strftime($filename_template)); 00195 } elseif ($export_type == 'database') { 00196 if (isset($remember_template)) { 00197 setcookie('pma_db_filename_template', $filename_template , 0, $GLOBALS['cookie_path'], '' , $GLOBALS['is_https']); 00198 } 00199 $filename = str_replace('__DB__', $db, str_replace('__SERVER__', $GLOBALS['cfg']['Server']['host'], strftime($filename_template))); 00200 } else { 00201 if (isset($remember_template)) { 00202 setcookie('pma_table_filename_template', $filename_template , 0, $GLOBALS['cookie_path'], '' , $GLOBALS['is_https']); 00203 } 00204 $filename = str_replace('__TABLE__', $table, str_replace('__DB__', $db, str_replace('__SERVER__', $GLOBALS['cfg']['Server']['host'], strftime($filename_template)))); 00205 } 00206 00207 // convert filename to iso-8859-1, it is safer 00208 if (!(isset($cfg['AllowAnywhereRecoding']) && $cfg['AllowAnywhereRecoding'] && $allow_recoding)) { 00209 $filename = PMA_convert_string($charset, 'iso-8859-1', $filename); 00210 } else { 00211 $filename = PMA_convert_string($convcharset, 'iso-8859-1', $filename); 00212 } 00213 00214 // Generate basic dump extension 00215 if ($type == 'csv') { 00216 $filename .= '.csv'; 00217 $mime_type = 'text/comma-separated-values'; 00218 } else if ($type == 'htmlexcel') { 00219 $filename .= '.xls'; 00220 $mime_type = 'application/vnd.ms-excel'; 00221 } else if ($type == 'htmlword') { 00222 $filename .= '.doc'; 00223 $mime_type = 'application/vnd.ms-word'; 00224 } else if ($type == 'xls') { 00225 $filename .= '.xls'; 00226 $mime_type = 'application/vnd.ms-excel'; 00227 } else if ($type == 'xml') { 00228 $filename .= '.xml'; 00229 $mime_type = 'text/xml'; 00230 } else if ($type == 'latex') { 00231 $filename .= '.tex'; 00232 $mime_type = 'application/x-tex'; 00233 } else { 00234 $filename .= '.sql'; 00235 // text/x-sql is correct MIME type, however safari ignores further 00236 // Content-Disposition header, so we must force it to download it this 00237 // way... 00238 $mime_type = PMA_USR_BROWSER_AGENT == 'SAFARI' 00239 ? 'application/octet-stream' 00240 : 'text/x-sql'; 00241 } 00242 00243 // If dump is going to be compressed, set correct encoding or mime_type and add 00244 // compression to extension 00245 $content_encoding = ''; 00246 if (isset($compression) && $compression == 'bzip') { 00247 $filename .= '.bz2'; 00248 // browsers don't like this: 00249 //$content_encoding = 'x-bzip2'; 00250 $mime_type = 'application/x-bzip2'; 00251 } else if (isset($compression) && $compression == 'gzip') { 00252 $filename .= '.gz'; 00253 // Needed to avoid recompression by server modules like mod_gzip. 00254 // It seems necessary to check about zlib.output_compression 00255 // to avoid compressing twice 00256 if (!@ini_get('zlib.output_compression')) { 00257 $content_encoding = 'x-gzip'; 00258 $mime_type = 'application/x-gzip'; 00259 } 00260 } else if (isset($compression) && $compression == 'zip') { 00261 $filename .= '.zip'; 00262 $mime_type = 'application/zip'; 00263 } 00264 } 00265 00266 // Open file on server if needed 00267 if ($save_on_server) { 00268 if (substr($cfg['SaveDir'], -1) != '/') { 00269 $cfg['SaveDir'] .= '/'; 00270 } 00271 $save_filename = $cfg['SaveDir'] . preg_replace('@[/\\\\]@','_',$filename); 00272 unset($message); 00273 if (file_exists($save_filename) && empty($onserverover)) { 00274 $message = sprintf($strFileAlreadyExists, htmlspecialchars($save_filename)); 00275 $GLOBALS['show_error_header'] = TRUE; 00276 } else { 00277 if (is_file($save_filename) && !is_writable($save_filename)) { 00278 $message = sprintf($strNoPermission, htmlspecialchars($save_filename)); 00279 $GLOBALS['show_error_header'] = TRUE; 00280 } else { 00281 if (!$file_handle = @fopen($save_filename, 'w')) { 00282 $message = sprintf($strNoPermission, htmlspecialchars($save_filename)); 00283 $GLOBALS['show_error_header'] = TRUE; 00284 } 00285 } 00286 } 00287 if (isset($message)) { 00288 $js_to_run = 'functions.js'; 00289 require_once('./header.inc.php'); 00290 if ($export_type == 'server') { 00291 $active_page = 'server_export.php'; 00292 require('./server_export.php'); 00293 } elseif ($export_type == 'database') { 00294 $active_page = 'db_details_export.php'; 00295 require('./db_details_export.php'); 00296 } else { 00297 $active_page = 'tbl_properties_export.php'; 00298 require('./tbl_properties_export.php'); 00299 } 00300 exit(); 00301 } 00302 } 00303 00308 if (!$save_on_server) { 00309 if ($asfile ) { 00310 // Download 00311 if (!empty($content_encoding)) { 00312 header('Content-Encoding: ' . $content_encoding); 00313 } 00314 header('Content-Type: ' . $mime_type); 00315 header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT'); 00316 // lem9: Tested behavior of 00317 // IE 5.50.4807.2300 00318 // IE 6.0.2800.1106 (small glitch, asks twice when I click Open) 00319 // IE 6.0.2900.2180 00320 // Firefox 1.0.6 00321 // in http and https 00322 header('Content-Disposition: attachment; filename="' . $filename . '"'); 00323 if (PMA_USR_BROWSER_AGENT == 'IE') { 00324 header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 00325 header('Pragma: public'); 00326 } else { 00327 header('Pragma: no-cache'); 00328 } 00329 } else { 00330 // HTML 00331 $backup_cfgServer = $cfg['Server']; 00332 require_once('./header.inc.php'); 00333 $cfg['Server'] = $backup_cfgServer; 00334 unset($backup_cfgServer); 00335 echo "\n" . '<div align="' . $cell_align_left . '">' . "\n"; 00336 //echo ' <pre>' . "\n"; 00337 echo ' <form name="nofunction">' . "\n" 00338 // remove auto-select for now: there is no way to select 00339 // only a part of the text; anyway, it should obey 00340 // $cfg['TextareaAutoSelect'] 00341 //. ' <textarea name="sqldump" cols="50" rows="30" onclick="this.select();" id="textSQLDUMP" wrap="OFF">' . "\n"; 00342 . ' <textarea name="sqldump" cols="50" rows="30" id="textSQLDUMP" wrap="OFF">' . "\n"; 00343 } // end download 00344 } 00345 00346 // Check if we have something to export 00347 if ($export_type == 'database') { 00348 $tables = PMA_DBI_get_tables($db); 00349 $num_tables = count($tables); 00350 if ($num_tables == 0) { 00351 $message = $strNoTablesFound; 00352 $js_to_run = 'functions.js'; 00353 require_once('./header.inc.php'); 00354 if ($export_type == 'server') { 00355 $active_page = 'server_export.php'; 00356 require('./server_export.php'); 00357 } elseif ($export_type == 'database') { 00358 $active_page = 'db_details_export.php'; 00359 require('./db_details_export.php'); 00360 } else { 00361 $active_page = 'tbl_properties_export.php'; 00362 require('./tbl_properties_export.php'); 00363 } 00364 exit(); 00365 } 00366 } 00367 00368 // Fake loop just to allow skip of remain of this code by break, I'd really 00369 // need exceptions here :-) 00370 do { 00371 00372 // Add possibly some comments to export 00373 if (!PMA_exportHeader()) break; 00374 00375 // Will we need relation & co. setup? 00376 $do_relation = isset($GLOBALS[$what . '_relation']); 00377 $do_comments = isset($GLOBALS[$what . '_comments']); 00378 $do_mime = isset($GLOBALS[$what . '_mime']); 00379 if ($do_relation || $do_comments || $do_mime) { 00380 require_once('./libraries/relation.lib.php'); 00381 $cfgRelation = PMA_getRelationsParam(); 00382 } 00383 if ($do_mime) { 00384 require_once('./libraries/transformations.lib.php'); 00385 } 00386 00387 // Include dates in export? 00388 $do_dates = isset($GLOBALS[$what . '_dates']); 00389 00393 // Gets the number of tables if a dump of a database has been required 00394 if ($export_type == 'server') { 00398 if ($server > 0 && empty($dblist)) { 00399 PMA_availableDatabases(); 00400 } 00401 00402 if (isset($db_select)) { 00403 $tmp_select = implode($db_select, '|'); 00404 $tmp_select = '|' . $tmp_select . '|'; 00405 } 00406 // Walk over databases 00407 foreach ($dblist AS $current_db) { 00408 if ((isset($tmp_select) && strpos(' ' . $tmp_select, '|' . $current_db . '|')) 00409 || !isset($tmp_select)) { 00410 if (!PMA_exportDBHeader($current_db)) 00411 break 2; 00412 if (!PMA_exportDBCreate($current_db)) 00413 break 2; 00414 $tables = PMA_DBI_get_tables($current_db); 00415 foreach ($tables as $table) { 00416 $local_query = 'SELECT * FROM ' . PMA_backquote($current_db) . '.' . PMA_backquote($table); 00417 if (isset($GLOBALS[$what . '_structure'])) { 00418 if (!PMA_exportStructure($current_db, $table, $crlf, $err_url, $do_relation, $do_comments, $do_mime, $do_dates)) 00419 break 3; 00420 } 00421 if (isset($GLOBALS[$what . '_data'])) { 00422 if (!PMA_exportData($current_db, $table, $crlf, $err_url, $local_query)) 00423 break 3; 00424 } 00425 } 00426 if (!PMA_exportDBFooter($current_db)) 00427 break 2; 00428 } 00429 } 00430 } elseif ($export_type == 'database') { 00431 if (!PMA_exportDBHeader($db)) 00432 break; 00433 00434 if (isset($table_select)) { 00435 $tmp_select = implode($table_select, '|'); 00436 $tmp_select = '|' . $tmp_select . '|'; 00437 } 00438 $i = 0; 00439 foreach ($tables as $table) { 00440 $local_query = 'SELECT * FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table); 00441 if ((isset($tmp_select) && strpos(' ' . $tmp_select, '|' . $table . '|')) 00442 || !isset($tmp_select)) { 00443 00444 if (isset($GLOBALS[$what . '_structure'])) { 00445 if (!PMA_exportStructure($db, $table, $crlf, $err_url, $do_relation, $do_comments, $do_mime, $do_dates)) 00446 break 2; 00447 } 00448 if (isset($GLOBALS[$what . '_data'])) { 00449 if (!PMA_exportData($db, $table, $crlf, $err_url, $local_query)) 00450 break 2; 00451 } 00452 } 00453 } 00454 if (!PMA_exportDBFooter($db)) 00455 break; 00456 } else { 00457 if (!PMA_exportDBHeader($db)) 00458 break; 00459 // We export just one table 00460 00461 if ($limit_to > 0 && $limit_from >= 0) { 00462 $add_query = ' LIMIT ' 00463 . (($limit_from > 0) ? $limit_from . ', ' : '') 00464 . $limit_to; 00465 } else { 00466 $add_query = ''; 00467 } 00468 00469 if (!empty($sql_query)) { 00470 $local_query = $sql_query . $add_query; 00471 PMA_DBI_select_db($db); 00472 } else { 00473 $local_query = 'SELECT * FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table) . $add_query; 00474 } 00475 00476 if (isset($GLOBALS[$what . '_structure'])) { 00477 if (!PMA_exportStructure($db, $table, $crlf, $err_url, $do_relation, $do_comments, $do_mime, $do_dates)) 00478 break; 00479 } 00480 if (isset($GLOBALS[$what . '_data'])) { 00481 if (!PMA_exportData($db, $table, $crlf, $err_url, $local_query)) 00482 break; 00483 } 00484 if (!PMA_exportDBFooter($db)) 00485 break; 00486 } 00487 if (!PMA_exportFooter()) break; 00488 00489 } while (FALSE); 00490 // End of fake loop 00491 00492 if ($save_on_server && isset($message)) { 00493 $js_to_run = 'functions.js'; 00494 require_once('./header.inc.php'); 00495 if ($export_type == 'server') { 00496 $active_page = 'server_export.php'; 00497 require('./server_export.php'); 00498 } elseif ($export_type == 'database') { 00499 $active_page = 'db_details_export.php'; 00500 require('./db_details_export.php'); 00501 } else { 00502 $active_page = 'tbl_properties_export.php'; 00503 require('./tbl_properties_export.php'); 00504 } 00505 exit(); 00506 } 00507 00511 if (!empty($asfile)) { 00512 // Convert the charset if required. 00513 if ($output_charset_conversion) { 00514 $dump_buffer = PMA_convert_string($GLOBALS['charset'], $GLOBALS['charset_of_file'], $dump_buffer); 00515 } 00516 00517 // Do the compression 00518 // 1. as a gzipped file 00519 if (isset($compression) && $compression == 'zip') { 00520 if (@function_exists('gzcompress')) { 00521 $zipfile = new zipfile(); 00522 $zipfile -> addFile($dump_buffer, substr($filename, 0, -4)); 00523 $dump_buffer = $zipfile -> file(); 00524 } 00525 } 00526 // 2. as a bzipped file 00527 else if (isset($compression) && $compression == 'bzip') { 00528 if (@function_exists('bzcompress')) { 00529 $dump_buffer = bzcompress($dump_buffer); 00530 if ($dump_buffer === -8) { 00531 require_once('./header.inc.php'); 00532 echo sprintf($strBzError, '<a href="http://bugs.php.net/bug.php?id=17300" target="_blank">17300</a>'); 00533 require_once('./footer.inc.php'); 00534 } 00535 } 00536 } 00537 // 3. as a gzipped file 00538 else if (isset($compression) && $compression == 'gzip') { 00539 if (@function_exists('gzencode')) { 00540 // without the optional parameter level because it bug 00541 $dump_buffer = gzencode($dump_buffer); 00542 } 00543 } 00544 00545 /* If ve saved on server, we have to close file now */ 00546 if ($save_on_server) { 00547 $write_result = @fwrite($file_handle, $dump_buffer); 00548 fclose($file_handle); 00549 if (strlen($dump_buffer) !=0 && (!$write_result || ($write_result != strlen($dump_buffer)))) { 00550 $message = sprintf($strNoSpace, htmlspecialchars($save_filename)); 00551 } else { 00552 $message = sprintf($strDumpSaved, htmlspecialchars($save_filename)); 00553 } 00554 00555 $js_to_run = 'functions.js'; 00556 require_once('./header.inc.php'); 00557 if ($export_type == 'server') { 00558 $active_page = 'server_export.php'; 00559 require_once('./server_export.php'); 00560 } elseif ($export_type == 'database') { 00561 $active_page = 'db_details_export.php'; 00562 require_once('./db_details_export.php'); 00563 } else { 00564 $active_page = 'tbl_properties_export.php'; 00565 require_once('./tbl_properties_export.php'); 00566 } 00567 exit(); 00568 } else { 00569 echo $dump_buffer; 00570 } 00571 } 00575 else { 00579 //echo ' </pre>' . "\n"; 00580 echo '</textarea>' . "\n" 00581 . ' </form>' . "\n"; 00582 echo '</div>' . "\n"; 00583 echo "\n"; 00584 ?><script language="JavaScript" type="text/javascript"> 00585 <!-- 00586 var bodyWidth=null; var bodyHeight=null; 00587 if (document.getElementById('textSQLDUMP')) { 00588 bodyWidth = self.innerWidth; 00589 bodyHeight = self.innerHeight; 00590 if(!bodyWidth && !bodyHeight){ 00591 if (document.compatMode && document.compatMode == "BackCompat") { 00592 bodyWidth = document.body.clientWidth; 00593 bodyHeight = document.body.clientHeight; 00594 } else if (document.compatMode && document.compatMode == "CSS1Compat") { 00595 bodyWidth = document.documentElement.clientWidth; 00596 bodyHeight = document.documentElement.clientHeight; 00597 } 00598 } 00599 document.getElementById('textSQLDUMP').style.width=(bodyWidth-50) + 'px'; 00600 document.getElementById('textSQLDUMP').style.height=(bodyHeight-100) + 'px'; 00601 } 00602 //--> 00603 </script> 00604 <?php 00605 require_once('./footer.inc.php'); 00606 } // end if 00607 ?>