export.lib.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * function for the main export logic
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. if (! defined('PHPMYADMIN')) {
  9. exit;
  10. }
  11. /**
  12. * Sets a session variable upon a possible fatal error during export
  13. *
  14. * @return void
  15. */
  16. function PMA_shutdownDuringExport()
  17. {
  18. $a = error_get_last();
  19. if ($a != null && strpos($a['message'], "execution time")) {
  20. //write in partially downloaded file for future reference of user
  21. print_r($a);
  22. //set session variable to check if there was error while exporting
  23. $_SESSION['pma_export_error'] = $a['message'];
  24. }
  25. }
  26. /**
  27. * Detect ob_gzhandler
  28. *
  29. * @return bool
  30. */
  31. function PMA_isGzHandlerEnabled()
  32. {
  33. return in_array('ob_gzhandler', ob_list_handlers());
  34. }
  35. /**
  36. * Detect whether gzencode is needed; it might not be needed if
  37. * the server is already compressing by itself
  38. *
  39. * @return bool Whether gzencode is needed
  40. */
  41. function PMA_gzencodeNeeded()
  42. {
  43. /*
  44. * We should gzencode only if the function exists
  45. * but we don't want to compress twice, therefore
  46. * gzencode only if transparent compression is not enabled
  47. * and gz compression was not asked via $cfg['OBGzip']
  48. * but transparent compression does not apply when saving to server
  49. */
  50. if (@function_exists('gzencode')
  51. && ((! @ini_get('zlib.output_compression')
  52. && ! PMA_isGzHandlerEnabled())
  53. || $GLOBALS['save_on_server'])
  54. ) {
  55. return true;
  56. } else {
  57. return false;
  58. }
  59. }
  60. /**
  61. * Output handler for all exports, if needed buffering, it stores data into
  62. * $dump_buffer, otherwise it prints them out.
  63. *
  64. * @param string $line the insert statement
  65. *
  66. * @return bool Whether output succeeded
  67. */
  68. function PMA_exportOutputHandler($line)
  69. {
  70. global $time_start, $dump_buffer, $dump_buffer_len, $save_filename;
  71. // Kanji encoding convert feature
  72. if ($GLOBALS['output_kanji_conversion']) {
  73. $line = PMA_Kanji_strConv(
  74. $line,
  75. $GLOBALS['knjenc'],
  76. isset($GLOBALS['xkana']) ? $GLOBALS['xkana'] : ''
  77. );
  78. }
  79. // If we have to buffer data, we will perform everything at once at the end
  80. if ($GLOBALS['buffer_needed']) {
  81. $dump_buffer .= $line;
  82. if ($GLOBALS['onfly_compression']) {
  83. $dump_buffer_len += strlen($line);
  84. if ($dump_buffer_len > $GLOBALS['memory_limit']) {
  85. if ($GLOBALS['output_charset_conversion']) {
  86. $dump_buffer = PMA_convertString(
  87. 'utf-8',
  88. $GLOBALS['charset_of_file'],
  89. $dump_buffer
  90. );
  91. }
  92. if ($GLOBALS['compression'] == 'gzip'
  93. && PMA_gzencodeNeeded()
  94. ) {
  95. // as a gzipped file
  96. // without the optional parameter level because it bugs
  97. $dump_buffer = gzencode($dump_buffer);
  98. }
  99. if ($GLOBALS['save_on_server']) {
  100. $write_result = @fwrite($GLOBALS['file_handle'], $dump_buffer);
  101. if ($write_result != strlen($dump_buffer)) {
  102. $GLOBALS['message'] = PMA_Message::error(
  103. __('Insufficient space to save the file %s.')
  104. );
  105. $GLOBALS['message']->addParam($save_filename);
  106. return false;
  107. }
  108. } else {
  109. echo $dump_buffer;
  110. }
  111. $dump_buffer = '';
  112. $dump_buffer_len = 0;
  113. }
  114. } else {
  115. $time_now = time();
  116. if ($time_start >= $time_now + 30) {
  117. $time_start = $time_now;
  118. header('X-pmaPing: Pong');
  119. } // end if
  120. }
  121. } else {
  122. if ($GLOBALS['asfile']) {
  123. if ($GLOBALS['output_charset_conversion']) {
  124. $line = PMA_convertString(
  125. 'utf-8',
  126. $GLOBALS['charset_of_file'],
  127. $line
  128. );
  129. }
  130. if ($GLOBALS['save_on_server'] && strlen($line) > 0) {
  131. $write_result = @fwrite($GLOBALS['file_handle'], $line);
  132. if (! $write_result || ($write_result != strlen($line))) {
  133. $GLOBALS['message'] = PMA_Message::error(
  134. __('Insufficient space to save the file %s.')
  135. );
  136. $GLOBALS['message']->addParam($save_filename);
  137. return false;
  138. }
  139. $time_now = time();
  140. if ($time_start >= $time_now + 30) {
  141. $time_start = $time_now;
  142. header('X-pmaPing: Pong');
  143. } // end if
  144. } else {
  145. // We export as file - output normally
  146. echo $line;
  147. }
  148. } else {
  149. // We export as html - replace special chars
  150. echo htmlspecialchars($line);
  151. }
  152. }
  153. return true;
  154. } // end of the 'PMA_exportOutputHandler()' function
  155. /**
  156. * Returns HTML containing the footer for a displayed export
  157. *
  158. * @param string $back_button the link for going Back
  159. *
  160. * @return string $html the HTML output
  161. */
  162. function PMA_getHtmlForDisplayedExportFooter($back_button)
  163. {
  164. /**
  165. * Close the html tags and add the footers for on-screen export
  166. */
  167. $html = '</textarea>'
  168. . ' </form>'
  169. // bottom back button
  170. . $back_button
  171. . '</div>'
  172. . '<script type="text/javascript">' . "\n"
  173. . '//<![CDATA[' . "\n"
  174. . 'var $body = $("body");' . "\n"
  175. . '$("#textSQLDUMP")' . "\n"
  176. . '.width($body.width() - 50)' . "\n"
  177. . '.height($body.height() - 100);' . "\n"
  178. . '//]]>' . "\n"
  179. . '</script>' . "\n";
  180. return $html;
  181. }
  182. /**
  183. * Computes the memory limit for export
  184. *
  185. * @return int $memory_limit the memory limit
  186. */
  187. function PMA_getMemoryLimitForExport()
  188. {
  189. $memory_limit = trim(@ini_get('memory_limit'));
  190. $memory_limit_num = (int)substr($memory_limit, 0, -1);
  191. // 2 MB as default
  192. if (empty($memory_limit) || '-1' == $memory_limit) {
  193. $memory_limit = 2 * 1024 * 1024;
  194. } elseif (strtolower(substr($memory_limit, -1)) == 'm') {
  195. $memory_limit = $memory_limit_num * 1024 * 1024;
  196. } elseif (strtolower(substr($memory_limit, -1)) == 'k') {
  197. $memory_limit = $memory_limit_num * 1024;
  198. } elseif (strtolower(substr($memory_limit, -1)) == 'g') {
  199. $memory_limit = $memory_limit_num * 1024 * 1024 * 1024;
  200. } else {
  201. $memory_limit = (int)$memory_limit;
  202. }
  203. // Some of memory is needed for other things and as threshold.
  204. // During export I had allocated (see memory_get_usage function)
  205. // approx 1.2MB so this comes from that.
  206. if ($memory_limit > 1500000) {
  207. $memory_limit -= 1500000;
  208. }
  209. // Some memory is needed for compression, assume 1/3
  210. $memory_limit /= 8;
  211. return $memory_limit;
  212. }
  213. /**
  214. * Return the filename and MIME type for export file
  215. *
  216. * @param string $export_type type of export
  217. * @param string $remember_template whether to remember template
  218. * @param object $export_plugin the export plugin
  219. * @param string $compression compression asked
  220. * @param string $filename_template the filename template
  221. *
  222. * @return array the filename template and mime type
  223. */
  224. function PMA_getExportFilenameAndMimetype(
  225. $export_type, $remember_template, $export_plugin, $compression,
  226. $filename_template
  227. ) {
  228. if ($export_type == 'server') {
  229. if (! empty($remember_template)) {
  230. $GLOBALS['PMA_Config']->setUserValue(
  231. 'pma_server_filename_template',
  232. 'Export/file_template_server',
  233. $filename_template
  234. );
  235. }
  236. } elseif ($export_type == 'database') {
  237. if (! empty($remember_template)) {
  238. $GLOBALS['PMA_Config']->setUserValue(
  239. 'pma_db_filename_template',
  240. 'Export/file_template_database',
  241. $filename_template
  242. );
  243. }
  244. } else {
  245. if (! empty($remember_template)) {
  246. $GLOBALS['PMA_Config']->setUserValue(
  247. 'pma_table_filename_template',
  248. 'Export/file_template_table',
  249. $filename_template
  250. );
  251. }
  252. }
  253. $filename = PMA_Util::expandUserString($filename_template);
  254. // remove dots in filename (coming from either the template or already
  255. // part of the filename) to avoid a remote code execution vulnerability
  256. $filename = PMA_sanitizeFilename($filename, $replaceDots = true);
  257. // Grab basic dump extension and mime type
  258. // Check if the user already added extension;
  259. // get the substring where the extension would be if it was included
  260. $extension_start_pos = strlen($filename) - strlen(
  261. $export_plugin->getProperties()->getExtension()
  262. ) - 1;
  263. $user_extension = substr($filename, $extension_start_pos, strlen($filename));
  264. $required_extension = "." . $export_plugin->getProperties()->getExtension();
  265. if (strtolower($user_extension) != $required_extension) {
  266. $filename .= $required_extension;
  267. }
  268. $mime_type = $export_plugin->getProperties()->getMimeType();
  269. // If dump is going to be compressed, set correct mime_type and add
  270. // compression to extension
  271. if ($compression == 'gzip') {
  272. $filename .= '.gz';
  273. $mime_type = 'application/x-gzip';
  274. } elseif ($compression == 'zip') {
  275. $filename .= '.zip';
  276. $mime_type = 'application/zip';
  277. }
  278. return array($filename, $mime_type);
  279. }
  280. /**
  281. * Open the export file
  282. *
  283. * @param string $filename the export filename
  284. * @param boolean $quick_export whether it's a quick export or not
  285. *
  286. * @return array the full save filename, possible message and the file handle
  287. */
  288. function PMA_openExportFile($filename, $quick_export)
  289. {
  290. $file_handle = null;
  291. $message = '';
  292. $save_filename = PMA_Util::userDir($GLOBALS['cfg']['SaveDir'])
  293. . preg_replace('@[/\\\\]@', '_', $filename);
  294. if (file_exists($save_filename)
  295. && ((! $quick_export && empty($_REQUEST['onserverover']))
  296. || ($quick_export
  297. && $_REQUEST['quick_export_onserverover'] != 'saveitover'))
  298. ) {
  299. $message = PMA_Message::error(
  300. __(
  301. 'File %s already exists on server, '
  302. . 'change filename or check overwrite option.'
  303. )
  304. );
  305. $message->addParam($save_filename);
  306. } elseif (is_file($save_filename) && ! is_writable($save_filename)) {
  307. $message = PMA_Message::error(
  308. __(
  309. 'The web server does not have permission '
  310. . 'to save the file %s.'
  311. )
  312. );
  313. $message->addParam($save_filename);
  314. } elseif (! $file_handle = @fopen($save_filename, 'w')) {
  315. $message = PMA_Message::error(
  316. __(
  317. 'The web server does not have permission '
  318. . 'to save the file %s.'
  319. )
  320. );
  321. $message->addParam($save_filename);
  322. }
  323. return array($save_filename, $message, $file_handle);
  324. }
  325. /**
  326. * Close the export file
  327. *
  328. * @param resource $file_handle the export file handle
  329. * @param string $dump_buffer the current dump buffer
  330. * @param string $save_filename the export filename
  331. *
  332. * @return object $message a message object (or empty string)
  333. */
  334. function PMA_closeExportFile($file_handle, $dump_buffer, $save_filename)
  335. {
  336. $message = '';
  337. $write_result = @fwrite($file_handle, $dump_buffer);
  338. fclose($file_handle);
  339. if (strlen($dump_buffer) > 0
  340. && (! $write_result || ($write_result != strlen($dump_buffer)))
  341. ) {
  342. $message = new PMA_Message(
  343. __('Insufficient space to save the file %s.'),
  344. PMA_Message::ERROR,
  345. $save_filename
  346. );
  347. } else {
  348. $message = new PMA_Message(
  349. __('Dump has been saved to file %s.'),
  350. PMA_Message::SUCCESS,
  351. $save_filename
  352. );
  353. }
  354. return $message;
  355. }
  356. /**
  357. * Compress the export buffer
  358. *
  359. * @param string $dump_buffer the current dump buffer
  360. * @param string $compression the compression mode
  361. * @param string $filename the filename
  362. *
  363. * @return object $message a message object (or empty string)
  364. */
  365. function PMA_compressExport($dump_buffer, $compression, $filename)
  366. {
  367. if ($compression == 'zip' && @function_exists('gzcompress')) {
  368. $zipfile = new ZipFile();
  369. $zipfile->addFile($dump_buffer, substr($filename, 0, -4));
  370. $dump_buffer = $zipfile->file();
  371. } elseif ($compression == 'gzip' && PMA_gzencodeNeeded()) {
  372. // without the optional parameter level because it bugs
  373. $dump_buffer = gzencode($dump_buffer);
  374. }
  375. return $dump_buffer;
  376. }
  377. /**
  378. * Returns HTML containing the header for a displayed export
  379. *
  380. * @param string $export_type the export type
  381. * @param string $db the database name
  382. * @param string $table the table name
  383. *
  384. * @return array the generated HTML and back button
  385. */
  386. function PMA_getHtmlForDisplayedExportHeader($export_type, $db, $table)
  387. {
  388. $html = '<div style="text-align: ' . $GLOBALS['cell_align_left'] . '">';
  389. /**
  390. * Displays a back button with all the $_REQUEST data in the URL
  391. * (store in a variable to also display after the textarea)
  392. */
  393. $back_button = '<p>[ <a href="';
  394. if ($export_type == 'server') {
  395. $back_button .= 'server_export.php?' . PMA_URL_getCommon();
  396. } elseif ($export_type == 'database') {
  397. $back_button .= 'db_export.php?' . PMA_URL_getCommon($db);
  398. } else {
  399. $back_button .= 'tbl_export.php?' . PMA_URL_getCommon($db, $table);
  400. }
  401. // Convert the multiple select elements from an array to a string
  402. if ($export_type == 'server' && isset($_REQUEST['db_select'])) {
  403. $_REQUEST['db_select'] = implode(",", $_REQUEST['db_select']);
  404. } elseif ($export_type == 'database'
  405. && isset($_REQUEST['table_select'])
  406. ) {
  407. $_REQUEST['table_select'] = implode(",", $_REQUEST['table_select']);
  408. }
  409. foreach ($_REQUEST as $name => $value) {
  410. $back_button .= '&amp;' . urlencode($name) . '=' . urlencode($value);
  411. }
  412. $back_button .= '&amp;repopulate=1">' . __('Back') . '</a> ]</p>';
  413. $html .= $back_button
  414. . '<form name="nofunction">'
  415. . '<textarea name="sqldump" cols="50" rows="30" '
  416. . 'id="textSQLDUMP" wrap="OFF">';
  417. return array($html, $back_button);
  418. }
  419. /**
  420. * Export at the server level
  421. *
  422. * @param string $db_select the selected databases to export
  423. * @param string $whatStrucOrData structure or data or both
  424. * @param object $export_plugin the selected export plugin
  425. * @param string $crlf end of line character(s)
  426. * @param string $err_url the URL in case of error
  427. * @param string $export_type the export type
  428. * @param bool $do_relation whether to export relation info
  429. * @param bool $do_comments whether to add comments
  430. * @param bool $do_mime whether to add MIME info
  431. * @param bool $do_dates whether to add dates
  432. *
  433. * @return void
  434. */
  435. function PMA_exportServer(
  436. $db_select, $whatStrucOrData, $export_plugin, $crlf, $err_url,
  437. $export_type, $do_relation, $do_comments, $do_mime, $do_dates
  438. ) {
  439. if (! empty($db_select)) {
  440. $tmp_select = implode($db_select, '|');
  441. $tmp_select = '|' . $tmp_select . '|';
  442. }
  443. // Walk over databases
  444. foreach ($GLOBALS['pma']->databases as $current_db) {
  445. if (isset($tmp_select)
  446. && strpos(' ' . $tmp_select, '|' . $current_db . '|')
  447. ) {
  448. $tables = $GLOBALS['dbi']->getTables($current_db);
  449. PMA_exportDatabase(
  450. $current_db, $tables, $whatStrucOrData, $export_plugin, $crlf,
  451. $err_url, $export_type, $do_relation, $do_comments, $do_mime,
  452. $do_dates
  453. );
  454. }
  455. } // end foreach database
  456. }
  457. /**
  458. * Export at the database level
  459. *
  460. * @param string $db the database to export
  461. * @param array $tables the tables to export
  462. * @param string $whatStrucOrData structure or data or both
  463. * @param object $export_plugin the selected export plugin
  464. * @param string $crlf end of line character(s)
  465. * @param string $err_url the URL in case of error
  466. * @param string $export_type the export type
  467. * @param bool $do_relation whether to export relation info
  468. * @param bool $do_comments whether to add comments
  469. * @param bool $do_mime whether to add MIME info
  470. * @param bool $do_dates whether to add dates
  471. *
  472. * @return void
  473. */
  474. function PMA_exportDatabase(
  475. $db, $tables, $whatStrucOrData, $export_plugin, $crlf, $err_url,
  476. $export_type, $do_relation, $do_comments, $do_mime, $do_dates
  477. ) {
  478. if (! $export_plugin->exportDBHeader($db)) {
  479. return;
  480. }
  481. if (! $export_plugin->exportDBCreate($db)) {
  482. return;
  483. }
  484. if (method_exists($export_plugin, 'exportRoutines')
  485. && strpos($GLOBALS['sql_structure_or_data'], 'structure') !== false
  486. && isset($GLOBALS['sql_procedure_function'])
  487. ) {
  488. $export_plugin->exportRoutines($db);
  489. }
  490. $views = array();
  491. foreach ($tables as $table) {
  492. // if this is a view, collect it for later;
  493. // views must be exported after the tables
  494. $is_view = PMA_Table::isView($db, $table);
  495. if ($is_view) {
  496. $views[] = $table;
  497. }
  498. if ($whatStrucOrData == 'structure'
  499. || $whatStrucOrData == 'structure_and_data'
  500. ) {
  501. // for a view, export a stand-in definition of the table
  502. // to resolve view dependencies
  503. if ($is_view) {
  504. if (isset($GLOBALS['sql_create_view'])) {
  505. if (! $export_plugin->exportStructure(
  506. $db, $table, $crlf, $err_url,
  507. 'stand_in', $export_type,
  508. $do_relation, $do_comments, $do_mime, $do_dates
  509. )) {
  510. break 1;
  511. }
  512. }
  513. } else if (isset($GLOBALS['sql_create_table'])) {
  514. $table_size = $GLOBALS['maxsize'];
  515. // Checking if the maximum table size constrain has been set
  516. // And if that constrain is a valid number or not
  517. if ($table_size !== '' && is_numeric($table_size)) {
  518. // This obtains the current table's size
  519. $query = 'SELECT data_length + index_length
  520. from information_schema.TABLES
  521. WHERE table_schema = "' . $db . '"
  522. AND table_name = "' . $table . '"';
  523. $size = $GLOBALS['dbi']->fetchValue($query);
  524. //Converting the size to MB
  525. $size = ($size / 1024) / 1024;
  526. if ($size > $table_size) {
  527. continue;
  528. }
  529. }
  530. if (! $export_plugin->exportStructure(
  531. $db, $table, $crlf, $err_url,
  532. 'create_table', $export_type,
  533. $do_relation, $do_comments, $do_mime, $do_dates
  534. )) {
  535. break 1;
  536. }
  537. }
  538. }
  539. // if this is a view or a merge table, don't export data
  540. if (($whatStrucOrData == 'data'
  541. || $whatStrucOrData == 'structure_and_data')
  542. && ! ($is_view || PMA_Table::isMerge($db, $table))
  543. ) {
  544. $local_query = 'SELECT * FROM ' . PMA_Util::backquote($db)
  545. . '.' . PMA_Util::backquote($table);
  546. if (! $export_plugin->exportData(
  547. $db, $table, $crlf, $err_url, $local_query
  548. )) {
  549. break 1;
  550. }
  551. }
  552. // now export the triggers (needs to be done after the data because
  553. // triggers can modify already imported tables)
  554. if (isset($GLOBALS['sql_create_trigger']) && ($whatStrucOrData == 'structure'
  555. || $whatStrucOrData == 'structure_and_data')
  556. ) {
  557. if (! $export_plugin->exportStructure(
  558. $db, $table, $crlf, $err_url,
  559. 'triggers', $export_type,
  560. $do_relation, $do_comments, $do_mime, $do_dates
  561. )) {
  562. break 1;
  563. }
  564. }
  565. }
  566. if (isset($GLOBALS['sql_create_view'])) {
  567. foreach ($views as $view) {
  568. // no data export for a view
  569. if ($whatStrucOrData == 'structure'
  570. || $whatStrucOrData == 'structure_and_data'
  571. ) {
  572. if (! $export_plugin->exportStructure(
  573. $db, $view, $crlf, $err_url,
  574. 'create_view', $export_type,
  575. $do_relation, $do_comments, $do_mime, $do_dates
  576. )) {
  577. break 1;
  578. }
  579. }
  580. }
  581. }
  582. if (! $export_plugin->exportDBFooter($db)) {
  583. return;
  584. }
  585. }
  586. /**
  587. * Export at the table level
  588. *
  589. * @param string $db the database to export
  590. * @param string $table the table to export
  591. * @param string $whatStrucOrData structure or data or both
  592. * @param object $export_plugin the selected export plugin
  593. * @param string $crlf end of line character(s)
  594. * @param string $err_url the URL in case of error
  595. * @param string $export_type the export type
  596. * @param bool $do_relation whether to export relation info
  597. * @param bool $do_comments whether to add comments
  598. * @param bool $do_mime whether to add MIME info
  599. * @param bool $do_dates whether to add dates
  600. * @param string $allrows whether "dump all rows" was ticked
  601. * @param string $limit_to upper limit
  602. * @param string $limit_from starting limit
  603. * @param string $sql_query query for which exporting is requested
  604. *
  605. * @return void
  606. */
  607. function PMA_exportTable(
  608. $db, $table, $whatStrucOrData, $export_plugin, $crlf, $err_url,
  609. $export_type, $do_relation, $do_comments, $do_mime, $do_dates,
  610. $allrows, $limit_to, $limit_from, $sql_query
  611. ) {
  612. if (! $export_plugin->exportDBHeader($db)) {
  613. return;
  614. }
  615. if (isset($allrows)
  616. && $allrows == '0'
  617. && $limit_to > 0
  618. && $limit_from >= 0
  619. ) {
  620. $add_query = ' LIMIT '
  621. . (($limit_from > 0) ? $limit_from . ', ' : '')
  622. . $limit_to;
  623. } else {
  624. $add_query = '';
  625. }
  626. $is_view = PMA_Table::isView($db, $table);
  627. if ($whatStrucOrData == 'structure'
  628. || $whatStrucOrData == 'structure_and_data'
  629. ) {
  630. if ($is_view) {
  631. if (isset($GLOBALS['sql_create_view'])) {
  632. if (! $export_plugin->exportStructure(
  633. $db, $table, $crlf, $err_url,
  634. 'create_view', $export_type,
  635. $do_relation, $do_comments, $do_mime, $do_dates
  636. )) {
  637. return;
  638. }
  639. }
  640. } else if (isset($GLOBALS['sql_create_table'])) {
  641. if (! $export_plugin->exportStructure(
  642. $db, $table, $crlf, $err_url,
  643. 'create_table', $export_type,
  644. $do_relation, $do_comments, $do_mime, $do_dates
  645. )) {
  646. return;
  647. }
  648. }
  649. }
  650. // If this is an export of a single view, we have to export data;
  651. // for example, a PDF report
  652. // if it is a merge table, no data is exported
  653. if (($whatStrucOrData == 'data'
  654. || $whatStrucOrData == 'structure_and_data')
  655. && ! PMA_Table::isMerge($db, $table)
  656. ) {
  657. if (! empty($sql_query)) {
  658. // only preg_replace if needed
  659. if (! empty($add_query)) {
  660. // remove trailing semicolon before adding a LIMIT
  661. $sql_query = preg_replace('%;\s*$%', '', $sql_query);
  662. }
  663. $local_query = $sql_query . $add_query;
  664. $GLOBALS['dbi']->selectDb($db);
  665. } else {
  666. $local_query = 'SELECT * FROM ' . PMA_Util::backquote($db)
  667. . '.' . PMA_Util::backquote($table) . $add_query;
  668. }
  669. if (! $export_plugin->exportData(
  670. $db, $table, $crlf, $err_url, $local_query
  671. )) {
  672. return;
  673. }
  674. }
  675. // now export the triggers (needs to be done after the data because
  676. // triggers can modify already imported tables)
  677. if (isset($GLOBALS['sql_create_trigger']) && ($whatStrucOrData == 'structure'
  678. || $whatStrucOrData == 'structure_and_data')
  679. ) {
  680. if (! $export_plugin->exportStructure(
  681. $db, $table, $crlf, $err_url,
  682. 'triggers', $export_type,
  683. $do_relation, $do_comments, $do_mime, $do_dates
  684. )) {
  685. return;
  686. }
  687. }
  688. if (! $export_plugin->exportDBFooter($db)) {
  689. return;
  690. }
  691. }
  692. ?>