ExportController.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <?php
  2. declare(strict_types=1);
  3. namespace PhpMyAdmin\Controllers\Table;
  4. use PhpMyAdmin\Config\PageSettings;
  5. use PhpMyAdmin\Export\Options;
  6. use PhpMyAdmin\Html\Generator;
  7. use PhpMyAdmin\Message;
  8. use PhpMyAdmin\Plugins;
  9. use PhpMyAdmin\Response;
  10. use PhpMyAdmin\SqlParser\Parser;
  11. use PhpMyAdmin\SqlParser\Statements\SelectStatement;
  12. use PhpMyAdmin\SqlParser\Utils\Query;
  13. use PhpMyAdmin\Template;
  14. use PhpMyAdmin\Url;
  15. use PhpMyAdmin\Util;
  16. use function array_merge;
  17. use function implode;
  18. use function is_array;
  19. class ExportController extends AbstractController
  20. {
  21. /** @var Options */
  22. private $export;
  23. /**
  24. * @param Response $response
  25. * @param string $db Database name.
  26. * @param string $table Table name.
  27. */
  28. public function __construct(
  29. $response,
  30. Template $template,
  31. $db,
  32. $table,
  33. Options $export
  34. ) {
  35. parent::__construct($response, $template, $db, $table);
  36. $this->export = $export;
  37. }
  38. public function index(): void
  39. {
  40. global $db, $url_params, $table, $replaces, $cfg, $err_url;
  41. global $sql_query, $where_clause, $num_tables, $unlim_num_rows;
  42. $pageSettings = new PageSettings('Export');
  43. $pageSettingsErrorHtml = $pageSettings->getErrorHTML();
  44. $pageSettingsHtml = $pageSettings->getHTML();
  45. $this->addScriptFiles(['export.js']);
  46. Util::checkParameters(['db', 'table']);
  47. $url_params = ['db' => $db, 'table' => $table];
  48. $err_url = Util::getScriptNameForOption($cfg['DefaultTabTable'], 'table');
  49. $err_url .= Url::getCommon($url_params, '&');
  50. $url_params['goto'] = Url::getFromRoute('/table/export');
  51. $url_params['back'] = Url::getFromRoute('/table/export');
  52. $message = '';
  53. // When we have some query, we need to remove LIMIT from that and possibly
  54. // generate WHERE clause (if we are asked to export specific rows)
  55. if (! empty($sql_query)) {
  56. $parser = new Parser($sql_query);
  57. if (! empty($parser->statements[0])
  58. && ($parser->statements[0] instanceof SelectStatement)
  59. ) {
  60. // Checking if the WHERE clause has to be replaced.
  61. if (! empty($where_clause) && is_array($where_clause)) {
  62. $replaces[] = [
  63. 'WHERE',
  64. 'WHERE (' . implode(') OR (', $where_clause) . ')',
  65. ];
  66. }
  67. // Preparing to remove the LIMIT clause.
  68. $replaces[] = [
  69. 'LIMIT',
  70. '',
  71. ];
  72. // Replacing the clauses.
  73. $sql_query = Query::replaceClauses(
  74. $parser->statements[0],
  75. $parser->list,
  76. $replaces
  77. );
  78. }
  79. $message = Generator::getMessage(Message::success());
  80. }
  81. if (! isset($sql_query)) {
  82. $sql_query = '';
  83. }
  84. if (! isset($num_tables)) {
  85. $num_tables = 0;
  86. }
  87. if (! isset($unlim_num_rows)) {
  88. $unlim_num_rows = 0;
  89. }
  90. $GLOBALS['single_table'] = $_POST['single_table'] ?? $_GET['single_table'] ?? $GLOBALS['single_table'] ?? null;
  91. $exportList = Plugins::getExport('table', isset($GLOBALS['single_table']));
  92. if (empty($exportList)) {
  93. $this->response->addHTML(Message::error(
  94. __('Could not load export plugins, please check your installation!')
  95. )->getDisplay());
  96. return;
  97. }
  98. $exportType = 'table';
  99. $isReturnBackFromRawExport = isset($_POST['export_type']) && $_POST['export_type'] === 'raw';
  100. if (isset($_POST['raw_query']) || $isReturnBackFromRawExport) {
  101. $exportType = 'raw';
  102. }
  103. $options = $this->export->getOptions(
  104. $exportType,
  105. $db,
  106. $table,
  107. $sql_query,
  108. $num_tables,
  109. $unlim_num_rows,
  110. $exportList
  111. );
  112. $this->render('table/export/index', array_merge($options, [
  113. 'export_type' => $exportType,
  114. 'page_settings_error_html' => $pageSettingsErrorHtml,
  115. 'page_settings_html' => $pageSettingsHtml,
  116. 'message' => $message,
  117. ]));
  118. }
  119. public function rows(): void
  120. {
  121. global $active_page, $single_table, $where_clause;
  122. if (isset($_POST['goto']) && (! isset($_POST['rows_to_delete']) || ! is_array($_POST['rows_to_delete']))) {
  123. $this->response->setRequestStatus(false);
  124. $this->response->addJSON('message', __('No row selected.'));
  125. return;
  126. }
  127. // Needed to allow SQL export
  128. $single_table = true;
  129. // As we got the rows to be exported from the
  130. // 'rows_to_delete' checkbox, we use the index of it as the
  131. // indicating WHERE clause. Then we build the array which is used
  132. // for the /table/change script.
  133. $where_clause = [];
  134. if (isset($_POST['rows_to_delete']) && is_array($_POST['rows_to_delete'])) {
  135. foreach ($_POST['rows_to_delete'] as $i => $i_where_clause) {
  136. $where_clause[] = $i_where_clause;
  137. }
  138. }
  139. $active_page = Url::getFromRoute('/table/export');
  140. $this->index();
  141. }
  142. }