'sql', 'copy' => 'sql', 'csv' => 'csv', 'tab' => 'txt', 'html' => 'html', 'xml' => 'xml', ]; public $controller_title = 'strexport'; /** * Default method to render the controller according to the action parameter. */ public function render() { set_time_limit(0); // if (!isset($_REQUEST['table']) && !isset($_REQUEST['query'])) // What must we do in this case? Maybe redirect to the homepage? $format = 'N/A'; // force behavior to assume there is no pg_dump in the system $forcemimic = isset($_REQUEST['forcemimic']) ? $_REQUEST['forcemimic'] : false; // If format is set, then perform the export if (!isset($_REQUEST['what'])) { return $this->doDefault(); } $this->prtrace("REQUEST['what']", $_REQUEST['what']); // Include application functions $this->setNoOutput(true); $clean = false; $oids = false; switch ($_REQUEST['what']) { case 'dataonly': // Check to see if they have pg_dump set up and if they do, use that // instead of custom dump code if (!$forcemimic && $this->misc->isDumpEnabled() && ('copy' == $_REQUEST['d_format'] || 'sql' == $_REQUEST['d_format'])) { $this->prtrace('DUMP ENABLED, d_format is', $_REQUEST['d_format']); $dbexport_controller = new \PHPPgAdmin\Controller\DbexportController($this->getContainer()); return $dbexport_controller->render(); } $this->prtrace('d_format is', $_REQUEST['d_format'], 'd_oids is', isset($_REQUEST['d_oids'])); $format = $_REQUEST['d_format']; $oids = isset($_REQUEST['d_oids']); break; case 'structureonly': // Check to see if they have pg_dump set up and if they do, use that // instead of custom dump code if (!$forcemimic && $this->misc->isDumpEnabled()) { $dbexport_controller = new \PHPPgAdmin\Controller\DbexportController($this->getContainer()); return $dbexport_controller->render(); } $clean = isset($_REQUEST['s_clean']); break; case 'structureanddata': // Check to see if they have pg_dump set up and if they do, use that // instead of custom dump code if (!$forcemimic && $this->misc->isDumpEnabled()) { $dbexport_controller = new \PHPPgAdmin\Controller\DbexportController($this->getContainer()); return $dbexport_controller->render(); } $format = $_REQUEST['sd_format']; $clean = isset($_REQUEST['sd_clean']); $oids = isset($_REQUEST['sd_oids']); break; } $cleanprefix = $clean ? '' : '-- '; return $this->mimicDumpFeature($format, $cleanprefix, $oids); } protected function mimicDumpFeature($format, $cleanprefix, $oids) { $data = $this->misc->getDatabaseAccessor(); set_time_limit(0); // if (!isset($_REQUEST['table']) && !isset($_REQUEST['query'])) // What must we do in this case? Maybe redirect to the homepage? // If format is set, then perform the export if (!isset($_REQUEST['what'])) { return $this->doDefault(); } $this->prtrace("REQUEST['what']", $_REQUEST['what']); // Include application functions $this->setNoOutput(true); $response = $this->_getResponse($format); $this->coalesceArr($_REQUEST, 'query', ''); $_REQUEST['query'] = trim(urldecode($_REQUEST['query'])); // Set the schema search path if (isset($_REQUEST['search_path'])) { $data->setSearchPath(array_map('trim', explode(',', $_REQUEST['search_path']))); } elseif (isset($_REQUEST['schema'])) { $data->setSearchPath($_REQUEST['schema']); } $subject = $this->coalesceArr($_REQUEST, 'subject', 'table')['subject']; $object = $this->coalesceArr($_REQUEST, $subject)[$subject]; // Set up the dump transaction $status = $data->beginDump(); $this->prtrace('subject', $subject); $this->prtrace('object', $object); $tabledefprefix = ''; $tabledefsuffix = ''; // If the dump is not dataonly then dump the structure prefix if ('dataonly' != $_REQUEST['what']) { $tabledefprefix = $data->getTableDefPrefix($object, $cleanprefix); $this->prtrace('tabledefprefix', $tabledefprefix); echo $tabledefprefix; } // If the dump is not structureonly then dump the actual data if ('structureonly' != $_REQUEST['what']) { // Get database encoding //$dbEncoding = $data->getDatabaseEncoding(); // Set fetch mode to NUM so that duplicate field names are properly returned $data->conn->setFetchMode(\ADODB_FETCH_NUM); // Execute the query, if set, otherwise grab all rows from the table $rs = $this->_getRS($data, $object, $oids); $response = $this->pickFormat($data, $object, $oids, $rs, $format, $response); } if ('dataonly' != $_REQUEST['what']) { $data->conn->setFetchMode(\ADODB_FETCH_ASSOC); $tabledefsuffix = $data->getTableDefSuffix($object); $this->prtrace('tabledefsuffix', $tabledefsuffix); echo $tabledefsuffix; } // Finish the dump transaction $status = $data->endDump(); return $response; } private function _getRS($data, $object, $oids) { if ($object) { return $data->dumpRelation($object, $oids); } $this->prtrace('$_REQUEST[query]', $_REQUEST['query']); return $data->conn->Execute($_REQUEST['query']); } private function _getResponse($format) { $response = $this ->container ->responseobj; // Make it do a download, if necessary if ('download' !== $_REQUEST['output']) { return $response ->withHeader('Content-type', 'text/plain'); } // Set headers. MSIE is totally broken for SSL downloading, so // we need to have it download in-place as plain text if (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') && isset($_SERVER['HTTPS'])) { return $response ->withHeader('Content-type', 'text/plain'); } $response = $response ->withHeader('Content-type', 'application/download'); $ext = 'txt'; if (isset($this->extensions[$format])) { $ext = $this->extensions[$format]; } return $response ->withHeader('Content-Disposition', 'attachment; filename=dump.'.$ext); } private function pickFormat($data, $object, $oids, $rs, $format, $response) { if ('copy' == $format) { $this->_mimicCopy($data, $object, $oids, $rs); } elseif ('html' == $format) { $response = $response ->withHeader('Content-type', 'text/html'); $this->_mimicHtml($data, $object, $oids, $rs); } elseif ('xml' == $format) { $response = $response ->withHeader('Content-type', 'application/xml'); $this->_mimicXml($data, $object, $oids, $rs); } elseif ('sql' == $format) { $this->_mimicSQL($data, $object, $oids, $rs); } $this->_csvOrTab($data, $object, $oids, $rs, $format); return $response; } public function doDefault($msg = '') { if (!isset($_REQUEST['query']) || empty($_REQUEST['query'])) { $_REQUEST['query'] = $_SESSION['sqlquery']; } $this->printHeader(); $this->printBody(); $this->printTrail(isset($_REQUEST['subject']) ? $_REQUEST['subject'] : 'database'); $this->printTitle($this->lang['strexport']); if (isset($msg)) { $this->printMsg($msg); } echo '
'.PHP_EOL; echo ''.PHP_EOL; echo "'; echo '
{$this->lang['strformat']}:
'.PHP_EOL; echo "

{$this->lang['stroptions']}

".PHP_EOL; echo "

".PHP_EOL; echo "

".PHP_EOL; echo '

'.PHP_EOL; echo ''.PHP_EOL; if (isset($_REQUEST['table'])) { echo ''.PHP_EOL; echo ''.PHP_EOL; } else { echo ''.PHP_EOL; } $this->prtrace('$_REQUEST[query]', $_REQUEST['query'], htmlspecialchars(urlencode($_REQUEST['query']))); $this->prtrace('$_SESSION[sqlquery]', $_SESSION['sqlquery'], htmlspecialchars(urlencode($_SESSION['sqlquery']))); echo ''.PHP_EOL; if (isset($_REQUEST['search_path'])) { echo ''.PHP_EOL; } echo $this->misc->form; echo "lang['strexport']}\" />

".PHP_EOL; echo '
'.PHP_EOL; $this->printFooter(); } private function _mimicCopy($data, $object, $oids, $rs) { $data->fieldClean($object); echo "COPY \"{$_REQUEST['table']}\""; if ($oids) { echo ' WITH OIDS'; } echo " FROM stdin;\n"; while (!$rs->EOF) { $first = true; //while (list($k, $v) = each($rs->fields)) { foreach ($rs->fields as $k => $v) { // Escape value $v = $data->escapeBytea($v); // We add an extra escaping slash onto octal encoded characters $v = preg_replace('/\\\\([0-7]{3})/', '\\\\\1', $v); if ($first) { echo (is_null($v)) ? '\\N' : $v; $first = false; } else { echo "\t", (is_null($v)) ? '\\N' : $v; } } echo PHP_EOL; $rs->moveNext(); } echo "\\.\n"; } private function _mimicHtml($data, $object, $oids, $rs) { echo "\r\n"; echo "\r\n"; echo "\r\n"; echo "\t\r\n"; echo "\t\r\n"; echo "\r\n"; echo "\r\n"; echo "\r\n"; echo "\t\r\n"; if (!$rs->EOF) { // Output header row $j = 0; foreach ($rs->fields as $k => $v) { $finfo = $rs->fetchField($j++); if ($finfo->name == $data->id && !$oids) { continue; } echo "\t\t\r\n"; } } echo "\t\r\n"; while (!$rs->EOF) { echo "\t\r\n"; $j = 0; foreach ($rs->fields as $k => $v) { $finfo = $rs->fetchField($j++); if ($finfo->name == $data->id && !$oids) { continue; } echo "\t\t\r\n"; } echo "\t\r\n"; $rs->moveNext(); } echo "
", $this->misc->printVal($finfo->name, 'verbatim'), "
", $this->misc->printVal($v, 'verbatim', $finfo->type), "
\r\n"; echo "\r\n"; echo "\r\n"; } private function _mimicXml($data, $object, $oids, $rs) { echo ''.PHP_EOL; echo ''.PHP_EOL; if (!$rs->EOF) { // Output header row $j = 0; echo "\t
".PHP_EOL; foreach ($rs->fields as $k => $v) { $finfo = $rs->fetchField($j++); $name = htmlspecialchars($finfo->name); $type = htmlspecialchars($finfo->type); echo "\t\t".PHP_EOL; } echo "\t
".PHP_EOL; } echo "\t".PHP_EOL; while (!$rs->EOF) { $j = 0; echo "\t\t".PHP_EOL; foreach ($rs->fields as $k => $v) { $finfo = $rs->fetchField($j++); $name = htmlspecialchars($finfo->name); if (!is_null($v)) { $v = htmlspecialchars($v); } echo "\t\t\t{$v}".PHP_EOL; } echo "\t\t".PHP_EOL; $rs->moveNext(); } echo "\t".PHP_EOL; echo '
'.PHP_EOL; } private function _mimicSQL($data, $object, $oids, $rs) { $data->fieldClean($object); $values = ''; while (!$rs->EOF) { echo "INSERT INTO \"{$object}\" ("; $first = true; $j = 0; foreach ($rs->fields as $k => $v) { $finfo = $rs->fetchField($j++); $k = $finfo->name; // SQL (INSERT) format cannot handle oids // if ($k == $data->id) continue; // Output field $data->fieldClean($k); if ($first) { echo "\"{$k}\""; } else { echo ", \"{$k}\""; } if (!is_null($v)) { // Output value // addCSlashes converts all weird ASCII characters to octal representation, // EXCEPT the 'special' ones like \r \n \t, etc. $v = addcslashes($v, "\0..\37\177..\377"); // We add an extra escaping slash onto octal encoded characters $v = preg_replace('/\\\\([0-7]{3})/', '\\\1', $v); // Finally, escape all apostrophes $v = str_replace("'", "''", $v); } if ($first) { $values = (is_null($v) ? 'NULL' : "'{$v}'"); $first = false; } else { $values .= ', '.((is_null($v) ? 'NULL' : "'{$v}'")); } } echo ") VALUES ({$values});\n"; $rs->moveNext(); } } private function _csvOrTab($data, $object, $oids, $rs, $format) { switch ($format) { case 'tab': $sep = "\t"; break; case 'csv': default: $sep = ','; break; } if (!$rs->EOF) { // Output header row $first = true; foreach ($rs->fields as $k => $v) { $finfo = $rs->fetchField($k); $v = $finfo->name; if (!is_null($v)) { $v = str_replace('"', '""', $v); } if ($first) { echo "\"{$v}\""; $first = false; } else { echo "{$sep}\"{$v}\""; } } echo "\r\n"; } while (!$rs->EOF) { $first = true; foreach ($rs->fields as $k => $v) { if (!is_null($v)) { $v = str_replace('"', '""', $v); } if ($first) { echo (is_null($v)) ? '"\\N"' : "\"{$v}\""; $first = false; } else { echo is_null($v) ? "{$sep}\"\\N\"" : "{$sep}\"{$v}\""; } } echo "\r\n"; $rs->moveNext(); } } }