diff options
Diffstat (limited to 'hugo/libraries/plugins/export')
18 files changed, 8505 insertions, 0 deletions
diff --git a/hugo/libraries/plugins/export/ExportCodegen.class.php b/hugo/libraries/plugins/export/ExportCodegen.class.php new file mode 100644 index 0000000..d0a2216 --- /dev/null +++ b/hugo/libraries/plugins/export/ExportCodegen.class.php @@ -0,0 +1,423 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Set of functions used to build NHibernate dumps of tables + * + * @package PhpMyAdmin-Export + * @subpackage CodeGen + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/* Get the export interface */ +require_once 'libraries/plugins/ExportPlugin.class.php'; +/* Get the table property class */ +require_once 'libraries/plugins/export/TableProperty.class.php'; + +/** + * Handles the export for the CodeGen class + * + * @package PhpMyAdmin-Export + * @subpackage CodeGen + */ +class ExportCodegen extends ExportPlugin +{ + /** + * CodeGen Formats + * + * @var array + */ + private $_cgFormats; + + /** + * CodeGen Handlers + * + * @var array + */ + private $_cgHandlers; + + /** + * Constructor + */ + public function __construct() + { + // initialize the specific export CodeGen variables + $this->initSpecificVariables(); + $this->setProperties(); + } + + /** + * Initialize the local variables that are used for export CodeGen + * + * @return void + */ + protected function initSpecificVariables() + { + $this->_setCgFormats( + array( + "NHibernate C# DO", + "NHibernate XML" + ) + ); + + $this->_setCgHandlers( + array( + "_handleNHibernateCSBody", + "_handleNHibernateXMLBody" + ) + ); + } + + /** + * Sets the export CodeGen properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + include_once "$props/options/items/SelectPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('CodeGen'); + $exportPluginProperties->setExtension('cs'); + $exportPluginProperties->setMimeType('text/cs'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new HiddenPropertyItem(); + $leaf->setName("structure_or_data"); + $generalOptions->addProperty($leaf); + $leaf = new SelectPropertyItem(); + $leaf->setName("format"); + $leaf->setText(__('Format:')); + $leaf->setValues($this->_getCgFormats()); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs the content of a table in NHibernate format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + $CG_FORMATS = $this->_getCgFormats(); + $CG_HANDLERS = $this->_getCgHandlers(); + + $format = $GLOBALS['codegen_format']; + if (isset($CG_FORMATS[$format])) { + return PMA_exportOutputHandler( + $this->$CG_HANDLERS[$format]($db, $table, $crlf) + ); + } + return PMA_exportOutputHandler(sprintf("%s is not supported.", $format)); + } + + /** + * Used to make identifiers (from table or database names) + * + * @param string $str name to be converted + * @param bool $ucfirst whether to make the first character uppercase + * + * @return string identifier + */ + public static function cgMakeIdentifier($str, $ucfirst = true) + { + // remove unsafe characters + $str = preg_replace('/[^\p{L}\p{Nl}_]/u', '', $str); + // make sure first character is a letter or _ + if (! preg_match('/^\pL/u', $str)) { + $str = '_' . $str; + } + if ($ucfirst) { + $str = ucfirst($str); + } + return $str; + } + + /** + * C# Handler + * + * @param string $db database name + * @param string $table table name + * @param string $crlf line separator + * + * @return string containing C# code lines, separated by "\n" + */ + private function _handleNHibernateCSBody($db, $table, $crlf) + { + $lines = array(); + + $result = PMA_DBI_query( + sprintf( + 'DESC %s.%s', PMA_Util::backquote($db), + PMA_Util::backquote($table) + ) + ); + if ($result) { + $tableProperties = array(); + while ($row = PMA_DBI_fetch_row($result)) { + $tableProperties[] = new TableProperty($row); + } + PMA_DBI_free_result($result); + $lines[] = 'using System;'; + $lines[] = 'using System.Collections;'; + $lines[] = 'using System.Collections.Generic;'; + $lines[] = 'using System.Text;'; + $lines[] = 'namespace ' . ExportCodegen::cgMakeIdentifier($db); + $lines[] = '{'; + $lines[] = ' #region ' . ExportCodegen::cgMakeIdentifier($table); + $lines[] = ' public class ' . ExportCodegen::cgMakeIdentifier($table); + $lines[] = ' {'; + $lines[] = ' #region Member Variables'; + foreach ($tableProperties as $tableProperty) { + $lines[] = $tableProperty->formatCs( + ' protected #dotNetPrimitiveType# _#name#;' + ); + } + $lines[] = ' #endregion'; + $lines[] = ' #region Constructors'; + $lines[] = ' public ' + . ExportCodegen::cgMakeIdentifier($table) . '() { }'; + $temp = array(); + foreach ($tableProperties as $tableProperty) { + if (! $tableProperty->isPK()) { + $temp[] = $tableProperty->formatCs( + '#dotNetPrimitiveType# #name#' + ); + } + } + $lines[] = ' public ' + . ExportCodegen::cgMakeIdentifier($table) + . '(' + . implode(', ', $temp) + . ')'; + $lines[] = ' {'; + foreach ($tableProperties as $tableProperty) { + if (! $tableProperty->isPK()) { + $lines[] = $tableProperty->formatCs( + ' this._#name#=#name#;' + ); + } + } + $lines[] = ' }'; + $lines[] = ' #endregion'; + $lines[] = ' #region Public Properties'; + foreach ($tableProperties as $tableProperty) { + $lines[] = $tableProperty->formatCs( + ' public virtual #dotNetPrimitiveType# #ucfirstName#' + . "\n" + . ' {' . "\n" + . ' get {return _#name#;}' . "\n" + . ' set {_#name#=value;}' . "\n" + . ' }' + ); + } + $lines[] = ' #endregion'; + $lines[] = ' }'; + $lines[] = ' #endregion'; + $lines[] = '}'; + } + return implode("\n", $lines); + } + + /** + * XML Handler + * + * @param string $db database name + * @param string $table table name + * @param string $crlf line separator + * + * @return string containing XML code lines, separated by "\n" + */ + private function _handleNHibernateXMLBody($db, $table, $crlf) + { + $lines = array(); + $lines[] = '<?xml version="1.0" encoding="utf-8" ?' . '>'; + $lines[] = '<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" ' + . 'namespace="' . ExportCodegen::cgMakeIdentifier($db) . '" ' + . 'assembly="' . ExportCodegen::cgMakeIdentifier($db) . '">'; + $lines[] = ' <class ' + . 'name="' . ExportCodegen::cgMakeIdentifier($table) . '" ' + . 'table="' . ExportCodegen::cgMakeIdentifier($table) . '">'; + $result = PMA_DBI_query( + sprintf( + "DESC %s.%s", PMA_Util::backquote($db), + PMA_Util::backquote($table) + ) + ); + if ($result) { + while ($row = PMA_DBI_fetch_row($result)) { + $tableProperty = new TableProperty($row); + if ($tableProperty->isPK()) { + $lines[] = $tableProperty->formatXml( + ' <id name="#ucfirstName#" type="#dotNetObjectType#"' + . ' unsaved-value="0">' . "\n" + . ' <column name="#name#" sql-type="#type#"' + . ' not-null="#notNull#" unique="#unique#"' + . ' index="PRIMARY"/>' . "\n" + . ' <generator class="native" />' . "\n" + . ' </id>' + ); + } else { + $lines[] = $tableProperty->formatXml( + ' <property name="#ucfirstName#"' + . ' type="#dotNetObjectType#">' . "\n" + . ' <column name="#name#" sql-type="#type#"' + . ' not-null="#notNull#" #indexName#/>' . "\n" + . ' </property>' + ); + } + } + PMA_DBI_free_result($result); + } + $lines[] = ' </class>'; + $lines[] = '</hibernate-mapping>'; + return implode("\n", $lines); + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Getter for CodeGen formats + * + * @return array + */ + private function _getCgFormats() + { + return $this->_cgFormats; + } + + /** + * Setter for CodeGen formats + * + * @param array $CG_FORMATS contains CodeGen Formats + * + * @return void + */ + private function _setCgFormats($CG_FORMATS) + { + $this->_cgFormats = $CG_FORMATS; + } + + /** + * Getter for CodeGen handlers + * + * @return array + */ + private function _getCgHandlers() + { + return $this->_cgHandlers; + } + + /** + * Setter for CodeGen handlers + * + * @param array $CG_HANDLERS contains CodeGen handler methods + * + * @return void + */ + private function _setCgHandlers($CG_HANDLERS) + { + $this->_cgHandlers = $CG_HANDLERS; + } +} +?>
\ No newline at end of file diff --git a/hugo/libraries/plugins/export/ExportCsv.class.php b/hugo/libraries/plugins/export/ExportCsv.class.php new file mode 100644 index 0000000..98558e9 --- /dev/null +++ b/hugo/libraries/plugins/export/ExportCsv.class.php @@ -0,0 +1,345 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * CSV export code + * + * @package PhpMyAdmin-Export + * @subpackage CSV + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/* Get the export interface */ +require_once 'libraries/plugins/ExportPlugin.class.php'; + +/** + * Handles the export for the CSV format + * + * @package PhpMyAdmin-Export + * @subpackage CSV + */ +class ExportCsv extends ExportPlugin +{ + /** + * The string used to end lines + * + * @var string + */ + private $_csvTerminated; + + /** + * The string used to separate columns + * + * @var string + */ + private $_csvSeparator; + + /** + * The string used to enclose columns + * + * @var string + */ + private $_csvEnclosed; + + /** + * The string used to escape columns + * + * @var string + */ + private $_csvEscaped; + + /** + * Constructor + */ + public function __construct() + { + $this->setProperties(); + } + + /** + * Sets the export CSV properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/TextPropertyItem.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('CSV'); + $exportPluginProperties->setExtension('csv'); + $exportPluginProperties->setMimeType('text/comma-separated-values'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create leaf items and add them to the group + $leaf = new TextPropertyItem(); + $leaf->setName("separator"); + $leaf->setText(__('Columns separated with:')); + $generalOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("enclosed"); + $leaf->setText(__('Columns enclosed with:')); + $generalOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("escaped"); + $leaf->setText(__('Columns escaped with:')); + $generalOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("terminated"); + $leaf->setText(__('Lines terminated with:')); + $generalOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName('null'); + $leaf->setText(__('Replace NULL with:')); + $generalOptions->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName('removeCRLF'); + $leaf->setText( + __('Remove carriage return/line feed characters within columns') + ); + $generalOptions->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName('columns'); + $leaf->setText(__('Put columns names in the first row')); + $generalOptions->addProperty($leaf); + $leaf = new HiddenPropertyItem(); + $leaf->setName('structure_or_data'); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + global $what, $csv_terminated, $csv_separator, $csv_enclosed, $csv_escaped; + + // Here we just prepare some values for export + if ($what == 'excel') { + $csv_terminated = "\015\012"; + switch($GLOBALS['excel_edition']) { + case 'win': + // as tested on Windows with Excel 2002 and Excel 2007 + $csv_separator = ';'; + break; + case 'mac_excel2003': + $csv_separator = ';'; + break; + case 'mac_excel2008': + $csv_separator = ','; + break; + } + $csv_enclosed = '"'; + $csv_escaped = '"'; + if (isset($GLOBALS['excel_columns'])) { + $GLOBALS['csv_columns'] = 'yes'; + } + } else { + if (empty($csv_terminated) || strtolower($csv_terminated) == 'auto') { + $csv_terminated = $GLOBALS['crlf']; + } else { + $csv_terminated = str_replace('\\r', "\015", $csv_terminated); + $csv_terminated = str_replace('\\n', "\012", $csv_terminated); + $csv_terminated = str_replace('\\t', "\011", $csv_terminated); + } // end if + $csv_separator = str_replace('\\t', "\011", $csv_separator); + } + + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs the content of a table in CSV format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + global $what, $csv_terminated, $csv_separator, $csv_enclosed, $csv_escaped; + + // Gets the data from the database + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + $fields_cnt = PMA_DBI_num_fields($result); + + // If required, get fields name at the first line + if (isset($GLOBALS['csv_columns'])) { + $schema_insert = ''; + for ($i = 0; $i < $fields_cnt; $i++) { + if ($csv_enclosed == '') { + $schema_insert .= stripslashes(PMA_DBI_field_name($result, $i)); + } else { + $schema_insert .= $csv_enclosed + . str_replace( + $csv_enclosed, + $csv_escaped . $csv_enclosed, + stripslashes(PMA_DBI_field_name($result, $i)) + ) + . $csv_enclosed; + } + $schema_insert .= $csv_separator; + } // end for + $schema_insert = trim(substr($schema_insert, 0, -1)); + if (! PMA_exportOutputHandler($schema_insert . $csv_terminated)) { + return false; + } + } // end if + + // Format the data + while ($row = PMA_DBI_fetch_row($result)) { + $schema_insert = ''; + for ($j = 0; $j < $fields_cnt; $j++) { + if (! isset($row[$j]) || is_null($row[$j])) { + $schema_insert .= $GLOBALS[$what . '_null']; + } elseif ($row[$j] == '0' || $row[$j] != '') { + // always enclose fields + if ($what == 'excel') { + $row[$j] = preg_replace("/\015(\012)?/", "\012", $row[$j]); + } + // remove CRLF characters within field + if (isset($GLOBALS[$what . '_removeCRLF']) + && $GLOBALS[$what . '_removeCRLF'] + ) { + $row[$j] = str_replace( + "\n", + "", + str_replace( + "\r", + "", + $row[$j] + ) + ); + } + if ($csv_enclosed == '') { + $schema_insert .= $row[$j]; + } else { + // also double the escape string if found in the data + if ($csv_escaped != $csv_enclosed) { + $schema_insert .= $csv_enclosed + . str_replace( + $csv_enclosed, + $csv_escaped . $csv_enclosed, + str_replace( + $csv_escaped, + $csv_escaped . $csv_escaped, + $row[$j] + ) + ) + . $csv_enclosed; + } else { + // avoid a problem when escape string equals enclose + $schema_insert .= $csv_enclosed + . str_replace( + $csv_enclosed, + $csv_escaped . $csv_enclosed, + $row[$j] + ) + . $csv_enclosed; + } + } + } else { + $schema_insert .= ''; + } + if ($j < $fields_cnt-1) { + $schema_insert .= $csv_separator; + } + } // end for + + if (! PMA_exportOutputHandler($schema_insert . $csv_terminated)) { + return false; + } + } // end while + PMA_DBI_free_result($result); + + return true; + } +} +?>
\ No newline at end of file diff --git a/hugo/libraries/plugins/export/ExportExcel.class.php b/hugo/libraries/plugins/export/ExportExcel.class.php new file mode 100644 index 0000000..1bb1060 --- /dev/null +++ b/hugo/libraries/plugins/export/ExportExcel.class.php @@ -0,0 +1,105 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Class for exporting CSV dumps of tables for excel + * + * @package PhpMyAdmin-Export + * @subpackage CSV-Excel + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/* Extend the export CSV class */ +require_once 'libraries/plugins/export/ExportCsv.class.php'; + +/** + * Handles the export for the CSV-Excel format + * + * @package PhpMyAdmin-Export + * @subpackage CSV-Excel + */ +class ExportExcel extends ExportCsv +{ + /** + * Sets the export CSV for Excel properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/TextPropertyItem.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + include_once "$props/options/items/SelectPropertyItem.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('CSV for MS Excel'); + $exportPluginProperties->setExtension('csv'); + $exportPluginProperties->setMimeType('text/comma-separated-values'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new TextPropertyItem(); + $leaf->setName('null'); + $leaf->setText(__('Replace NULL with:')); + $generalOptions->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName('removeCRLF'); + $leaf->setText( + __('Remove carriage return/line feed characters within columns') + ); + $generalOptions->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName('columns'); + $leaf->setText(__('Put columns names in the first row')); + $generalOptions->addProperty($leaf); + $leaf = new SelectPropertyItem(); + $leaf->setName('edition'); + $leaf->setValues( + array( + 'win' => 'Windows', + 'mac_excel2003' => 'Excel 2003 / Macintosh', + 'mac_excel2008' => 'Excel 2008 / Macintosh' + ) + ); + $leaf->setText(__('Excel edition:')); + $generalOptions->addProperty($leaf); + $leaf = new HiddenPropertyItem(); + $leaf->setName('structure_or_data'); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } +} +?>
\ No newline at end of file diff --git a/hugo/libraries/plugins/export/ExportHtmlword.class.php b/hugo/libraries/plugins/export/ExportHtmlword.class.php new file mode 100644 index 0000000..cdd5ec6 --- /dev/null +++ b/hugo/libraries/plugins/export/ExportHtmlword.class.php @@ -0,0 +1,645 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * HTML-Word export code + * + * @package PhpMyAdmin-Export + * @subpackage HTML-Word + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/* Get the export interface */ +require_once 'libraries/plugins/ExportPlugin.class.php'; + +/** + * Handles the export for the HTML-Word format + * + * @package PhpMyAdmin-Export + * @subpackage HTML-Word + */ +class ExportHtmlword extends ExportPlugin +{ + /** + * Constructor + */ + public function __construct() + { + $this->setProperties(); + } + + /** + * Sets the export HTML-Word properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/RadioPropertyItem.class.php"; + include_once "$props/options/items/TextPropertyItem.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('Microsoft Word 2000'); + $exportPluginProperties->setExtension('doc'); + $exportPluginProperties->setMimeType('application/vnd.ms-word'); + $exportPluginProperties->setForceFile(true); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // what to dump (structure/data/both) + $dumpWhat = new OptionsPropertyMainGroup(); + $dumpWhat->setName("dump_what"); + $dumpWhat->setText(__('Dump table')); + // create primary items and add them to the group + $leaf = new RadioPropertyItem(); + $leaf->setName("structure_or_data"); + $leaf->setValues( + array( + 'structure' => __('structure'), + 'data' => __('data'), + 'structure_and_data' => __('structure and data') + ) + ); + $dumpWhat->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($dumpWhat); + + // data options main group + $dataOptions = new OptionsPropertyMainGroup(); + $dataOptions->setName("dump_what"); + $dataOptions->setText(__('Data dump options')); + $dataOptions->setForce('structure'); + // create primary items and add them to the group + $leaf = new TextPropertyItem(); + $leaf->setName("null"); + $leaf->setText(__('Replace NULL with:')); + $dataOptions->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName("columns"); + $leaf->setText(__('Put columns names in the first row')); + $dataOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($dataOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + global $charset_of_file; + + return PMA_exportOutputHandler( + '<html xmlns:o="urn:schemas-microsoft-com:office:office" + xmlns:x="urn:schemas-microsoft-com:office:word" + xmlns="http://www.w3.org/TR/REC-html40"> + + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' + . ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + <html> + <head> + <meta http-equiv="Content-type" content="text/html;charset=' + . (isset($charset_of_file) ? $charset_of_file : 'utf-8') . '" /> + </head> + <body>' + ); + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + return PMA_exportOutputHandler('</body></html>'); + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + return PMA_exportOutputHandler( + '<h1>' . __('Database') . ' ' . htmlspecialchars($db) . '</h1>' + ); + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs the content of a table in HTML-Word format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + global $what; + + if (! PMA_exportOutputHandler( + '<h2>' + . __('Dumping data for table') . ' ' . htmlspecialchars($table) + . '</h2>' + )) { + return false; + } + if (! PMA_exportOutputHandler( + '<table class="width100" cellspacing="1">' + )) { + return false; + } + + // Gets the data from the database + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + $fields_cnt = PMA_DBI_num_fields($result); + + // If required, get fields name at the first line + if (isset($GLOBALS['htmlword_columns'])) { + $schema_insert = '<tr class="print-category">'; + for ($i = 0; $i < $fields_cnt; $i++) { + $schema_insert .= '<td class="print"><strong>' + . htmlspecialchars( + stripslashes(PMA_DBI_field_name($result, $i)) + ) + . '</strong></td>'; + } // end for + $schema_insert .= '</tr>'; + if (! PMA_exportOutputHandler($schema_insert)) { + return false; + } + } // end if + + // Format the data + while ($row = PMA_DBI_fetch_row($result)) { + $schema_insert = '<tr class="print-category">'; + for ($j = 0; $j < $fields_cnt; $j++) { + if (! isset($row[$j]) || is_null($row[$j])) { + $value = $GLOBALS[$what . '_null']; + } elseif ($row[$j] == '0' || $row[$j] != '') { + $value = $row[$j]; + } else { + $value = ''; + } + $schema_insert .= '<td class="print">' + . htmlspecialchars($value) + . '</td>'; + } // end for + $schema_insert .= '</tr>'; + if (! PMA_exportOutputHandler($schema_insert)) { + return false; + } + } // end while + PMA_DBI_free_result($result); + if (! PMA_exportOutputHandler('</table>')) { + return false; + } + + return true; + } + + /** + * Returns a stand-in CREATE definition to resolve view dependencies + * + * @param string $db the database name + * @param string $view the view name + * @param string $crlf the end of line sequence + * + * @return string resulting definition + */ + public function getTableDefStandIn($db, $view, $crlf) + { + $schema_insert = '<table class="width100" cellspacing="1">' + . '<tr class="print-category">' + . '<th class="print">' + . __('Column') + . '</th>' + . '<td class="print"><strong>' + . __('Type') + . '</strong></td>' + . '<td class="print"><strong>' + . __('Null') + . '</strong></td>' + . '<td class="print"><strong>' + . __('Default') + . '</strong></td>' + . '</tr>'; + + /** + * Get the unique keys in the view + */ + $unique_keys = array(); + $keys = PMA_DBI_get_table_indexes($db, $view); + foreach ($keys as $key) { + if ($key['Non_unique'] == 0) { + $unique_keys[] = $key['Column_name']; + } + } + + $columns = PMA_DBI_get_columns($db, $view); + foreach ($columns as $column) { + $schema_insert .= $this->formatOneColumnDefinition( + $column, + $unique_keys + ); + $schema_insert .= '</tr>'; + } + + $schema_insert .= '</table>'; + return $schema_insert; + } + + /** + * Returns $table's CREATE definition + * + * @param string $db the database name + * @param string $table the table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column + * comments as comments in the structure; + * this is deprecated but the parameter is + * left here because export.php calls + * PMA_exportStructure() also for other + * export types which use this parameter + * @param bool $do_mime whether to include mime comments + * @param bool $show_dates whether to include creation/update/check dates + * @param bool $add_semicolon whether to add semicolon and end-of-line + * at the end + * @param bool $view whether we're handling a view + * + * @return string resulting schema + */ + public function getTableDef( + $db, + $table, + $crlf, + $error_url, + $do_relation, + $do_comments, + $do_mime, + $show_dates = false, + $add_semicolon = true, + $view = false + ) { + // set $cfgRelation here, because there is a chance that it's modified + // since the class initialization + global $cfgRelation; + + $schema_insert = ''; + + /** + * Gets fields properties + */ + PMA_DBI_select_db($db); + + // Check if we can use Relations + if ($do_relation && ! empty($cfgRelation['relation'])) { + // Find which tables are related with the current one and write it in + // an array + $res_rel = PMA_getForeigners($db, $table); + + if ($res_rel && count($res_rel) > 0) { + $have_rel = true; + } else { + $have_rel = false; + } + } else { + $have_rel = false; + } // end if + + /** + * Displays the table structure + */ + $schema_insert .= '<table class="width100" cellspacing="1">'; + + $columns_cnt = 4; + if ($do_relation && $have_rel) { + $columns_cnt++; + } + if ($do_comments && $cfgRelation['commwork']) { + $columns_cnt++; + } + if ($do_mime && $cfgRelation['mimework']) { + $columns_cnt++; + } + + $schema_insert .= '<tr class="print-category">'; + $schema_insert .= '<th class="print">' + . __('Column') + . '</th>'; + $schema_insert .= '<td class="print"><strong>' + . __('Type') + . '</strong></td>'; + $schema_insert .= '<td class="print"><strong>' + . __('Null') + . '</strong></td>'; + $schema_insert .= '<td class="print"><strong>' + . __('Default') + . '</strong></td>'; + if ($do_relation && $have_rel) { + $schema_insert .= '<td class="print"><strong>' + . __('Links to') + . '</strong></td>'; + } + if ($do_comments) { + $schema_insert .= '<td class="print"><strong>' + . __('Comments') + . '</strong></td>'; + $comments = PMA_getComments($db, $table); + } + if ($do_mime && $cfgRelation['mimework']) { + $schema_insert .= '<td class="print"><strong>' + . htmlspecialchars('MIME') + . '</strong></td>'; + $mime_map = PMA_getMIME($db, $table, true); + } + $schema_insert .= '</tr>'; + + $columns = PMA_DBI_get_columns($db, $table); + /** + * Get the unique keys in the table + */ + $unique_keys = array(); + $keys = PMA_DBI_get_table_indexes($db, $table); + foreach ($keys as $key) { + if ($key['Non_unique'] == 0) { + $unique_keys[] = $key['Column_name']; + } + } + foreach ($columns as $column) { + $schema_insert .= $this->formatOneColumnDefinition( + $column, + $unique_keys + ); + $field_name = $column['Field']; + + if ($do_relation && $have_rel) { + $schema_insert .= '<td class="print">' + . (isset($res_rel[$field_name]) + ? htmlspecialchars( + $res_rel[$field_name]['foreign_table'] + . ' (' . $res_rel[$field_name]['foreign_field'] + . ')' + ) + : '') . '</td>'; + } + if ($do_comments && $cfgRelation['commwork']) { + $schema_insert .= '<td class="print">' + . (isset($comments[$field_name]) + ? htmlspecialchars($comments[$field_name]) + : '') . '</td>'; + } + if ($do_mime && $cfgRelation['mimework']) { + $schema_insert .= '<td class="print">' + . (isset($mime_map[$field_name]) ? + htmlspecialchars( + str_replace('_', '/', $mime_map[$field_name]['mimetype']) + ) + : '') . '</td>'; + } + + $schema_insert .= '</tr>'; + } // end foreach + + $schema_insert .= '</table>'; + return $schema_insert; + } + + /** + * Outputs triggers + * + * @param string $db database name + * @param string $table table name + * + * @return string Formatted triggers list + */ + protected function getTriggers($db, $table) + { + $dump = '<table class="width100" cellspacing="1">'; + $dump .= '<tr class="print-category">'; + $dump .= '<th class="print">' . __('Name') . '</th>'; + $dump .= '<td class="print"><strong>' . __('Time') . '</strong></td>'; + $dump .= '<td class="print"><strong>' . __('Event') . '</strong></td>'; + $dump .= '<td class="print"><strong>' . __('Definition') . '</strong></td>'; + $dump .= '</tr>'; + + $triggers = PMA_DBI_get_triggers($db, $table); + + foreach ($triggers as $trigger) { + $dump .= '<tr class="print-category">'; + $dump .= '<td class="print">' + . htmlspecialchars($trigger['name']) + . '</td>' + . '<td class="print">' + . htmlspecialchars($trigger['action_timing']) + . '</td>' + . '<td class="print">' + . htmlspecialchars($trigger['event_manipulation']) + . '</td>' + . '<td class="print">' + . htmlspecialchars($trigger['definition']) + . '</td>' + . '</tr>'; + } + + $dump .= '</table>'; + return $dump; + } + + /** + * Outputs table's structure + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $export_mode 'create_table', 'triggers', 'create_view', + * 'stand_in' + * @param string $export_type 'server', 'database', 'table' + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column + * comments as comments in the structure; + * this is deprecated but the parameter is + * left here because export.php calls + * PMA_exportStructure() also for other + * export types which use this parameter + * @param bool $do_mime whether to include mime comments + * @param bool $dates whether to include creation/update/check dates + * + * @return bool Whether it succeeded + */ + public function exportStructure( + $db, + $table, + $crlf, + $error_url, + $export_mode, + $export_type, + $do_relation = false, + $do_comments = false, + $do_mime = false, + $dates = false + ) { + $dump = ''; + + switch($export_mode) { + case 'create_table': + $dump .= '<h2>' + . __('Table structure for table') . ' ' . htmlspecialchars($table) + . '</h2>'; + $dump .= $this->getTableDef( + $db, $table, $crlf, $error_url, $do_relation, $do_comments, $do_mime, + $dates + ); + break; + case 'triggers': + $dump = ''; + $triggers = PMA_DBI_get_triggers($db, $table); + if ($triggers) { + $dump .= '<h2>' + . __('Triggers') . ' ' . htmlspecialchars($table) + . '</h2>'; + $dump .= $this->getTriggers($db, $table); + } + break; + case 'create_view': + $dump .= '<h2>' + . __('Structure for view') . ' ' . htmlspecialchars($table) + . '</h2>'; + $dump .= $this->getTableDef( + $db, $table, $crlf, $error_url, $do_relation, $do_comments, $do_mime, + $dates, true, true + ); + break; + case 'stand_in': + $dump .= '<h2>' + . __('Stand-in structure for view') . ' ' . htmlspecialchars($table) + . '</h2>'; + // export a stand-in definition to resolve view dependencies + $dump .= $this->getTableDefStandIn($db, $table, $crlf); + } // end switch + + return PMA_exportOutputHandler($dump); + } + + /** + * Formats the definition for one column + * + * @param array $column info about this column + * @param array $unique_keys unique keys of the table + * + * @return string Formatted column definition + */ + protected function formatOneColumnDefinition( + $column, $unique_keys + ) { + $definition = '<tr class="print-category">'; + + $extracted_columnspec + = PMA_Util::extractColumnSpec($column['Type']); + + $type = htmlspecialchars($extracted_columnspec['print_type']); + if (empty($type)) { + $type = ' '; + } + + if (! isset($column['Default'])) { + if ($column['Null'] != 'NO') { + $column['Default'] = 'NULL'; + } + } + + $fmt_pre = ''; + $fmt_post = ''; + if (in_array($column['Field'], $unique_keys)) { + $fmt_pre = '<strong>' . $fmt_pre; + $fmt_post = $fmt_post . '</strong>'; + } + if ($column['Key'] == 'PRI') { + $fmt_pre = '<em>' . $fmt_pre; + $fmt_post = $fmt_post . '</em>'; + } + $definition .= '<td class="print">' . $fmt_pre + . htmlspecialchars($column['Field']) . $fmt_post . '</td>'; + $definition .= '<td class="print">' . htmlspecialchars($type) + . '</td>'; + $definition .= '<td class="print">' + . (($column['Null'] == '' || $column['Null'] == 'NO') + ? __('No') + : __('Yes')) + . '</td>'; + $definition .= '<td class="print">' + . htmlspecialchars( + isset($column['Default']) + ? $column['Default'] + : '' + ) + . '</td>'; + + return $definition; + } +} +?>
\ No newline at end of file diff --git a/hugo/libraries/plugins/export/ExportJson.class.php b/hugo/libraries/plugins/export/ExportJson.class.php new file mode 100644 index 0000000..299e248 --- /dev/null +++ b/hugo/libraries/plugins/export/ExportJson.class.php @@ -0,0 +1,221 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Set of methods used to build dumps of tables as JSON + * + * @package PhpMyAdmin-Export + * @subpackage JSON + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/* Get the export interface */ +require_once 'libraries/plugins/ExportPlugin.class.php'; + +/** + * Handles the export for the JSON format + * + * @package PhpMyAdmin-Export + * @subpackage JSON + */ +class ExportJson extends ExportPlugin +{ + /** + * Constructor + */ + public function __construct() + { + $this->setProperties(); + } + + /** + * Sets the export JSON properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('JSON'); + $exportPluginProperties->setExtension('json'); + $exportPluginProperties->setMimeType('text/plain'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new HiddenPropertyItem(); + $leaf->setName("structure_or_data"); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + PMA_exportOutputHandler( + '/**' . $GLOBALS['crlf'] + . ' Export to JSON plugin for PHPMyAdmin' . $GLOBALS['crlf'] + . ' @version 0.1' . $GLOBALS['crlf'] + . ' */' . $GLOBALS['crlf'] . $GLOBALS['crlf'] + ); + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + PMA_exportOutputHandler('// Database \'' . $db . '\'' . $GLOBALS['crlf']); + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs the content of a table in JSON format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + $columns_cnt = PMA_DBI_num_fields($result); + + // Get field information + $fields_meta = PMA_DBI_get_fields_meta($result); + + for ($i = 0; $i < $columns_cnt; $i++) { + $columns[$i] = stripslashes(PMA_DBI_field_name($result, $i)); + } + unset($i); + + $buffer = ''; + $record_cnt = 0; + while ($record = PMA_DBI_fetch_row($result)) { + + $record_cnt++; + + // Output table name as comment if this is the first record of the table + if ($record_cnt == 1) { + $buffer .= '// ' . $db . '.' . $table . $crlf . $crlf; + $buffer .= '[{'; + } else { + $buffer .= ', {'; + } + + for ($i = 0; $i < $columns_cnt; $i++) { + $isLastLine = ($i + 1 >= $columns_cnt); + $column = $columns[$i]; + if (is_null($record[$i])) { + $buffer .= '"' . addslashes($column) + . '": null' + . (! $isLastLine ? ',' : ''); + } elseif ($fields_meta[$i]->numeric) { + $buffer .= '"' . addslashes($column) + . '": ' + . $record[$i] + . (! $isLastLine ? ',' : ''); + } else { + $buffer .= '"' . addslashes($column) + . '": "' + . addslashes($record[$i]) + . '"' + . (! $isLastLine ? ',' : ''); + } + } + + $buffer .= '}'; + } + + if ($record_cnt) { + $buffer .= ']'; + } + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + + PMA_DBI_free_result($result); + return true; + } +} +?>
\ No newline at end of file diff --git a/hugo/libraries/plugins/export/ExportLatex.class.php b/hugo/libraries/plugins/export/ExportLatex.class.php new file mode 100644 index 0000000..0f5c953 --- /dev/null +++ b/hugo/libraries/plugins/export/ExportLatex.class.php @@ -0,0 +1,655 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Set of methods used to build dumps of tables as Latex + * + * @package PhpMyAdmin-Export + * @subpackage Latex + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/* Get the export interface */ +require_once 'libraries/plugins/ExportPlugin.class.php'; + +/** + * Handles the export for the Latex format + * + * @package PhpMyAdmin-Export + * @subpackage Latex + */ +class ExportLatex extends ExportPlugin +{ + /** + * Constructor + */ + public function __construct() + { + // initialize the specific export sql variables + $this->initSpecificVariables(); + + $this->setProperties(); + } + + /** + * Initialize the local variables that are used for export Latex + * + * @return void + */ + protected function initSpecificVariables() + { + /* Messages used in default captions */ + $GLOBALS['strLatexContent'] = __('Content of table @TABLE@'); + $GLOBALS['strLatexContinued'] = __('(continued)'); + $GLOBALS['strLatexStructure'] = __('Structure of table @TABLE@'); + } + + /** + * Sets the export Latex properties + * + * @return void + */ + protected function setProperties() + { + global $plugin_param; + $hide_structure = false; + if ($plugin_param['export_type'] == 'table' + && ! $plugin_param['single_table'] + ) { + $hide_structure = true; + } + + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + include_once "$props/options/items/RadioPropertyItem.class.php"; + include_once "$props/options/items/TextPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('LaTeX'); + $exportPluginProperties->setExtension('tex'); + $exportPluginProperties->setMimeType('application/x-tex'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new BoolPropertyItem(); + $leaf->setName("caption"); + $leaf->setText(__('Include table caption')); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // what to dump (structure/data/both) main group + $dumpWhat = new OptionsPropertyMainGroup(); + $dumpWhat->setName("dump_what"); + $dumpWhat->setText(__('Dump table')); + // create primary items and add them to the group + $leaf = new RadioPropertyItem(); + $leaf->setName("structure_or_data"); + $leaf->setValues( + array( + 'structure' => __('structure'), + 'data' => __('data'), + 'structure_and_data' => __('structure and data') + ) + ); + $dumpWhat->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($dumpWhat); + + // structure options main group + if (! $hide_structure) { + $structureOptions = new OptionsPropertyMainGroup(); + $structureOptions->setName("structure"); + $structureOptions->setText(__('Object creation options')); + $structureOptions->setForce('data'); + // create primary items and add them to the group + $leaf = new TextPropertyItem(); + $leaf->setName("structure_caption"); + $leaf->setText(__('Table caption')); + $leaf->setDoc('faq6-27'); + $structureOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("structure_continued_caption"); + $leaf->setText(__('Table caption (continued)')); + $leaf->setDoc('faq6-27'); + $structureOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("structure_label"); + $leaf->setText(__('Label key')); + $leaf->setDoc('faq6-27'); + $structureOptions->addProperty($leaf); + if (! empty($GLOBALS['cfgRelation']['relation'])) { + $leaf = new BoolPropertyItem(); + $leaf->setName("relation"); + $leaf->setText(__('Display foreign key relationships')); + $structureOptions->addProperty($leaf); + } + $leaf = new BoolPropertyItem(); + $leaf->setName("comments"); + $leaf->setText(__('Display comments')); + $structureOptions->addProperty($leaf); + if (! empty($GLOBALS['cfgRelation']['mimework'])) { + $leaf = new BoolPropertyItem(); + $leaf->setName("mime"); + $leaf->setText(__('Display MIME types')); + $structureOptions->addProperty($leaf); + } + // add the main group to the root group + $exportSpecificOptions->addProperty($structureOptions); + } + + // data options main group + $dataOptions = new OptionsPropertyMainGroup(); + $dataOptions->setName("data"); + $dataOptions->setText(__('Data dump options')); + $dataOptions->setForce('structure'); + // create primary items and add them to the group + $leaf = new BoolPropertyItem(); + $leaf->setName("columns"); + $leaf->setText(__('Put columns names in the first row')); + $dataOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("data_caption"); + $leaf->setText(__('Table caption')); + $leaf->setDoc('faq6-27'); + $dataOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("data_continued_caption"); + $leaf->setText(__('Table caption (continued)')); + $leaf->setDoc('faq6-27'); + $dataOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("data_label"); + $leaf->setText(__('Label key')); + $leaf->setDoc('faq6-27'); + $dataOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName('null'); + $leaf->setText(__('Replace NULL with:')); + $dataOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($dataOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + global $crlf; + global $cfg; + + $head = '% phpMyAdmin LaTeX Dump' . $crlf + . '% version ' . PMA_VERSION . $crlf + . '% http://www.phpmyadmin.net' . $crlf + . '%' . $crlf + . '% ' . __('Host') . ': ' . $cfg['Server']['host']; + if (! empty($cfg['Server']['port'])) { + $head .= ':' . $cfg['Server']['port']; + } + $head .= $crlf + . '% ' . __('Generation Time') . ': ' + . PMA_Util::localisedDate() . $crlf + . '% ' . __('Server version') . ': ' . PMA_MYSQL_STR_VERSION . $crlf + . '% ' . __('PHP Version') . ': ' . phpversion() . $crlf; + return PMA_exportOutputHandler($head); + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + global $crlf; + $head = '% ' . $crlf + . '% ' . __('Database') . ': ' . '\'' . $db . '\'' . $crlf + . '% ' . $crlf; + return PMA_exportOutputHandler($head); + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs the content of a table in JSON format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + $result = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + + $columns_cnt = PMA_DBI_num_fields($result); + for ($i = 0; $i < $columns_cnt; $i++) { + $columns[$i] = PMA_DBI_field_name($result, $i); + } + unset($i); + + $buffer = $crlf . '%' . $crlf . '% ' . __('Data') . ': ' . $table + . $crlf . '%' . $crlf . ' \\begin{longtable}{|'; + + for ($index = 0; $index < $columns_cnt; $index++) { + $buffer .= 'l|'; + } + $buffer .= '} ' . $crlf ; + + $buffer .= ' \\hline \\endhead \\hline \\endfoot \\hline ' . $crlf; + if (isset($GLOBALS['latex_caption'])) { + $buffer .= ' \\caption{' + . PMA_Util::expandUserString( + $GLOBALS['latex_data_caption'], + array( + 'texEscape', + get_class($this), + 'libraries/plugins/export/' . get_class($this) . ".class.php" + ), + array('table' => $table, 'database' => $db) + ) + . '} \\label{' + . PMA_Util::expandUserString( + $GLOBALS['latex_data_label'], + null, + array('table' => $table, 'database' => $db) + ) + . '} \\\\'; + } + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + + // show column names + if (isset($GLOBALS['latex_columns'])) { + $buffer = '\\hline '; + for ($i = 0; $i < $columns_cnt; $i++) { + $buffer .= '\\multicolumn{1}{|c|}{\\textbf{' + . self::texEscape(stripslashes($columns[$i])) . '}} & '; + } + + $buffer = substr($buffer, 0, -2) . '\\\\ \\hline \hline '; + if (! PMA_exportOutputHandler($buffer . ' \\endfirsthead ' . $crlf)) { + return false; + } + if (isset($GLOBALS['latex_caption'])) { + if (! PMA_exportOutputHandler( + '\\caption{' + . PMA_Util::expandUserString( + $GLOBALS['latex_data_continued_caption'], + array( + 'texEscape', + get_class($this), + 'libraries/plugins/export/' + . get_class($this) . ".class.php" + ), + array('table' => $table, 'database' => $db) + ) + . '} \\\\ ' + )) { + return false; + } + } + if (! PMA_exportOutputHandler($buffer . '\\endhead \\endfoot' . $crlf)) { + return false; + } + } else { + if (! PMA_exportOutputHandler('\\\\ \hline')) { + return false; + } + } + + // print the whole table + while ($record = PMA_DBI_fetch_assoc($result)) { + $buffer = ''; + // print each row + for ($i = 0; $i < $columns_cnt; $i++) { + if ((! function_exists('is_null') + || ! is_null($record[$columns[$i]])) + && isset($record[$columns[$i]]) + ) { + $column_value = self::texEscape( + stripslashes($record[$columns[$i]]) + ); + } else { + $column_value = $GLOBALS['latex_null']; + } + + // last column ... no need for & character + if ($i == ($columns_cnt - 1)) { + $buffer .= $column_value; + } else { + $buffer .= $column_value . " & "; + } + } + $buffer .= ' \\\\ \\hline ' . $crlf; + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + } + + $buffer = ' \\end{longtable}' . $crlf; + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + + PMA_DBI_free_result($result); + return true; + } // end getTableLaTeX + + /** + * Outputs table's structure + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $export_mode 'create_table', 'triggers', 'create_view', + * 'stand_in' + * @param string $export_type 'server', 'database', 'table' + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column + * comments as comments in the structure; + * this is deprecated but the parameter is + * left here because export.php calls + * exportStructure() also for other + * export types which use this parameter + * @param bool $do_mime whether to include mime comments + * @param bool $dates whether to include creation/update/check dates + * + * @return bool Whether it succeeded + */ + public function exportStructure( + $db, + $table, + $crlf, + $error_url, + $export_mode, + $export_type, + $do_relation = false, + $do_comments = false, + $do_mime = false, + $dates = false + ) { + global $cfgRelation; + + /* We do not export triggers */ + if ($export_mode == 'triggers') { + return true; + } + + /** + * Get the unique keys in the table + */ + $unique_keys = array(); + $keys = PMA_DBI_get_table_indexes($db, $table); + foreach ($keys as $key) { + if ($key['Non_unique'] == 0) { + $unique_keys[] = $key['Column_name']; + } + } + + /** + * Gets fields properties + */ + PMA_DBI_select_db($db); + + // Check if we can use Relations + if ($do_relation && ! empty($cfgRelation['relation'])) { + // Find which tables are related with the current one and write it in + // an array + $res_rel = PMA_getForeigners($db, $table); + + if ($res_rel && count($res_rel) > 0) { + $have_rel = true; + } else { + $have_rel = false; + } + } else { + $have_rel = false; + } // end if + + /** + * Displays the table structure + */ + $buffer = $crlf . '%' . $crlf . '% ' . __('Structure') . ': ' . $table + . $crlf . '%' . $crlf . ' \\begin{longtable}{'; + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + + $columns_cnt = 4; + $alignment = '|l|c|c|c|'; + if ($do_relation && $have_rel) { + $columns_cnt++; + $alignment .= 'l|'; + } + if ($do_comments) { + $columns_cnt++; + $alignment .= 'l|'; + } + if ($do_mime && $cfgRelation['mimework']) { + $columns_cnt++; + $alignment .='l|'; + } + $buffer = $alignment . '} ' . $crlf ; + + $header = ' \\hline '; + $header .= '\\multicolumn{1}{|c|}{\\textbf{' . __('Column') + . '}} & \\multicolumn{1}{|c|}{\\textbf{' . __('Type') + . '}} & \\multicolumn{1}{|c|}{\\textbf{' . __('Null') + . '}} & \\multicolumn{1}{|c|}{\\textbf{' . __('Default') . '}}'; + if ($do_relation && $have_rel) { + $header .= ' & \\multicolumn{1}{|c|}{\\textbf{' . __('Links to') . '}}'; + } + if ($do_comments) { + $header .= ' & \\multicolumn{1}{|c|}{\\textbf{' . __('Comments') . '}}'; + $comments = PMA_getComments($db, $table); + } + if ($do_mime && $cfgRelation['mimework']) { + $header .= ' & \\multicolumn{1}{|c|}{\\textbf{MIME}}'; + $mime_map = PMA_getMIME($db, $table, true); + } + + // Table caption for first page and label + if (isset($GLOBALS['latex_caption'])) { + $buffer .= ' \\caption{' + . PMA_Util::expandUserString( + $GLOBALS['latex_structure_caption'], + array( + 'texEscape', + get_class($this), + 'libraries/plugins/export/' . get_class($this) . ".class.php" + ), + array('table' => $table, 'database' => $db) + ) + . '} \\label{' + . PMA_Util::expandUserString( + $GLOBALS['latex_structure_label'], + null, + array('table' => $table, 'database' => $db) + ) + . '} \\\\' . $crlf; + } + $buffer .= $header . ' \\\\ \\hline \\hline' . $crlf + . '\\endfirsthead' . $crlf; + // Table caption on next pages + if (isset($GLOBALS['latex_caption'])) { + $buffer .= ' \\caption{' + . PMA_Util::expandUserString( + $GLOBALS['latex_structure_continued_caption'], + array( + 'texEscape', + get_class($this), + 'libraries/plugins/export/' . get_class($this) . ".class.php" + ), + array('table' => $table, 'database' => $db) + ) + . '} \\\\ ' . $crlf; + } + $buffer .= $header . ' \\\\ \\hline \\hline \\endhead \\endfoot ' . $crlf; + + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + + $fields = PMA_DBI_get_columns($db, $table); + foreach ($fields as $row) { + $extracted_columnspec + = PMA_Util::extractColumnSpec( + $row['Type'] + ); + $type = $extracted_columnspec['print_type']; + if (empty($type)) { + $type = ' '; + } + + if (! isset($row['Default'])) { + if ($row['Null'] != 'NO') { + $row['Default'] = 'NULL'; + } + } + + $field_name = $row['Field']; + + $local_buffer = $field_name . "\000" . $type . "\000" + . (($row['Null'] == '' || $row['Null'] == 'NO') + ? __('No') : __('Yes')) + . "\000" . (isset($row['Default']) ? $row['Default'] : ''); + + if ($do_relation && $have_rel) { + $local_buffer .= "\000"; + if (isset($res_rel[$field_name])) { + $local_buffer .= $res_rel[$field_name]['foreign_table'] . ' (' + . $res_rel[$field_name]['foreign_field'] . ')'; + } + } + if ($do_comments && $cfgRelation['commwork']) { + $local_buffer .= "\000"; + if (isset($comments[$field_name])) { + $local_buffer .= $comments[$field_name]; + } + } + if ($do_mime && $cfgRelation['mimework']) { + $local_buffer .= "\000"; + if (isset($mime_map[$field_name])) { + $local_buffer .= str_replace( + '_', + '/', + $mime_map[$field_name]['mimetype'] + ); + } + } + $local_buffer = self::texEscape($local_buffer); + if ($row['Key']=='PRI') { + $pos=strpos($local_buffer, "\000"); + $local_buffer = '\\textit{' + . substr($local_buffer, 0, $pos) + . '}' . substr($local_buffer, $pos); + } + if (in_array($field_name, $unique_keys)) { + $pos=strpos($local_buffer, "\000"); + $local_buffer = '\\textbf{' + . substr($local_buffer, 0, $pos) + . '}' . substr($local_buffer, $pos); + } + $buffer = str_replace("\000", ' & ', $local_buffer); + $buffer .= ' \\\\ \\hline ' . $crlf; + + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + } // end while + + $buffer = ' \\end{longtable}' . $crlf; + return PMA_exportOutputHandler($buffer); + } // end of the 'exportStructure' method + + /** + * Escapes some special characters for use in TeX/LaTeX + * + * @param string $string the string to convert + * + * @return string the converted string with escape codes + */ + public static function texEscape($string) + { + $escape = array('$', '%', '{', '}', '&', '#', '_', '^'); + $cnt_escape = count($escape); + for ($k = 0; $k < $cnt_escape; $k++) { + $string = str_replace($escape[$k], '\\' . $escape[$k], $string); + } + return $string; + } +} +?> diff --git a/hugo/libraries/plugins/export/ExportMediawiki.class.php b/hugo/libraries/plugins/export/ExportMediawiki.class.php new file mode 100644 index 0000000..89afe71 --- /dev/null +++ b/hugo/libraries/plugins/export/ExportMediawiki.class.php @@ -0,0 +1,364 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Set of functions used to build MediaWiki dumps of tables + * + * @package PhpMyAdmin-Export + * @subpackage MediaWiki + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/* Get the export interface */ +require_once 'libraries/plugins/ExportPlugin.class.php'; + +/** + * Handles the export for the MediaWiki class + * + * @package PhpMyAdmin-Export + * @subpackage MediaWiki + */ +class ExportMediawiki extends ExportPlugin +{ + /** + * Constructor + */ + public function __construct() + { + $this->setProperties(); + } + + /** + * Sets the export MediaWiki properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/groups/OptionsPropertySubgroup.class.php"; + include_once "$props/options/items/MessageOnlyPropertyItem.class.php"; + include_once "$props/options/items/RadioPropertyItem.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('MediaWiki Table'); + $exportPluginProperties->setExtension('mediawiki'); + $exportPluginProperties->setMimeType('text/plain'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + $generalOptions->setText(__('Dump table')); + + // what to dump (structure/data/both) + $subgroup = new OptionsPropertySubgroup(); + $subgroup->setName("dump_table"); + $subgroup->setText("Dump table"); + $leaf = new RadioPropertyItem(); + $leaf->setName('structure_or_data'); + $leaf->setValues( + array( + 'structure' => __('structure'), + 'data' => __('data'), + 'structure_and_data' => __('structure and data') + ) + ); + $subgroup->setSubgroupHeader($leaf); + $generalOptions->addProperty($subgroup); + + // export table name + $leaf = new BoolPropertyItem(); + $leaf->setName("caption"); + $leaf->setText(__('Export table names')); + $generalOptions->addProperty($leaf); + + // export table headers + $leaf = new BoolPropertyItem(); + $leaf->setName("headers"); + $leaf->setText(__('Export table headers')); + $generalOptions->addProperty($leaf); + //add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs table's structure + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $export_mode 'create_table','triggers','create_view', + * 'stand_in' + * @param string $export_type 'server', 'database', 'table' + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column + * comments as comments in the structure; this is + * deprecated but the parameter is left here + * because export.php calls exportStructure() + * also for other export types which use this + * parameter + * @param bool $do_mime whether to include mime comments + * @param bool $dates whether to include creation/update/check dates + * + * @return bool Whether it succeeded + */ + public function exportStructure( + $db, + $table, + $crlf, + $error_url, + $export_mode, + $export_type, + $do_relation = false, + $do_comments = false, + $do_mime = false, + $dates = false + ) { + switch($export_mode) { + case 'create_table': + $columns = PMA_DBI_get_columns($db, $table); + $columns = array_values($columns); + $row_cnt = count($columns); + + // Print structure comment + $output = $this->_exportComment( + "Table structure for " + . PMA_Util::backquote($table) + ); + + // Begin the table construction + $output .= "{| class=\"wikitable\" style=\"text-align:center;\"" + . $this->_exportCRLF(); + + // Add the table name + if ($GLOBALS['mediawiki_caption']) { + $output .= "|+'''" . $table . "'''" . $this->_exportCRLF(); + } + + // Add the table headers + if ($GLOBALS['mediawiki_headers']) { + $output .= "|- style=\"background:#ffdead;\"" . $this->_exportCRLF(); + $output .= "! style=\"background:#ffffff\" | " + . $this->_exportCRLF(); + for ($i = 0; $i < $row_cnt; ++$i) { + $output .= " | " . $columns[$i]['Field']. $this->_exportCRLF(); + } + } + + // Add the table structure + $output .= "|-" . $this->_exportCRLF(); + $output .= "! Type" . $this->_exportCRLF(); + for ($i = 0; $i < $row_cnt; ++$i) { + $output .= " | " . $columns[$i]['Type'] . $this->_exportCRLF(); + } + + $output .= "|-" . $this->_exportCRLF(); + $output .= "! Null" . $this->_exportCRLF(); + for ($i = 0; $i < $row_cnt; ++$i) { + $output .= " | " . $columns[$i]['Null'] . $this->_exportCRLF(); + } + + $output .= "|-" . $this->_exportCRLF(); + $output .= "! Default" . $this->_exportCRLF(); + for ($i = 0; $i < $row_cnt; ++$i) { + $output .= " | " . $columns[$i]['Default'] . $this->_exportCRLF(); + } + + $output .= "|-" . $this->_exportCRLF(); + $output .= "! Extra" . $this->_exportCRLF(); + for ($i = 0; $i < $row_cnt; ++$i) { + $output .= " | " . $columns[$i]['Extra'] . $this->_exportCRLF(); + } + + $output .= "|}" . str_repeat($this->_exportCRLF(), 2); + break; + } // end switch + + return PMA_exportOutputHandler($output); + } + + /** + * Outputs the content of a table in MediaWiki format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData( + $db, + $table, + $crlf, + $error_url, + $sql_query + ) { + // Print data comment + $output = $this->_exportComment( + "Table data for ". PMA_Util::backquote($table) + ); + + // Begin the table construction + // Use the "wikitable" class for style + // Use the "sortable" class for allowing tables to be sorted by column + $output .= "{| class=\"wikitable sortable\" style=\"text-align:center;\"" + . $this->_exportCRLF(); + + // Add the table name + if ($GLOBALS['mediawiki_caption']) { + $output .= "|+'''" . $table . "'''" . $this->_exportCRLF(); + } + + // Add the table headers + if ($GLOBALS['mediawiki_headers']) { + // Get column names + $column_names = PMA_DBI_get_column_names($db, $table); + + // Add column names as table headers + if ( ! is_null($column_names) ) { + // Use '|-' for separating rows + $output .= "|-" . $this->_exportCRLF(); + + // Use '!' for separating table headers + foreach ($column_names as $column) { + $output .= " ! " . $column . "" . $this->_exportCRLF(); + } + } + } + + // Get the table data from the database + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + $fields_cnt = PMA_DBI_num_fields($result); + + while ($row = PMA_DBI_fetch_row($result)) { + $output .= "|-" . $this->_exportCRLF(); + + // Use '|' for separating table columns + for ($i = 0; $i < $fields_cnt; ++ $i) { + $output .= " | " . $row[$i] . "" . $this->_exportCRLF(); + } + } + + // End table construction + $output .= "|}" . str_repeat($this->_exportCRLF(), 2); + return PMA_exportOutputHandler($output); + } + + /** + * Outputs comments containing info about the exported tables + * + * @param string $text Text of comment + * + * @return string The formatted comment + */ + private function _exportComment($text = '') + { + // see http://www.mediawiki.org/wiki/Help:Formatting + $comment = $this->_exportCRLF(); + $comment .= '<!--' . $this->_exportCRLF(); + $comment .= $text . $this->_exportCRLF(); + $comment .= '-->' . str_repeat($this->_exportCRLF(), 2); + + return $comment; + } + + /** + * Outputs CRLF + * + * @return string CRLF + */ + private function _exportCRLF() + { + // The CRLF expected by the mediawiki format is "\n" + return "\n"; + } +} +?> diff --git a/hugo/libraries/plugins/export/ExportOds.class.php b/hugo/libraries/plugins/export/ExportOds.class.php new file mode 100644 index 0000000..b1e9f91 --- /dev/null +++ b/hugo/libraries/plugins/export/ExportOds.class.php @@ -0,0 +1,334 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Set of functions used to build OpenDocument Spreadsheet dumps of tables + * + * @package PhpMyAdmin-Export + * @subpackage ODS + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/* Get the export interface */ +require_once 'libraries/plugins/ExportPlugin.class.php'; + +$GLOBALS['ods_buffer'] = ''; +require_once 'libraries/opendocument.lib.php'; + +/** + * Handles the export for the ODS class + * + * @package PhpMyAdmin-Export + * @subpackage ODS + */ +class ExportOds extends ExportPlugin +{ + /** + * Constructor + */ + public function __construct() + { + $this->setProperties(); + } + + /** + * Sets the export ODS properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/TextPropertyItem.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('OpenDocument Spreadsheet'); + $exportPluginProperties->setExtension('ods'); + $exportPluginProperties->setMimeType( + 'application/vnd.oasis.opendocument.spreadsheet' + ); + $exportPluginProperties->setForceFile(true); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new TextPropertyItem(); + $leaf->setName("null"); + $leaf->setText(__('Replace NULL with:')); + $generalOptions->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName("columns"); + $leaf->setText(__('Put columns names in the first row')); + $generalOptions->addProperty($leaf); + $leaf = new HiddenPropertyItem(); + $leaf->setName("structure_or_data"); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + $GLOBALS['ods_buffer'] .= '<?xml version="1.0" encoding="utf-8"?' . '>' + . '<office:document-content ' + . $GLOBALS['OpenDocumentNS'] . 'office:version="1.0">' + . '<office:automatic-styles>' + . '<number:date-style style:name="N37"' + .' number:automatic-order="true">' + . '<number:month number:style="long"/>' + . '<number:text>/</number:text>' + . '<number:day number:style="long"/>' + . '<number:text>/</number:text>' + . '<number:year/>' + . '</number:date-style>' + . '<number:time-style style:name="N43">' + . '<number:hours number:style="long"/>' + . '<number:text>:</number:text>' + . '<number:minutes number:style="long"/>' + . '<number:text>:</number:text>' + . '<number:seconds number:style="long"/>' + . '<number:text> </number:text>' + . '<number:am-pm/>' + . '</number:time-style>' + . '<number:date-style style:name="N50"' + . ' number:automatic-order="true"' + . ' number:format-source="language">' + . '<number:month/>' + . '<number:text>/</number:text>' + . '<number:day/>' + . '<number:text>/</number:text>' + . '<number:year/>' + . '<number:text> </number:text>' + . '<number:hours number:style="long"/>' + . '<number:text>:</number:text>' + . '<number:minutes number:style="long"/>' + . '<number:text> </number:text>' + . '<number:am-pm/>' + . '</number:date-style>' + . '<style:style style:name="DateCell" style:family="table-cell"' + . ' style:parent-style-name="Default" style:data-style-name="N37"/>' + . '<style:style style:name="TimeCell" style:family="table-cell"' + . ' style:parent-style-name="Default" style:data-style-name="N43"/>' + . '<style:style style:name="DateTimeCell" style:family="table-cell"' + . ' style:parent-style-name="Default" style:data-style-name="N50"/>' + . '</office:automatic-styles>' + . '<office:body>' + . '<office:spreadsheet>'; + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + $GLOBALS['ods_buffer'] .= '</office:spreadsheet>' + . '</office:body>' + . '</office:document-content>'; + if (! PMA_exportOutputHandler( + PMA_createOpenDocument( + 'application/vnd.oasis.opendocument.spreadsheet', + $GLOBALS['ods_buffer'] + ) + )) { + return false; + } + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs the content of a table in NHibernate format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + global $what; + + // Gets the data from the database + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + $fields_cnt = PMA_DBI_num_fields($result); + $fields_meta = PMA_DBI_get_fields_meta($result); + $field_flags = array(); + for ($j = 0; $j < $fields_cnt; $j++) { + $field_flags[$j] = PMA_DBI_field_flags($result, $j); + } + + $GLOBALS['ods_buffer'] .= + '<table:table table:name="' . htmlspecialchars($table) . '">'; + + // If required, get fields name at the first line + if (isset($GLOBALS[$what . '_columns'])) { + $GLOBALS['ods_buffer'] .= '<table:table-row>'; + for ($i = 0; $i < $fields_cnt; $i++) { + $GLOBALS['ods_buffer'] .= + '<table:table-cell office:value-type="string">' + . '<text:p>' + . htmlspecialchars( + stripslashes(PMA_DBI_field_name($result, $i)) + ) + . '</text:p>' + . '</table:table-cell>'; + } // end for + $GLOBALS['ods_buffer'] .= '</table:table-row>'; + } // end if + + // Format the data + while ($row = PMA_DBI_fetch_row($result)) { + $GLOBALS['ods_buffer'] .= '<table:table-row>'; + for ($j = 0; $j < $fields_cnt; $j++) { + if (! isset($row[$j]) || is_null($row[$j])) { + $GLOBALS['ods_buffer'] .= + '<table:table-cell office:value-type="string">' + . '<text:p>' + . htmlspecialchars($GLOBALS[$what . '_null']) + . '</text:p>' + . '</table:table-cell>'; + } elseif (stristr($field_flags[$j], 'BINARY') + && $fields_meta[$j]->blob + ) { + // ignore BLOB + $GLOBALS['ods_buffer'] .= + '<table:table-cell office:value-type="string">' + . '<text:p></text:p>' + . '</table:table-cell>'; + } elseif ($fields_meta[$j]->type == "date") { + $GLOBALS['ods_buffer'] .= + '<table:table-cell office:value-type="date"' + . ' office:date-value="' + . date("Y-m-d", strtotime($row[$j])) + . '" table:style-name="DateCell">' + . '<text:p>' + . htmlspecialchars($row[$j]) + . '</text:p>' + . '</table:table-cell>'; + } elseif ($fields_meta[$j]->type == "time") { + $GLOBALS['ods_buffer'] .= + '<table:table-cell office:value-type="time"' + . ' office:time-value="' + . date("\P\TH\Hi\Ms\S", strtotime($row[$j])) + . '" table:style-name="TimeCell">' + . '<text:p>' + . htmlspecialchars($row[$j]) + . '</text:p>' + . '</table:table-cell>'; + } elseif ($fields_meta[$j]->type == "datetime") { + $GLOBALS['ods_buffer'] .= + '<table:table-cell office:value-type="date"' + . ' office:date-value="' + . date("Y-m-d\TH:i:s", strtotime($row[$j])) + . '" table:style-name="DateTimeCell">' + . '<text:p>' + . htmlspecialchars($row[$j]) + . '</text:p>' + . '</table:table-cell>'; + } elseif (($fields_meta[$j]->numeric + && $fields_meta[$j]->type != 'timestamp' + && ! $fields_meta[$j]->blob) || $fields_meta[$j]->type == 'real' + ) { + $GLOBALS['ods_buffer'] .= + '<table:table-cell office:value-type="float"' + . ' office:value="' . $row[$j] . '" >' + . '<text:p>' + . htmlspecialchars($row[$j]) + . '</text:p>' + . '</table:table-cell>'; + } else { + $GLOBALS['ods_buffer'] .= + '<table:table-cell office:value-type="string">' + . '<text:p>' + . htmlspecialchars($row[$j]) + . '</text:p>' + . '</table:table-cell>'; + } + } // end for + $GLOBALS['ods_buffer'] .= '</table:table-row>'; + } // end while + PMA_DBI_free_result($result); + + $GLOBALS['ods_buffer'] .= '</table:table>'; + + return true; + } +} +?> diff --git a/hugo/libraries/plugins/export/ExportOdt.class.php b/hugo/libraries/plugins/export/ExportOdt.class.php new file mode 100644 index 0000000..bb608f0 --- /dev/null +++ b/hugo/libraries/plugins/export/ExportOdt.class.php @@ -0,0 +1,734 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Set of functions used to build OpenDocument Text dumps of tables + * + * @package PhpMyAdmin-Export + * @subpackage ODT + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/* Get the export interface */ +require_once 'libraries/plugins/ExportPlugin.class.php'; + +$GLOBALS['odt_buffer'] = ''; +require_once 'libraries/opendocument.lib.php'; + +/** + * Handles the export for the ODT class + * + * @package PhpMyAdmin-Export + * @subpackage ODT + */ +class ExportOdt extends ExportPlugin +{ + /** + * Constructor + */ + public function __construct() + { + $this->setProperties(); + } + + /** + * Sets the export ODT properties + * + * @return void + */ + protected function setProperties() + { + global $plugin_param; + $hide_structure = false; + if ($plugin_param['export_type'] == 'table' + && ! $plugin_param['single_table'] + ) { + $hide_structure = true; + } + + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/TextPropertyItem.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + include_once "$props/options/items/RadioPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('OpenDocument Text'); + $exportPluginProperties->setExtension('odt'); + $exportPluginProperties->setMimeType( + 'application/vnd.oasis.opendocument.text' + ); + $exportPluginProperties->setForceFile(true); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // what to dump (structure/data/both) main group + $dumpWhat = new OptionsPropertyMainGroup(); + $dumpWhat->setName("general_opts"); + $dumpWhat->setText(__('Dump table')); + // create primary items and add them to the group + $leaf = new RadioPropertyItem(); + $leaf->setName("structure_or_data"); + $leaf->setValues( + array( + 'structure' => __('structure'), + 'data' => __('data'), + 'structure_and_data' => __('structure and data') + ) + ); + $dumpWhat->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($dumpWhat); + + + // structure options main group + if (! $hide_structure) { + $structureOptions = new OptionsPropertyMainGroup(); + $structureOptions->setName("structure"); + $structureOptions->setText(__('Object creation options')); + $structureOptions->setForce('data'); + // create primary items and add them to the group + if (! empty($GLOBALS['cfgRelation']['relation'])) { + $leaf = new BoolPropertyItem(); + $leaf->setName("relation"); + $leaf->setText(__('Display foreign key relationships')); + $structureOptions->addProperty($leaf); + } + $leaf = new BoolPropertyItem(); + $leaf->setName("comments"); + $leaf->setText(__('Display comments')); + $structureOptions->addProperty($leaf); + if (! empty($GLOBALS['cfgRelation']['mimework'])) { + $leaf = new BoolPropertyItem(); + $leaf->setName("mime"); + $leaf->setText(__('Display MIME types')); + $structureOptions->addProperty($leaf); + } + // add the main group to the root group + $exportSpecificOptions->addProperty($structureOptions); + } + + // data options main group + $dataOptions = new OptionsPropertyMainGroup(); + $dataOptions->setName("data"); + $dataOptions->setText(__('Data dump options')); + $dataOptions->setForce('structure'); + // create primary items and add them to the group + $leaf = new BoolPropertyItem(); + $leaf->setName("columns"); + $leaf->setText(__('Put columns names in the first row')); + $dataOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName('null'); + $leaf->setText(__('Replace NULL with:')); + $dataOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($dataOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + $GLOBALS['odt_buffer'] .= '<?xml version="1.0" encoding="utf-8"?' . '>' + . '<office:document-content ' + . $GLOBALS['OpenDocumentNS'] . 'office:version="1.0">' + . '<office:body>' + . '<office:text>'; + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + $GLOBALS['odt_buffer'] .= '</office:text>' + . '</office:body>' + . '</office:document-content>'; + if (! PMA_exportOutputHandler( + PMA_createOpenDocument( + 'application/vnd.oasis.opendocument.text', + $GLOBALS['odt_buffer'] + ) + )) { + return false; + } + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + $GLOBALS['odt_buffer'] .= + '<text:h text:outline-level="1" text:style-name="Heading_1"' + . ' text:is-list-header="true">' + . __('Database') . ' ' . htmlspecialchars($db) + . '</text:h>'; + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + /** + * Outputs the content of a table in NHibernate format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + global $what; + + // Gets the data from the database + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + $fields_cnt = PMA_DBI_num_fields($result); + $fields_meta = PMA_DBI_get_fields_meta($result); + $field_flags = array(); + for ($j = 0; $j < $fields_cnt; $j++) { + $field_flags[$j] = PMA_DBI_field_flags($result, $j); + } + + $GLOBALS['odt_buffer'] .= + '<text:h text:outline-level="2" text:style-name="Heading_2"' + . ' text:is-list-header="true">' + . __('Dumping data for table') . ' ' . htmlspecialchars($table) + . '</text:h>' + . '<table:table' + . ' table:name="' . htmlspecialchars($table) . '_structure">' + . '<table:table-column' + . ' table:number-columns-repeated="' . $fields_cnt . '"/>'; + + // If required, get fields name at the first line + if (isset($GLOBALS[$what . '_columns'])) { + $GLOBALS['odt_buffer'] .= '<table:table-row>'; + for ($i = 0; $i < $fields_cnt; $i++) { + $GLOBALS['odt_buffer'] .= + '<table:table-cell office:value-type="string">' + . '<text:p>' + . htmlspecialchars( + stripslashes(PMA_DBI_field_name($result, $i)) + ) + . '</text:p>' + . '</table:table-cell>'; + } // end for + $GLOBALS['odt_buffer'] .= '</table:table-row>'; + } // end if + + // Format the data + while ($row = PMA_DBI_fetch_row($result)) { + $GLOBALS['odt_buffer'] .= '<table:table-row>'; + for ($j = 0; $j < $fields_cnt; $j++) { + if (! isset($row[$j]) || is_null($row[$j])) { + $GLOBALS['odt_buffer'] .= + '<table:table-cell office:value-type="string">' + . '<text:p>' + . htmlspecialchars($GLOBALS[$what . '_null']) + . '</text:p>' + . '</table:table-cell>'; + } elseif (stristr($field_flags[$j], 'BINARY') + && $fields_meta[$j]->blob + ) { + // ignore BLOB + $GLOBALS['odt_buffer'] .= + '<table:table-cell office:value-type="string">' + . '<text:p></text:p>' + . '</table:table-cell>'; + } elseif ($fields_meta[$j]->numeric + && $fields_meta[$j]->type != 'timestamp' + && ! $fields_meta[$j]->blob + ) { + $GLOBALS['odt_buffer'] .= + '<table:table-cell office:value-type="float"' + . ' office:value="' . $row[$j] . '" >' + . '<text:p>' + . htmlspecialchars($row[$j]) + . '</text:p>' + . '</table:table-cell>'; + } else { + $GLOBALS['odt_buffer'] .= + '<table:table-cell office:value-type="string">' + . '<text:p>' + . htmlspecialchars($row[$j]) + . '</text:p>' + . '</table:table-cell>'; + } + } // end for + $GLOBALS['odt_buffer'] .= '</table:table-row>'; + } // end while + PMA_DBI_free_result($result); + + $GLOBALS['odt_buffer'] .= '</table:table>'; + + return true; + } + + /** + * Returns a stand-in CREATE definition to resolve view dependencies + * + * @param string $db the database name + * @param string $view the view name + * @param string $crlf the end of line sequence + * + * @return bool true + */ + public function getTableDefStandIn($db, $view, $crlf) + { + /** + * Gets fields properties + */ + PMA_DBI_select_db($db); + + /** + * Displays the table structure + */ + $GLOBALS['odt_buffer'] .= + '<table:table table:name="' + . htmlspecialchars($view) . '_data">'; + $columns_cnt = 4; + $GLOBALS['odt_buffer'] .= + '<table:table-column' + . ' table:number-columns-repeated="' . $columns_cnt . '"/>'; + /* Header */ + $GLOBALS['odt_buffer'] .= '<table:table-row>' + . '<table:table-cell office:value-type="string">' + . '<text:p>' . __('Column') . '</text:p>' + . '</table:table-cell>' + . '<table:table-cell office:value-type="string">' + . '<text:p>' . __('Type') . '</text:p>' + . '</table:table-cell>' + . '<table:table-cell office:value-type="string">' + . '<text:p>' . __('Null') . '</text:p>' + . '</table:table-cell>' + . '<table:table-cell office:value-type="string">' + . '<text:p>' . __('Default') . '</text:p>' + . '</table:table-cell>' + . '</table:table-row>'; + + $columns = PMA_DBI_get_columns($db, $view); + foreach ($columns as $column) { + $GLOBALS['odt_buffer'] .= $this->formatOneColumnDefinition($column); + $GLOBALS['odt_buffer'] .= '</table:table-row>'; + } // end foreach + + $GLOBALS['odt_buffer'] .= '</table:table>'; + return true; + } + + /** + * Returns $table's CREATE definition + * + * @param string $db the database name + * @param string $table the table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column + * comments as comments in the structure; + * this is deprecated but the parameter is + * left here because export.php calls + * PMA_exportStructure() also for other + * @param bool $do_mime whether to include mime comments + * @param bool $show_dates whether to include creation/update/check dates + * @param bool $add_semicolon whether to add semicolon and end-of-line at + * the end + * @param bool $view whether we're handling a view + * + * @return bool true + */ + public function getTableDef( + $db, + $table, + $crlf, + $error_url, + $do_relation, + $do_comments, + $do_mime, + $show_dates = false, + $add_semicolon = true, + $view = false + ) { + global $cfgRelation; + + /** + * Gets fields properties + */ + PMA_DBI_select_db($db); + + // Check if we can use Relations + if ($do_relation && ! empty($cfgRelation['relation'])) { + // Find which tables are related with the current one and write it in + // an array + $res_rel = PMA_getForeigners($db, $table); + + if ($res_rel && count($res_rel) > 0) { + $have_rel = true; + } else { + $have_rel = false; + } + } else { + $have_rel = false; + } // end if + + /** + * Displays the table structure + */ + $GLOBALS['odt_buffer'] .= '<table:table table:name="' + . htmlspecialchars($table) . '_structure">'; + $columns_cnt = 4; + if ($do_relation && $have_rel) { + $columns_cnt++; + } + if ($do_comments) { + $columns_cnt++; + } + if ($do_mime && $cfgRelation['mimework']) { + $columns_cnt++; + } + $GLOBALS['odt_buffer'] .= '<table:table-column' + . ' table:number-columns-repeated="' . $columns_cnt . '"/>'; + /* Header */ + $GLOBALS['odt_buffer'] .= '<table:table-row>' + . '<table:table-cell office:value-type="string">' + . '<text:p>' . __('Column') . '</text:p>' + . '</table:table-cell>' + . '<table:table-cell office:value-type="string">' + . '<text:p>' . __('Type') . '</text:p>' + . '</table:table-cell>' + . '<table:table-cell office:value-type="string">' + . '<text:p>' . __('Null') . '</text:p>' + . '</table:table-cell>' + . '<table:table-cell office:value-type="string">' + . '<text:p>' . __('Default') . '</text:p>' + . '</table:table-cell>'; + if ($do_relation && $have_rel) { + $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' + . '<text:p>' . __('Links to') . '</text:p>' + . '</table:table-cell>'; + } + if ($do_comments) { + $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' + . '<text:p>' . __('Comments') . '</text:p>' + . '</table:table-cell>'; + $comments = PMA_getComments($db, $table); + } + if ($do_mime && $cfgRelation['mimework']) { + $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' + . '<text:p>' . __('MIME type') . '</text:p>' + . '</table:table-cell>'; + $mime_map = PMA_getMIME($db, $table, true); + } + $GLOBALS['odt_buffer'] .= '</table:table-row>'; + + $columns = PMA_DBI_get_columns($db, $table); + foreach ($columns as $column) { + $field_name = $column['Field']; + $GLOBALS['odt_buffer'] .= $this->formatOneColumnDefinition($column); + + if ($do_relation && $have_rel) { + if (isset($res_rel[$field_name])) { + $GLOBALS['odt_buffer'] .= + '<table:table-cell office:value-type="string">' + . '<text:p>' + . htmlspecialchars( + $res_rel[$field_name]['foreign_table'] + . ' (' . $res_rel[$field_name]['foreign_field'] . ')' + ) + . '</text:p>' + . '</table:table-cell>'; + } + } + if ($do_comments) { + if (isset($comments[$field_name])) { + $GLOBALS['odt_buffer'] .= + '<table:table-cell office:value-type="string">' + . '<text:p>' + . htmlspecialchars($comments[$field_name]) + . '</text:p>' + . '</table:table-cell>'; + } else { + $GLOBALS['odt_buffer'] .= + '<table:table-cell office:value-type="string">' + . '<text:p></text:p>' + . '</table:table-cell>'; + } + } + if ($do_mime && $cfgRelation['mimework']) { + if (isset($mime_map[$field_name])) { + $GLOBALS['odt_buffer'] .= + '<table:table-cell office:value-type="string">' + . '<text:p>' + . htmlspecialchars( + str_replace('_', '/', $mime_map[$field_name]['mimetype']) + ) + . '</text:p>' + . '</table:table-cell>'; + } else { + $GLOBALS['odt_buffer'] .= + '<table:table-cell office:value-type="string">' + . '<text:p></text:p>' + . '</table:table-cell>'; + } + } + $GLOBALS['odt_buffer'] .= '</table:table-row>'; + } // end foreach + + $GLOBALS['odt_buffer'] .= '</table:table>'; + return true; + } // end of the '$this->getTableDef()' function + + /** + * Outputs triggers + * + * @param string $db database name + * @param string $table table name + * + * @return bool true + */ + protected function getTriggers($db, $table) + { + $GLOBALS['odt_buffer'] .= '<table:table' + . ' table:name="' . htmlspecialchars($table) . '_triggers">' + . '<table:table-column' + . ' table:number-columns-repeated="4"/>' + . '<table:table-row>' + . '<table:table-cell office:value-type="string">' + . '<text:p>' . __('Name') . '</text:p>' + . '</table:table-cell>' + . '<table:table-cell office:value-type="string">' + . '<text:p>' . __('Time') . '</text:p>' + . '</table:table-cell>' + . '<table:table-cell office:value-type="string">' + . '<text:p>' . __('Event') . '</text:p>' + . '</table:table-cell>' + . '<table:table-cell office:value-type="string">' + . '<text:p>' . __('Definition') . '</text:p>' + . '</table:table-cell>' + . '</table:table-row>'; + + $triggers = PMA_DBI_get_triggers($db, $table); + + foreach ($triggers as $trigger) { + $GLOBALS['odt_buffer'] .= '<table:table-row>'; + $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' + . '<text:p>' + . htmlspecialchars($trigger['name']) + . '</text:p>' + . '</table:table-cell>'; + $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' + . '<text:p>' + . htmlspecialchars($trigger['action_timing']) + . '</text:p>' + . '</table:table-cell>'; + $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' + . '<text:p>' + . htmlspecialchars($trigger['event_manipulation']) + . '</text:p>' + . '</table:table-cell>'; + $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">' + . '<text:p>' + . htmlspecialchars($trigger['definition']) + . '</text:p>' + . '</table:table-cell>'; + $GLOBALS['odt_buffer'] .= '</table:table-row>'; + } + + $GLOBALS['odt_buffer'] .= '</table:table>'; + return true; + } + + /** + * Outputs table's structure + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $export_mode 'create_table', 'triggers', 'create_view', + * 'stand_in' + * @param string $export_type 'server', 'database', 'table' + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column + * comments as comments in the structure; + * this is deprecated but the parameter is + * left here because export.php calls + * PMA_exportStructure() also for other + * @param bool $do_mime whether to include mime comments + * @param bool $dates whether to include creation/update/check dates + * + * @return bool Whether it succeeded + */ + public function exportStructure( + $db, + $table, + $crlf, + $error_url, + $export_mode, + $export_type, + $do_relation = false, + $do_comments = false, + $do_mime = false, + $dates = false + ) { + switch($export_mode) { + case 'create_table': + $GLOBALS['odt_buffer'] .= + '<text:h text:outline-level="2" text:style-name="Heading_2"' + . ' text:is-list-header="true">' + . __('Table structure for table') . ' ' . + htmlspecialchars($table) + . '</text:h>'; + $this->getTableDef( + $db, $table, $crlf, $error_url, $do_relation, $do_comments, + $do_mime, $dates + ); + break; + case 'triggers': + $triggers = PMA_DBI_get_triggers($db, $table); + if ($triggers) { + $GLOBALS['odt_buffer'] .= + '<text:h text:outline-level="2" text:style-name="Heading_2"' + . ' text:is-list-header="true">' + . __('Triggers') . ' ' + . htmlspecialchars($table) + . '</text:h>'; + $this->getTriggers($db, $table); + } + break; + case 'create_view': + $GLOBALS['odt_buffer'] .= + '<text:h text:outline-level="2" text:style-name="Heading_2"' + . ' text:is-list-header="true">' + . __('Structure for view') . ' ' + . htmlspecialchars($table) + . '</text:h>'; + $this->getTableDef( + $db, $table, $crlf, $error_url, $do_relation, $do_comments, + $do_mime, $dates, true, true + ); + break; + case 'stand_in': + $GLOBALS['odt_buffer'] .= + '<text:h text:outline-level="2" text:style-name="Heading_2"' + . ' text:is-list-header="true">' + . __('Stand-in structure for view') . ' ' + . htmlspecialchars($table) + . '</text:h>'; + // export a stand-in definition to resolve view dependencies + $this->getTableDefStandIn($db, $table, $crlf); + } // end switch + + return true; + } // end of the '$this->exportStructure' function + + /** + * Formats the definition for one column + * + * @param array $column info about this column + * + * @return string Formatted column definition + */ + protected function formatOneColumnDefinition($column) + { + $field_name = $column['Field']; + $definition = '<table:table-row>'; + $definition .= '<table:table-cell office:value-type="string">' + . '<text:p>' . htmlspecialchars($field_name) . '</text:p>' + . '</table:table-cell>'; + + $extracted_columnspec + = PMA_Util::extractColumnSpec($column['Type']); + $type = htmlspecialchars($extracted_columnspec['print_type']); + if (empty($type)) { + $type = ' '; + } + + $definition .= '<table:table-cell office:value-type="string">' + . '<text:p>' . htmlspecialchars($type) . '</text:p>' + . '</table:table-cell>'; + if (! isset($column['Default'])) { + if ($column['Null'] != 'NO') { + $column['Default'] = 'NULL'; + } else { + $column['Default'] = ''; + } + } else { + $column['Default'] = $column['Default']; + } + $definition .= '<table:table-cell office:value-type="string">' + . '<text:p>' + . (($column['Null'] == '' || $column['Null'] == 'NO') + ? __('No') + : __('Yes')) + . '</text:p>' + . '</table:table-cell>'; + $definition .= '<table:table-cell office:value-type="string">' + . '<text:p>' . htmlspecialchars($column['Default']) . '</text:p>' + . '</table:table-cell>'; + return $definition; + } +} +?> diff --git a/hugo/libraries/plugins/export/ExportPdf.class.php b/hugo/libraries/plugins/export/ExportPdf.class.php new file mode 100644 index 0000000..ffabb96 --- /dev/null +++ b/hugo/libraries/plugins/export/ExportPdf.class.php @@ -0,0 +1,268 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Produce a PDF report (export) from a query + * + * @package PhpMyAdmin-Export + * @subpackage PDF + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/* Get the export interface */ +require_once 'libraries/plugins/ExportPlugin.class.php'; +/* Get the PMA_ExportPdf class */ +require_once 'libraries/plugins/export/PMA_ExportPdf.class.php'; + +/** + * Handles the export for the PDF class + * + * @package PhpMyAdmin-Export + * @subpackage PDF + */ +class ExportPdf extends ExportPlugin +{ + /** + * PMA_ExportPdf instance + * + * @var PMA_ExportPdf + */ + private $_pdf; + + /** + * PDF Report Title + * + * @var string + */ + private $_pdfReportTitle; + + /** + * Constructor + */ + public function __construct() + { + // initialize the specific export PDF variables + $this->initSpecificVariables(); + + $this->setProperties(); + } + + /** + * Initialize the local variables that are used for export PDF + * + * @return void + */ + protected function initSpecificVariables() + { + $this->_setPdfReportTitle(""); + $this->_setPdf(new PMA_ExportPdf('L', 'pt', 'A3')); + } + + /** + * Sets the export PDF properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/MessageOnlyPropertyItem.class.php"; + include_once "$props/options/items/TextPropertyItem.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('PDF'); + $exportPluginProperties->setExtension('pdf'); + $exportPluginProperties->setMimeType('application/pdf'); + $exportPluginProperties->setForceFile(true); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new MessageOnlyPropertyItem(); + $leaf->setName("explanation"); + $leaf->setText( + __('(Generates a report containing the data of a single table)') + ); + $generalOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName("report_title"); + $leaf->setText(__('Report title:')); + $generalOptions->addProperty($leaf); + $leaf = new HiddenPropertyItem(); + $leaf->setName("structure_or_data"); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + $pdf_report_title = $this->_getPdfReportTitle(); + $pdf = $this->_getPdf(); + $pdf->Open(); + + $attr = array('titleFontSize' => 18, 'titleText' => $pdf_report_title); + $pdf->setAttributes($attr); + $pdf->setTopMargin(30); + + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + $pdf = $this->_getPdf(); + + // instead of $pdf->Output(): + if (! PMA_exportOutputHandler($pdf->getPDFData())) { + return false; + } + + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + /** + * Outputs the content of a table in NHibernate format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + $pdf = $this->_getPdf(); + + $attr = array('currentDb' => $db, 'currentTable' => $table); + $pdf->setAttributes($attr); + $pdf->mysqlReport($sql_query); + + return true; + } // end of the 'PMA_exportData()' function + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the PMA_ExportPdf instance + * + * @return PMA_ExportPdf + */ + private function _getPdf() + { + return $this->_pdf; + } + + /** + * Instantiates the PMA_ExportPdf class + * + * @param string $pdf PMA_ExportPdf instance + * + * @return void + */ + private function _setPdf($pdf) + { + $this->_pdf = $pdf; + } + + /** + * Gets the PDF report title + * + * @return string + */ + private function _getPdfReportTitle() + { + return $this->_pdfReportTitle; + } + + /** + * Sets the PDF report title + * + * @param string $pdfReportTitle PDF report title + * + * @return void + */ + private function _setPdfReportTitle($pdfReportTitle) + { + $this->_pdfReportTitle = $pdfReportTitle; + } +} +?>
\ No newline at end of file diff --git a/hugo/libraries/plugins/export/ExportPhparray.class.php b/hugo/libraries/plugins/export/ExportPhparray.class.php new file mode 100644 index 0000000..2d3b73c --- /dev/null +++ b/hugo/libraries/plugins/export/ExportPhparray.class.php @@ -0,0 +1,227 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Set of functions used to build dumps of tables as PHP Arrays + * + * @package PhpMyAdmin-Export + * @subpackage PHP + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/* Get the export interface */ +require_once 'libraries/plugins/ExportPlugin.class.php'; + +/** + * Handles the export for the PHP Array class + * + * @package PhpMyAdmin-Export + * @subpackage PHP + */ +class ExportPhparray extends ExportPlugin +{ + /** + * Constructor + */ + public function __construct() + { + $this->setProperties(); + } + + /** + * Sets the export PHP Array properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('PHP array'); + $exportPluginProperties->setExtension('php'); + $exportPluginProperties->setMimeType('text/plain'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new HiddenPropertyItem(); + $leaf->setName("structure_or_data"); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + PMA_exportOutputHandler( + '<?php' . $GLOBALS['crlf'] + . '/**' . $GLOBALS['crlf'] + . ' * Export to PHP Array plugin for PHPMyAdmin' . $GLOBALS['crlf'] + . ' * @version 0.2b' . $GLOBALS['crlf'] + . ' */' . $GLOBALS['crlf'] . $GLOBALS['crlf'] + ); + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + PMA_exportOutputHandler( + '//' . $GLOBALS['crlf'] + . '// Database ' . PMA_Util::backquote($db) + . $GLOBALS['crlf'] . '//' . $GLOBALS['crlf'] + ); + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs the content of a table in NHibernate format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + + $columns_cnt = PMA_DBI_num_fields($result); + for ($i = 0; $i < $columns_cnt; $i++) { + $columns[$i] = stripslashes(PMA_DBI_field_name($result, $i)); + } + unset($i); + + // fix variable names (based on + // http://www.php.net/manual/language.variables.basics.php) + if (! preg_match( + '/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', + $table + )) { + // fix invalid characters in variable names by replacing them with + // underscores + $tablefixed = preg_replace('/[^a-zA-Z0-9_\x7f-\xff]/', '_', $table); + + // variable name must not start with a number or dash... + if (preg_match('/^[a-zA-Z_\x7f-\xff]/', $tablefixed) == false) { + $tablefixed = '_' . $tablefixed; + } + } else { + $tablefixed = $table; + } + + $buffer = ''; + $record_cnt = 0; + // Output table name as comment + $buffer .= $crlf . '// ' + . PMA_Util::backquote($db) . '.' + . PMA_Util::backquote($table) . $crlf; + $buffer .= '$' . $tablefixed . ' = array('; + + while ($record = PMA_DBI_fetch_row($result)) { + $record_cnt++; + + if ($record_cnt == 1) { + $buffer .= $crlf . ' array('; + } else { + $buffer .= ',' . $crlf . ' array('; + } + + for ($i = 0; $i < $columns_cnt; $i++) { + $buffer .= var_export($columns[$i], true) + . " => " . var_export($record[$i], true) + . (($i + 1 >= $columns_cnt) ? '' : ','); + } + + $buffer .= ')'; + } + + $buffer .= $crlf . ');' . $crlf; + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + + PMA_DBI_free_result($result); + return true; + } +} +?> diff --git a/hugo/libraries/plugins/export/ExportSql.class.php b/hugo/libraries/plugins/export/ExportSql.class.php new file mode 100644 index 0000000..fade66e --- /dev/null +++ b/hugo/libraries/plugins/export/ExportSql.class.php @@ -0,0 +1,1888 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Set of functions used to build SQL dumps of tables + * + * @package PhpMyAdmin-Export + * @subpackage SQL + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/* Get the export interface */ +require_once 'libraries/plugins/ExportPlugin.class.php'; + +/** + * Handles the export for the SQL class + * + * @package PhpMyAdmin-Export + * @subpackage SQL + */ +class ExportSql extends ExportPlugin +{ + /** + * Constructor + */ + public function __construct() + { + $this->setProperties(); + + // Avoids undefined variables, use NULL so isset() returns false + if (! isset($GLOBALS['sql_backquotes'])) { + $GLOBALS['sql_backquotes'] = null; + } + } + + /** + * Sets the export SQL properties + * + * @return void + */ + protected function setProperties() + { + global $plugin_param; + + $hide_sql = false; + $hide_structure = false; + if ($plugin_param['export_type'] == 'table' + && ! $plugin_param['single_table'] + ) { + $hide_structure = true; + $hide_sql = true; + } + + if (! $hide_sql) { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/groups/OptionsPropertySubgroup.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + include_once "$props/options/items/MessageOnlyPropertyItem.class.php"; + include_once "$props/options/items/RadioPropertyItem.class.php"; + include_once "$props/options/items/SelectPropertyItem.class.php"; + include_once "$props/options/items/TextPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('SQL'); + $exportPluginProperties->setExtension('sql'); + $exportPluginProperties->setMimeType('text/x-sql'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + + // comments + $subgroup = new OptionsPropertySubgroup(); + $subgroup->setName("include_comments"); + $leaf = new BoolPropertyItem(); + $leaf->setName('include_comments'); + $leaf->setText( + __( + 'Display comments <i>(includes info such as export' + . ' timestamp, PHP version, and server version)</i>' + ) + ); + $subgroup->setSubgroupHeader($leaf); + + $leaf = new TextPropertyItem(); + $leaf->setName('header_comment'); + $leaf->setText( + __('Additional custom header comment (\n splits lines):') + ); + $subgroup->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName('dates'); + $leaf->setText( + __( + 'Include a timestamp of when databases were created, last' + . ' updated, and last checked' + ) + ); + $subgroup->addProperty($leaf); + if (! empty($GLOBALS['cfgRelation']['relation'])) { + $leaf = new BoolPropertyItem(); + $leaf->setName('relation'); + $leaf->setText(__('Display foreign key relationships')); + $subgroup->addProperty($leaf); + } + if (! empty($GLOBALS['cfgRelation']['mimework'])) { + $leaf = new BoolPropertyItem(); + $leaf->setName('mime'); + $leaf->setText(__('Display MIME types')); + $subgroup->addProperty($leaf); + } + $generalOptions->addProperty($subgroup); + + // enclose in a transaction + $leaf = new BoolPropertyItem(); + $leaf->setName("use_transaction"); + $leaf->setText(__('Enclose export in a transaction')); + $leaf->setDoc( + array( + 'programs', + 'mysqldump', + 'option_mysqldump_single-transaction' + ) + ); + $generalOptions->addProperty($leaf); + + // disable foreign key checks + $leaf = new BoolPropertyItem(); + $leaf->setName("disable_fk"); + $leaf->setText(__('Disable foreign key checks')); + $leaf->setDoc( + array( + 'manual_MySQL_Database_Administration', + 'server-system-variables', + 'sysvar_foreign_key_checks' + ) + ); + $generalOptions->addProperty($leaf); + + // compatibility maximization + $compats = PMA_DBI_getCompatibilities(); + if (count($compats) > 0) { + $values = array(); + foreach ($compats as $val) { + $values[$val] = $val; + } + + $leaf = new SelectPropertyItem(); + $leaf->setName("compatibility"); + $leaf->setText( + __( + 'Database system or older MySQL server to maximize output' + . ' compatibility with:' + ) + ); + $leaf->setValues($values); + $leaf->setDoc( + array( + 'manual_MySQL_Database_Administration', + 'Server_SQL_mode' + ) + ); + $generalOptions->addProperty($leaf); + + unset($values); + } + + // server export options + if ($plugin_param['export_type'] == 'server') { + $leaf = new BoolPropertyItem(); + $leaf->setName("drop_database"); + $leaf->setText( + sprintf(__('Add %s statement'), '<code>DROP DATABASE</code>') + ); + $generalOptions->addProperty($leaf); + } + + // what to dump (structure/data/both) + $subgroup = new OptionsPropertySubgroup(); + $subgroup->setName("dump_table"); + $subgroup->setText("Dump table"); + $leaf = new RadioPropertyItem(); + $leaf->setName('structure_or_data'); + $leaf->setValues( + array( + 'structure' => __('structure'), + 'data' => __('data'), + 'structure_and_data' => __('structure and data') + ) + ); + $subgroup->setSubgroupHeader($leaf); + $generalOptions->addProperty($subgroup); + + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + + // structure options main group + if (! $hide_structure) { + $structureOptions = new OptionsPropertyMainGroup(); + $structureOptions->setName("structure"); + $structureOptions->setText(__('Object creation options')); + $structureOptions->setForce('data'); + + // begin SQL Statements + $subgroup = new OptionsPropertySubgroup(); + $leaf = new MessageOnlyPropertyItem(); + $leaf->setName('add_statements'); + $leaf->setText(__('Add statements:')); + $subgroup->setSubgroupHeader($leaf); + + if ($plugin_param['export_type'] != 'table') { + $leaf = new BoolPropertyItem(); + $leaf->setName('create_database'); + $create_clause = '<code>CREATE DATABASE / USE</code>'; + $leaf->setText(sprintf(__('Add %s statement'), $create_clause)); + $subgroup->addProperty($leaf); + } + + if ($plugin_param['export_type'] == 'table') { + if (PMA_Table::isView($GLOBALS['db'], $GLOBALS['table'])) { + $drop_clause = '<code>DROP VIEW</code>'; + } else { + $drop_clause = '<code>DROP TABLE</code>'; + } + } else { + if (PMA_DRIZZLE) { + $drop_clause = '<code>DROP TABLE</code>'; + } else { + $drop_clause = '<code>DROP TABLE / VIEW / PROCEDURE' + . ' / FUNCTION</code>'; + if (PMA_MYSQL_INT_VERSION > 50100) { + $drop_clause .= '<code> / EVENT</code>'; + } + } + } + $leaf = new BoolPropertyItem(); + $leaf->setName('drop_table'); + $leaf->setText(sprintf(__('Add %s statement'), $drop_clause)); + $subgroup->addProperty($leaf); + // Drizzle doesn't support procedures and functions + if (! PMA_DRIZZLE) { + $leaf = new BoolPropertyItem(); + $leaf->setName('procedure_function'); + $leaf->setText( + sprintf( + __('Add %s statement'), + '<code>CREATE PROCEDURE / FUNCTION' + . (PMA_MYSQL_INT_VERSION > 50100 + ? ' / EVENT</code>' : '</code>') + ) + ); + $subgroup->addProperty($leaf); + } + + // begin CREATE TABLE statements + $subgroup_create_table = new OptionsPropertySubgroup(); + $leaf = new BoolPropertyItem(); + $leaf->setName('create_table_statements'); + $leaf->setText(__('<code>CREATE TABLE</code> options:')); + $subgroup_create_table->setSubgroupHeader($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName('if_not_exists'); + $leaf->setText('<code>IF NOT EXISTS</code>'); + $subgroup_create_table->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName('auto_increment'); + $leaf->setText('<code>AUTO_INCREMENT</code>'); + $subgroup_create_table->addProperty($leaf); + $subgroup->addProperty($subgroup_create_table); + $structureOptions->addProperty($subgroup); + + $leaf = new BoolPropertyItem(); + $leaf->setName("backquotes"); + $leaf->setText( + __( + 'Enclose table and column names with backquotes ' + . '<i>(Protects column and table names formed with' + . ' special characters or keywords)</i>' + ) + ); + + $structureOptions->addProperty($leaf); + + // add the main group to the root group + $exportSpecificOptions->addProperty($structureOptions); + } + + + // begin Data options + $dataOptions = new OptionsPropertyMainGroup(); + $dataOptions->setName("data"); + $dataOptions->setText(__('Data creation options')); + $dataOptions->setForce('structure'); + $leaf = new BoolPropertyItem(); + $leaf->setName("truncate"); + $leaf->setText(__('Truncate table before insert')); + $dataOptions->addProperty($leaf); + + // begin SQL Statements + $subgroup = new OptionsPropertySubgroup(); + $leaf = new MessageOnlyPropertyItem(); + $leaf->setText(__('Instead of <code>INSERT</code> statements, use:')); + $subgroup->setSubgroupHeader($leaf); + // Not supported in Drizzle + if (! PMA_DRIZZLE) { + $leaf = new BoolPropertyItem(); + $leaf->setName("delayed"); + $leaf->setText(__('<code>INSERT DELAYED</code> statements')); + $leaf->setDoc( + array( + 'manual_MySQL_Database_Administration', + 'insert_delayed' + ) + ); + $subgroup->addProperty($leaf); + } + $leaf = new BoolPropertyItem(); + $leaf->setName("ignore"); + $leaf->setText(__('<code>INSERT IGNORE</code> statements')); + $leaf->setDoc( + array( + 'manual_MySQL_Database_Administration', + 'insert' + ) + ); + $subgroup->addProperty($leaf); + $dataOptions->addProperty($subgroup); + + // Function to use when dumping dat + $leaf = new SelectPropertyItem(); + $leaf->setName("type"); + $leaf->setText(__('Function to use when dumping data:')); + $leaf->setValues( + array( + 'INSERT' => 'INSERT', + 'UPDATE' => 'UPDATE', + 'REPLACE' => 'REPLACE' + ) + ); + $dataOptions->addProperty($leaf); + + /* Syntax to use when inserting data */ + $subgroup = new OptionsPropertySubgroup(); + $leaf = new MessageOnlyPropertyItem(); + $leaf->setText(__('Syntax to use when inserting data:')); + $subgroup->setSubgroupHeader($leaf); + $leaf = new RadioPropertyItem(); + $leaf->setName("insert_syntax"); + $leaf->setText(__('<code>INSERT IGNORE</code> statements')); + $leaf->setValues( + array( + 'complete' => __( + 'include column names in every <code>INSERT</code> statement' + . ' <br /> Example: <code>INSERT INTO' + . ' tbl_name (col_A,col_B,col_C) VALUES (1,2,3)</code>' + ), + 'extended' => __( + 'insert multiple rows in every <code>INSERT</code> statement' + . '<br /> Example: <code>INSERT INTO' + . ' tbl_name VALUES (1,2,3), (4,5,6), (7,8,9)</code>' + ), + 'both' => __( + 'both of the above<br /> Example:' + . ' <code>INSERT INTO tbl_name (col_A,col_B) VALUES (1,2,3),' + . ' (4,5,6), (7,8,9)</code>' + ), + 'none' => __( + 'neither of the above<br /> Example:' + . ' <code>INSERT INTO tbl_name VALUES (1,2,3)</code>' + ) + ) + ); + $subgroup->addProperty($leaf); + $dataOptions->addProperty($subgroup); + + // Max length of query + $leaf = new TextPropertyItem(); + $leaf->setName("max_query_size"); + $leaf->setText(__('Maximal length of created query')); + $dataOptions->addProperty($leaf); + + // Dump binary columns in hexadecimal + $leaf = new BoolPropertyItem(); + $leaf->setName("hex_for_blob"); + $leaf->setText( + __( + 'Dump binary columns in hexadecimal notation' + . ' <i>(for example, "abc" becomes 0x616263)</i>' + ) + ); + $dataOptions->addProperty($leaf); + + // Drizzle works only with UTC timezone + if (! PMA_DRIZZLE) { + // Dump time in UTC + $leaf = new BoolPropertyItem(); + $leaf->setName("utc_time"); + $leaf->setText( + __( + 'Dump TIMESTAMP columns in UTC <i>(enables TIMESTAMP columns' + . ' to be dumped and reloaded between servers in different' + . ' time zones)</i>' + ) + ); + $dataOptions->addProperty($leaf); + } + + // add the main group to the root group + $exportSpecificOptions->addProperty($dataOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Exports routines (procedures and functions) + * + * @param string $db Database + * + * @return bool Whether it succeeded + */ + public function exportRoutines($db) + { + global $crlf; + + $text = ''; + $delimiter = '$$'; + + $procedure_names = PMA_DBI_get_procedures_or_functions($db, 'PROCEDURE'); + $function_names = PMA_DBI_get_procedures_or_functions($db, 'FUNCTION'); + + if ($procedure_names || $function_names) { + $text .= $crlf + . 'DELIMITER ' . $delimiter . $crlf; + } + + if ($procedure_names) { + $text .= + $this->_exportComment() + . $this->_exportComment(__('Procedures')) + . $this->_exportComment(); + + foreach ($procedure_names as $procedure_name) { + if (! empty($GLOBALS['sql_drop_table'])) { + $text .= 'DROP PROCEDURE IF EXISTS ' + . PMA_Util::backquote($procedure_name) + . $delimiter . $crlf; + } + $text .= PMA_DBI_get_definition($db, 'PROCEDURE', $procedure_name) + . $delimiter . $crlf . $crlf; + } + } + + if ($function_names) { + $text .= + $this->_exportComment() + . $this->_exportComment(__('Functions')) + . $this->_exportComment(); + + foreach ($function_names as $function_name) { + if (! empty($GLOBALS['sql_drop_table'])) { + $text .= 'DROP FUNCTION IF EXISTS ' + . PMA_Util::backquote($function_name) + . $delimiter . $crlf; + } + $text .= PMA_DBI_get_definition($db, 'FUNCTION', $function_name) + . $delimiter . $crlf . $crlf; + } + } + + if ($procedure_names || $function_names) { + $text .= 'DELIMITER ;' . $crlf; + } + + if (! empty($text)) { + return PMA_exportOutputHandler($text); + } else { + return false; + } + } + + /** + * Possibly outputs comment + * + * @param string $text Text of comment + * + * @return string The formatted comment + */ + private function _exportComment($text = '') + { + if (isset($GLOBALS['sql_include_comments']) + && $GLOBALS['sql_include_comments'] + ) { + // see http://dev.mysql.com/doc/refman/5.0/en/ansi-diff-comments.html + return '--' . (empty($text) ? '' : ' ') . $text . $GLOBALS['crlf']; + } else { + return ''; + } + } + + /** + * Possibly outputs CRLF + * + * @return string $crlf or nothing + */ + private function _possibleCRLF() + { + if (isset($GLOBALS['sql_include_comments']) + && $GLOBALS['sql_include_comments'] + ) { + return $GLOBALS['crlf']; + } else { + return ''; + } + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter() + { + global $crlf, $mysql_charset_map; + + $foot = ''; + + if (isset($GLOBALS['sql_disable_fk'])) { + $foot .= 'SET FOREIGN_KEY_CHECKS=1;' . $crlf; + } + + if (isset($GLOBALS['sql_use_transaction'])) { + $foot .= 'COMMIT;' . $crlf; + } + + // restore connection settings + $charset_of_file = isset($GLOBALS['charset_of_file']) + ? $GLOBALS['charset_of_file'] : ''; + if (! empty($GLOBALS['asfile']) + && isset($mysql_charset_map[$charset_of_file]) + && ! PMA_DRIZZLE + ) { + $foot .= $crlf + . '/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;' + . $crlf + . '/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;' + . $crlf + . '/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;' + . $crlf; + } + + /* Restore timezone */ + if (isset($GLOBALS['sql_utc_time']) && $GLOBALS['sql_utc_time']) { + PMA_DBI_query('SET time_zone = "' . $GLOBALS['old_tz'] . '"'); + } + + return PMA_exportOutputHandler($foot); + } + + /** + * Outputs export header. It is the first method to be called, so all + * the required variables are initialized here. + * + * @return bool Whether it succeeded + */ + public function exportHeader() + { + global $crlf, $cfg; + global $mysql_charset_map; + + if (isset($GLOBALS['sql_compatibility'])) { + $tmp_compat = $GLOBALS['sql_compatibility']; + if ($tmp_compat == 'NONE') { + $tmp_compat = ''; + } + PMA_DBI_try_query('SET SQL_MODE="' . $tmp_compat . '"'); + unset($tmp_compat); + } + $head = $this->_exportComment('phpMyAdmin SQL Dump') + . $this->_exportComment('version ' . PMA_VERSION) + . $this->_exportComment('http://www.phpmyadmin.net') + . $this->_exportComment(); + $host_string = __('Host') . ': ' . $cfg['Server']['host']; + if (! empty($cfg['Server']['port'])) { + $host_string .= ':' . $cfg['Server']['port']; + } + $head .= $this->_exportComment($host_string); + $head .= + $this->_exportComment( + __('Generation Time') . ': ' + . PMA_Util::localisedDate() + ) + . $this->_exportComment( + __('Server version') . ': ' . PMA_MYSQL_STR_VERSION + ) + . $this->_exportComment(__('PHP Version') . ': ' . phpversion()) + . $this->_possibleCRLF(); + + if (isset($GLOBALS['sql_header_comment']) + && ! empty($GLOBALS['sql_header_comment']) + ) { + // '\n' is not a newline (like "\n" would be), it's the characters + // backslash and n, as explained on the export interface + $lines = explode('\n', $GLOBALS['sql_header_comment']); + $head .= $this->_exportComment(); + foreach ($lines as $one_line) { + $head .= $this->_exportComment($one_line); + } + $head .= $this->_exportComment(); + } + + if (isset($GLOBALS['sql_disable_fk'])) { + $head .= 'SET FOREIGN_KEY_CHECKS=0;' . $crlf; + } + + // We want exported AUTO_INCREMENT columns to have still same value, + // do this only for recent MySQL exports + if ((! isset($GLOBALS['sql_compatibility']) + || $GLOBALS['sql_compatibility'] == 'NONE') + && ! PMA_DRIZZLE + ) { + $head .= 'SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";' . $crlf; + } + + if (isset($GLOBALS['sql_use_transaction'])) { + $head .= 'SET AUTOCOMMIT = 0;' . $crlf + . 'START TRANSACTION;' . $crlf; + } + + /* Change timezone if we should export timestamps in UTC */ + if (isset($GLOBALS['sql_utc_time']) && $GLOBALS['sql_utc_time']) { + $head .= 'SET time_zone = "+00:00";' . $crlf; + $GLOBALS['old_tz'] = PMA_DBI_fetch_value('SELECT @@session.time_zone'); + PMA_DBI_query('SET time_zone = "+00:00"'); + } + + $head .= $this->_possibleCRLF(); + + if (! empty($GLOBALS['asfile']) && ! PMA_DRIZZLE) { + // we are saving as file, therefore we provide charset information + // so that a utility like the mysql client can interpret + // the file correctly + if (isset($GLOBALS['charset_of_file']) + && isset($mysql_charset_map[$GLOBALS['charset_of_file']]) + ) { + // we got a charset from the export dialog + $set_names = $mysql_charset_map[$GLOBALS['charset_of_file']]; + } else { + // by default we use the connection charset + $set_names = $mysql_charset_map['utf-8']; + } + $head .= $crlf + . '/*!40101 SET @OLD_CHARACTER_SET_CLIENT=' + . '@@CHARACTER_SET_CLIENT */;' . $crlf + . '/*!40101 SET @OLD_CHARACTER_SET_RESULTS=' + . '@@CHARACTER_SET_RESULTS */;' . $crlf + . '/*!40101 SET @OLD_COLLATION_CONNECTION=' + . '@@COLLATION_CONNECTION */;'. $crlf + . '/*!40101 SET NAMES ' . $set_names . ' */;' . $crlf . $crlf; + } + + return PMA_exportOutputHandler($head); + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + global $crlf; + + if (isset($GLOBALS['sql_compatibility'])) { + $compat = $GLOBALS['sql_compatibility']; + } else { + $compat = 'NONE'; + } + if (isset($GLOBALS['sql_drop_database'])) { + if (! PMA_exportOutputHandler( + 'DROP DATABASE ' + . (isset($GLOBALS['sql_backquotes']) + ? PMA_Util::backquoteCompat($db, $compat) : $db) + . ';' . $crlf + )) { + return false; + } + } + if (isset($GLOBALS['sql_create_database'])) { + $create_query = 'CREATE DATABASE IF NOT EXISTS ' + . (isset($GLOBALS['sql_backquotes']) + ? PMA_Util::backquoteCompat($db, $compat) : $db); + $collation = PMA_getDbCollation($db); + if (PMA_DRIZZLE) { + $create_query .= ' COLLATE ' . $collation; + } else { + if (strpos($collation, '_')) { + $create_query .= ' DEFAULT CHARACTER SET ' + . substr($collation, 0, strpos($collation, '_')) + . ' COLLATE ' . $collation; + } else { + $create_query .= ' DEFAULT CHARACTER SET ' . $collation; + } + } + $create_query .= ';' . $crlf; + if (! PMA_exportOutputHandler($create_query)) { + return false; + } + if (isset($GLOBALS['sql_backquotes']) + && ((isset($GLOBALS['sql_compatibility']) + && $GLOBALS['sql_compatibility'] == 'NONE') + || PMA_DRIZZLE) + ) { + $result = PMA_exportOutputHandler( + 'USE ' . PMA_Util::backquoteCompat($db, $compat) + . ';' . $crlf + ); + } else { + $result = PMA_exportOutputHandler('USE ' . $db . ';' . $crlf); + } + return $result; + } else { + return true; + } + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader($db) + { + if (isset($GLOBALS['sql_compatibility'])) { + $compat = $GLOBALS['sql_compatibility']; + } else { + $compat = 'NONE'; + } + $head = $this->_exportComment() + . $this->_exportComment( + __('Database') . ': ' + . (isset($GLOBALS['sql_backquotes']) + ? PMA_Util::backquoteCompat($db, $compat) + : '\'' . $db . '\'') + ) + . $this->_exportComment(); + return PMA_exportOutputHandler($head); + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter($db) + { + global $crlf; + + $result = true; + if (isset($GLOBALS['sql_constraints'])) { + $result = PMA_exportOutputHandler($GLOBALS['sql_constraints']); + unset($GLOBALS['sql_constraints']); + } + + if (($GLOBALS['sql_structure_or_data'] == 'structure' + || $GLOBALS['sql_structure_or_data'] == 'structure_and_data') + && isset($GLOBALS['sql_procedure_function']) + ) { + $text = ''; + $delimiter = '$$'; + + if (PMA_MYSQL_INT_VERSION > 50100) { + $event_names = PMA_DBI_fetch_result( + 'SELECT EVENT_NAME FROM information_schema.EVENTS WHERE' + . ' EVENT_SCHEMA= \'' + . PMA_Util::sqlAddSlashes($db, true) + . '\';' + ); + } else { + $event_names = array(); + } + + if ($event_names) { + $text .= $crlf + . 'DELIMITER ' . $delimiter . $crlf; + + $text .= + $this->_exportComment() + . $this->_exportComment(__('Events')) + . $this->_exportComment(); + + foreach ($event_names as $event_name) { + if (! empty($GLOBALS['sql_drop_table'])) { + $text .= 'DROP EVENT ' + . PMA_Util::backquote($event_name) + . $delimiter . $crlf; + } + $text .= PMA_DBI_get_definition($db, 'EVENT', $event_name) + . $delimiter . $crlf . $crlf; + } + + $text .= 'DELIMITER ;' . $crlf; + } + + if (! empty($text)) { + $result = PMA_exportOutputHandler($text); + } + } + return $result; + } + + /** + * Returns a stand-in CREATE definition to resolve view dependencies + * + * @param string $db the database name + * @param string $view the view name + * @param string $crlf the end of line sequence + * + * @return string resulting definition + */ + public function getTableDefStandIn($db, $view, $crlf) + { + $create_query = ''; + if (! empty($GLOBALS['sql_drop_table'])) { + $create_query .= 'DROP VIEW IF EXISTS ' + . PMA_Util::backquote($view) + . ';' . $crlf; + } + + $create_query .= 'CREATE TABLE '; + + if (isset($GLOBALS['sql_if_not_exists']) + && $GLOBALS['sql_if_not_exists'] + ) { + $create_query .= 'IF NOT EXISTS '; + } + $create_query .= PMA_Util::backquote($view) . ' (' . $crlf; + $tmp = array(); + $columns = PMA_DBI_get_columns_full($db, $view); + foreach ($columns as $column_name => $definition) { + $tmp[] = PMA_Util::backquote($column_name) . ' ' . + $definition['Type'] . $crlf; + } + $create_query .= implode(',', $tmp) . ');'; + return($create_query); + } + + /** + * Returns $table's CREATE definition + * + * @param string $db the database name + * @param string $table the table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param bool $show_dates whether to include creation/update/check + * dates + * @param bool $add_semicolon whether to add semicolon and end-of-line at + * the end + * @param bool $view whether we're handling a view + * + * @return string resulting schema + */ + public function getTableDef( + $db, + $table, + $crlf, + $error_url, + $show_dates = false, + $add_semicolon = true, + $view = false + ) { + global $sql_drop_table, $sql_backquotes, $sql_constraints, + $sql_constraints_query, $sql_drop_foreign_keys; + + $schema_create = ''; + $auto_increment = ''; + $new_crlf = $crlf; + + if (isset($GLOBALS['sql_compatibility'])) { + $compat = $GLOBALS['sql_compatibility']; + } else { + $compat = 'NONE'; + } + + // need to use PMA_DBI_QUERY_STORE with PMA_DBI_num_rows() in mysqli + $result = PMA_DBI_query( + 'SHOW TABLE STATUS FROM ' . PMA_Util::backquote($db) + . ' LIKE \'' . PMA_Util::sqlAddSlashes($table, true) . '\'', + null, + PMA_DBI_QUERY_STORE + ); + if ($result != false) { + if (PMA_DBI_num_rows($result) > 0) { + $tmpres = PMA_DBI_fetch_assoc($result); + if (PMA_DRIZZLE && $show_dates) { + // Drizzle doesn't give Create_time and Update_time in + // SHOW TABLE STATUS, add it + $sql ="SELECT + TABLE_CREATION_TIME AS Create_time, + TABLE_UPDATE_TIME AS Update_time + FROM data_dictionary.TABLES + WHERE TABLE_SCHEMA = '" + . PMA_Util::sqlAddSlashes($db) . "' + AND TABLE_NAME = '" + . PMA_Util::sqlAddSlashes($table) . "'"; + $tmpres = array_merge(PMA_DBI_fetch_single_row($sql), $tmpres); + } + // Here we optionally add the AUTO_INCREMENT next value, + // but starting with MySQL 5.0.24, the clause is already included + // in SHOW CREATE TABLE so we'll remove it below + // It's required for Drizzle because SHOW CREATE TABLE uses + // the value from table's creation time + if (isset($GLOBALS['sql_auto_increment']) + && ! empty($tmpres['Auto_increment']) + ) { + $auto_increment .= ' AUTO_INCREMENT=' + . $tmpres['Auto_increment'] . ' '; + } + + if ($show_dates + && isset($tmpres['Create_time']) + && ! empty($tmpres['Create_time']) + ) { + $schema_create .= $this->_exportComment( + __('Creation') . ': ' + . PMA_Util::localisedDate( + strtotime($tmpres['Create_time']) + ) + ); + $new_crlf = $this->_exportComment() . $crlf; + } + + if ($show_dates + && isset($tmpres['Update_time']) + && ! empty($tmpres['Update_time']) + ) { + $schema_create .= $this->_exportComment( + __('Last update') . ': ' + . PMA_Util::localisedDate( + strtotime($tmpres['Update_time']) + ) + ); + $new_crlf = $this->_exportComment() . $crlf; + } + + if ($show_dates + && isset($tmpres['Check_time']) + && ! empty($tmpres['Check_time']) + ) { + $schema_create .= $this->_exportComment( + __('Last check') . ': ' + . PMA_Util::localisedDate( + strtotime($tmpres['Check_time']) + ) + ); + $new_crlf = $this->_exportComment() . $crlf; + } + } + PMA_DBI_free_result($result); + } + + $schema_create .= $new_crlf; + + // no need to generate a DROP VIEW here, it was done earlier + if (! empty($sql_drop_table) && ! PMA_Table::isView($db, $table)) { + $schema_create .= 'DROP TABLE IF EXISTS ' + . PMA_Util::backquote($table, $sql_backquotes) . ';' + . $crlf; + } + + // Complete table dump, + // Whether to quote table and column names or not + // Drizzle always quotes names + if (! PMA_DRIZZLE) { + if ($sql_backquotes) { + PMA_DBI_query('SET SQL_QUOTE_SHOW_CREATE = 1'); + } else { + PMA_DBI_query('SET SQL_QUOTE_SHOW_CREATE = 0'); + } + } + + // I don't see the reason why this unbuffered query could cause problems, + // because SHOW CREATE TABLE returns only one row, and we free the + // results below. Nonetheless, we got 2 user reports about this + // (see bug 1562533) so I removed the unbuffered mode. + // $result = PMA_DBI_query('SHOW CREATE TABLE ' . backquote($db) + // . '.' . backquote($table), null, PMA_DBI_QUERY_UNBUFFERED); + // + // Note: SHOW CREATE TABLE, at least in MySQL 5.1.23, does not + // produce a displayable result for the default value of a BIT + // column, nor does the mysqldump command. See MySQL bug 35796 + $result = PMA_DBI_try_query( + 'SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.' + . PMA_Util::backquote($table) + ); + // an error can happen, for example the table is crashed + $tmp_error = PMA_DBI_getError(); + if ($tmp_error) { + return $this->_exportComment(__('in use') . '(' . $tmp_error . ')'); + } + + if ($result != false && ($row = PMA_DBI_fetch_row($result))) { + $create_query = $row[1]; + unset($row); + + // Convert end of line chars to one that we want (note that MySQL + // doesn't return query it will accept in all cases) + if (strpos($create_query, "(\r\n ")) { + $create_query = str_replace("\r\n", $crlf, $create_query); + } elseif (strpos($create_query, "(\n ")) { + $create_query = str_replace("\n", $crlf, $create_query); + } elseif (strpos($create_query, "(\r ")) { + $create_query = str_replace("\r", $crlf, $create_query); + } + + /* + * Drop database name from VIEW creation. + * + * This is a bit tricky, but we need to issue SHOW CREATE TABLE with + * database name, but we don't want name to show up in CREATE VIEW + * statement. + */ + if ($view) { + $create_query = preg_replace( + '/' . PMA_Util::backquote($db) . '\./', + '', + $create_query + ); + } + + // Should we use IF NOT EXISTS? + // It always must be OFF for MSSQL compatibility mode + if (isset($GLOBALS['sql_if_not_exists']) && $compat != 'MSSQL') { + $create_query = preg_replace( + '/^CREATE TABLE/', + 'CREATE TABLE IF NOT EXISTS', + $create_query + ); + } + + // In MSSQL + // 1. DATE field doesn't exists, we will use DATETIME instead + // 2. UNSIGNED attribute doesn't exist + // 3. No length on INT, TINYINT, SMALLINT, BIGINT and no precision on + // FLOAT fields + // 4. No KEY and INDEX inside CREATE TABLE + // 5. DOUBLE field doesn't exists, we will use FLOAT instead + if ($compat == 'MSSQL') { + // first we need to replace all lines ended with '" DATE ...,\n' + // last preg_replace preserve us from situation with date text + // inside DEFAULT field value + $create_query = preg_replace( + "/\" date DEFAULT NULL(,)?\n/", + '" datetime DEFAULT NULL$1' . "\n", + $create_query + ); + $create_query = preg_replace( + "/\" date NOT NULL(,)?\n/", + '" datetime NOT NULL$1' . "\n", + $create_query + ); + $create_query = preg_replace( + '/" date NOT NULL DEFAULT \'([^\'])/', + '" datetime NOT NULL DEFAULT \'$1', + $create_query + ); + + // next we need to replace all lines ended with ') UNSIGNED ...,' + // last preg_replace preserve us from situation with unsigned text + // inside DEFAULT field value + $create_query = preg_replace( + "/\) unsigned NOT NULL(,)?\n/", + ') NOT NULL$1' . "\n", + $create_query + ); + $create_query = preg_replace( + "/\) unsigned DEFAULT NULL(,)?\n/", + ') DEFAULT NULL$1' . "\n", + $create_query + ); + $create_query = preg_replace( + '/\) unsigned NOT NULL DEFAULT \'([^\'])/', + ') NOT NULL DEFAULT \'$1', + $create_query + ); + + // we need to replace all lines ended with + // '" INT|TINYINT([0-9]{1,}) ...,' last preg_replace preserve us + // from situation with int([0-9]{1,}) text inside DEFAULT field + // value + $create_query = preg_replace( + '/" (int|tinyint|smallint|bigint)\([0-9]+\) DEFAULT NULL(,)?\n/', + '" $1 DEFAULT NULL$2' . "\n", + $create_query + ); + $create_query = preg_replace( + '/" (int|tinyint|smallint|bigint)\([0-9]+\) NOT NULL(,)?\n/', + '" $1 NOT NULL$2' . "\n", + $create_query + ); + $create_query = preg_replace( + '/" (int|tinyint|smallint|bigint)\([0-9]+\) NOT NULL DEFAULT \'([^\'])/', + '" $1 NOT NULL DEFAULT \'$2', + $create_query + ); + + // we need to replace all lines ended with + // '" FLOAT|DOUBLE([0-9,]{1,}) ...,' + // last preg_replace preserve us from situation with + // float([0-9,]{1,}) text inside DEFAULT field value + $create_query = preg_replace( + '/" (float|double)(\([0-9]+,[0-9,]+\))? DEFAULT NULL(,)?\n/', + '" float DEFAULT NULL$3' . "\n", + $create_query + ); + $create_query = preg_replace( + '/" (float|double)(\([0-9,]+,[0-9,]+\))? NOT NULL(,)?\n/', + '" float NOT NULL$3' . "\n", + $create_query + ); + $create_query = preg_replace( + '/" (float|double)(\([0-9,]+,[0-9,]+\))? NOT NULL DEFAULT \'([^\'])/', + '" float NOT NULL DEFAULT \'$3', + $create_query + ); + + // @todo remove indexes from CREATE TABLE + } + + // Drizzle (checked on 2011.03.13) returns ROW_FORMAT surrounded + // with quotes, which is not accepted by parser + if (PMA_DRIZZLE) { + $create_query = preg_replace( + '/ROW_FORMAT=\'(\S+)\'/', + 'ROW_FORMAT=$1', + $create_query + ); + } + + // are there any constraints to cut out? + if (preg_match('@CONSTRAINT|FOREIGN[\s]+KEY@', $create_query)) { + + // Split the query into lines, so we can easily handle it. + // We know lines are separated by $crlf (done few lines above). + $sql_lines = explode($crlf, $create_query); + $sql_count = count($sql_lines); + + // lets find first line with constraints + for ($i = 0; $i < $sql_count; $i++) { + if (preg_match( + '@^[\s]*(CONSTRAINT|FOREIGN[\s]+KEY)@', + $sql_lines[$i] + )) { + break; + } + } + + // If we really found a constraint + if ($i != $sql_count) { + + // remove, from the end of create statement + $sql_lines[$i - 1] = preg_replace( + '@,$@', + '', + $sql_lines[$i - 1] + ); + + // prepare variable for constraints + if (! isset($sql_constraints)) { + if (isset($GLOBALS['no_constraints_comments'])) { + $sql_constraints = ''; + } else { + $sql_constraints = $crlf + . $this->_exportComment() + . $this->_exportComment( + __('Constraints for dumped tables') + ) + . $this->_exportComment(); + } + } + + // comments for current table + if (! isset($GLOBALS['no_constraints_comments'])) { + $sql_constraints .= $crlf + . $this->_exportComment() + . $this->_exportComment( + __('Constraints for table') + . ' ' + . PMA_Util::backquoteCompat($table, $compat) + ) + . $this->_exportComment(); + } + + // let's do the work + $sql_constraints_query .= 'ALTER TABLE ' + . PMA_Util::backquoteCompat($table, $compat) + . $crlf; + $sql_constraints .= 'ALTER TABLE ' + . PMA_Util::backquoteCompat($table, $compat) + . $crlf; + $sql_drop_foreign_keys .= 'ALTER TABLE ' + . PMA_Util::backquoteCompat($db, $compat) . '.' + . PMA_Util::backquoteCompat($table, $compat) + . $crlf; + + $first = true; + for ($j = $i; $j < $sql_count; $j++) { + if (preg_match( + '@CONSTRAINT|FOREIGN[\s]+KEY@', + $sql_lines[$j] + )) { + if (! $first) { + $sql_constraints .= $crlf; + } + if (strpos($sql_lines[$j], 'CONSTRAINT') === false) { + $tmp_str = preg_replace( + '/(FOREIGN[\s]+KEY)/', + 'ADD \1', + $sql_lines[$j] + ); + $sql_constraints_query .= $tmp_str; + $sql_constraints .= $tmp_str; + } else { + $tmp_str = preg_replace( + '/(CONSTRAINT)/', + 'ADD \1', + $sql_lines[$j] + ); + $sql_constraints_query .= $tmp_str; + $sql_constraints .= $tmp_str; + preg_match( + '/(CONSTRAINT)([\s])([\S]*)([\s])/', + $sql_lines[$j], + $matches + ); + if (! $first) { + $sql_drop_foreign_keys .= ', '; + } + $sql_drop_foreign_keys .= 'DROP FOREIGN KEY ' + . $matches[3]; + } + $first = false; + } else { + break; + } + } + $sql_constraints .= ';' . $crlf; + $sql_constraints_query .= ';'; + + $create_query = implode( + $crlf, + array_slice($sql_lines, 0, $i) + ) + . $crlf + . implode( + $crlf, + array_slice($sql_lines, $j, $sql_count - 1) + ); + unset($sql_lines); + } + } + $schema_create .= $create_query; + } + + // remove a possible "AUTO_INCREMENT = value" clause + // that could be there starting with MySQL 5.0.24 + // in Drizzle it's useless as it contains the value given at table + // creation time + $schema_create = preg_replace( + '/AUTO_INCREMENT\s*=\s*([0-9])+/', + '', + $schema_create + ); + + $schema_create .= ($compat != 'MSSQL') ? $auto_increment : ''; + + PMA_DBI_free_result($result); + return $schema_create . ($add_semicolon ? ';' . $crlf : ''); + } // end of the 'getTableDef()' function + + /** + * Returns $table's comments, relations etc. + * + * @param string $db database name + * @param string $table table name + * @param string $crlf end of line sequence + * @param bool $do_relation whether to include relation comments + * @param bool $do_mime whether to include mime comments + * + * @return string resulting comments + */ + private function _getTableComments( + $db, + $table, + $crlf, + $do_relation = false, + $do_mime = false + ) { + global $cfgRelation, $sql_backquotes; + + $schema_create = ''; + + // Check if we can use Relations + if ($do_relation && ! empty($cfgRelation['relation'])) { + // Find which tables are related with the current one and write it in + // an array + $res_rel = PMA_getForeigners($db, $table); + + if ($res_rel && count($res_rel) > 0) { + $have_rel = true; + } else { + $have_rel = false; + } + } else { + $have_rel = false; + } // end if + + if ($do_mime && $cfgRelation['mimework']) { + if (! ($mime_map = PMA_getMIME($db, $table, true))) { + unset($mime_map); + } + } + + if (isset($mime_map) && count($mime_map) > 0) { + $schema_create .= $this->_possibleCRLF() + . $this->_exportComment() + . $this->_exportComment( + __('MIME TYPES FOR TABLE'). ' ' + . PMA_Util::backquote($table, $sql_backquotes) . ':' + ); + @reset($mime_map); + foreach ($mime_map AS $mime_field => $mime) { + $schema_create .= + $this->_exportComment( + ' ' + . PMA_Util::backquote($mime_field, $sql_backquotes) + ) + . $this->_exportComment( + ' ' + . PMA_Util::backquote( + $mime['mimetype'], + $sql_backquotes + ) + ); + } + $schema_create .= $this->_exportComment(); + } + + if ($have_rel) { + $schema_create .= $this->_possibleCRLF() + . $this->_exportComment() + . $this->_exportComment( + __('RELATIONS FOR TABLE') . ' ' + . PMA_Util::backquote($table, $sql_backquotes) + . ':' + ); + foreach ($res_rel AS $rel_field => $rel) { + $schema_create .= + $this->_exportComment( + ' ' + . PMA_Util::backquote($rel_field, $sql_backquotes) + ) + . $this->_exportComment( + ' ' + . PMA_Util::backquote( + $rel['foreign_table'], + $sql_backquotes + ) + . ' -> ' + . PMA_Util::backquote( + $rel['foreign_field'], + $sql_backquotes + ) + ); + } + $schema_create .= $this->_exportComment(); + } + + return $schema_create; + + } // end of the '_getTableComments()' function + + /** + * Outputs table's structure + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $export_mode 'create_table','triggers','create_view', + * 'stand_in' + * @param string $export_type 'server', 'database', 'table' + * @param bool $relation whether to include relation comments + * @param bool $comments whether to include the pmadb-style column + * comments as comments in the structure; this is + * deprecated but the parameter is left here + * because export.php calls exportStructure() + * also for other export types which use this + * parameter + * @param bool $mime whether to include mime comments + * @param bool $dates whether to include creation/update/check dates + * + * @return bool Whether it succeeded + */ + public function exportStructure( + $db, + $table, + $crlf, + $error_url, + $export_mode, + $export_type, + $relation = false, + $comments = false, + $mime = false, + $dates = false + ) { + if (isset($GLOBALS['sql_compatibility'])) { + $compat = $GLOBALS['sql_compatibility']; + } else { + $compat = 'NONE'; + } + + $formatted_table_name = (isset($GLOBALS['sql_backquotes'])) + ? PMA_Util::backquoteCompat($table, $compat) + : '\'' . $table . '\''; + $dump = $this->_possibleCRLF() + . $this->_exportComment(str_repeat('-', 56)) + . $this->_possibleCRLF() + . $this->_exportComment(); + + switch($export_mode) { + case 'create_table': + $dump .= $this->_exportComment( + __('Table structure for table') . ' '. $formatted_table_name + ); + $dump .= $this->_exportComment(); + $dump .= $this->getTableDef($db, $table, $crlf, $error_url, $dates); + $dump .= $this->_getTableComments($db, $table, $crlf, $relation, $mime); + break; + case 'triggers': + $dump = ''; + $triggers = PMA_DBI_get_triggers($db, $table); + if ($triggers) { + $dump .= $this->_possibleCRLF() + . $this->_exportComment() + . $this->_exportComment( + __('Triggers') . ' ' . $formatted_table_name + ) + . $this->_exportComment(); + $delimiter = '//'; + foreach ($triggers as $trigger) { + $dump .= $trigger['drop'] . ';' . $crlf; + $dump .= 'DELIMITER ' . $delimiter . $crlf; + $dump .= $trigger['create']; + $dump .= 'DELIMITER ;' . $crlf; + } + } + break; + case 'create_view': + $dump .= + $this->_exportComment( + __('Structure for view') + . ' ' + . $formatted_table_name + ) + . $this->_exportComment(); + // delete the stand-in table previously created (if any) + if ($export_type != 'table') { + $dump .= 'DROP TABLE IF EXISTS ' + . PMA_Util::backquote($table) . ';' . $crlf; + } + $dump .= $this->getTableDef( + $db, $table, $crlf, $error_url, $dates, true, true + ); + break; + case 'stand_in': + $dump .= + $this->_exportComment( + __('Stand-in structure for view') . ' ' . $formatted_table_name + ) + . $this->_exportComment(); + // export a stand-in definition to resolve view dependencies + $dump .= $this->getTableDefStandIn($db, $table, $crlf); + } // end switch + + // this one is built by getTableDef() to use in table copy/move + // but not in the case of export + unset($GLOBALS['sql_constraints_query']); + + return PMA_exportOutputHandler($dump); + } + + /** + * Outputs the content of a table in SQL format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + global $current_row, $sql_backquotes; + + if (isset($GLOBALS['sql_compatibility'])) { + $compat = $GLOBALS['sql_compatibility']; + } else { + $compat = 'NONE'; + } + + $formatted_table_name = (isset($GLOBALS['sql_backquotes'])) + ? PMA_Util::backquoteCompat($table, $compat) + : '\'' . $table . '\''; + + // Do not export data for a VIEW + // (For a VIEW, this is called only when exporting a single VIEW) + if (PMA_Table::isView($db, $table)) { + $head = $this->_possibleCRLF() + . $this->_exportComment() + . $this->_exportComment('VIEW ' . ' ' . $formatted_table_name) + . $this->_exportComment(__('Data') . ': ' . __('None')) + . $this->_exportComment() + . $this->_possibleCRLF(); + + if (! PMA_exportOutputHandler($head)) { + return false; + } + return true; + } + + // analyze the query to get the true column names, not the aliases + // (this fixes an undefined index, also if Complete inserts + // are used, we did not get the true column name in case of aliases) + $analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($sql_query)); + + $result = PMA_DBI_try_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + // a possible error: the table has crashed + $tmp_error = PMA_DBI_getError(); + if ($tmp_error) { + return PMA_exportOutputHandler( + $this->_exportComment( + __('Error reading data:') . ' (' . $tmp_error . ')' + ) + ); + } + + if ($result != false) { + $fields_cnt = PMA_DBI_num_fields($result); + + // Get field information + $fields_meta = PMA_DBI_get_fields_meta($result); + $field_flags = array(); + for ($j = 0; $j < $fields_cnt; $j++) { + $field_flags[$j] = PMA_DBI_field_flags($result, $j); + } + + for ($j = 0; $j < $fields_cnt; $j++) { + if (isset($analyzed_sql[0]['select_expr'][$j]['column'])) { + $field_set[$j] = PMA_Util::backquoteCompat( + $analyzed_sql[0]['select_expr'][$j]['column'], + $compat, + $sql_backquotes + ); + } else { + $field_set[$j] = PMA_Util::backquoteCompat( + $fields_meta[$j]->name, + $compat, + $sql_backquotes + ); + } + } + + if (isset($GLOBALS['sql_type']) + && $GLOBALS['sql_type'] == 'UPDATE' + ) { + // update + $schema_insert = 'UPDATE '; + if (isset($GLOBALS['sql_ignore'])) { + $schema_insert .= 'IGNORE '; + } + // avoid EOL blank + $schema_insert .= PMA_Util::backquoteCompat( + $table, + $compat, + $sql_backquotes + ) . ' SET'; + } else { + // insert or replace + if (isset($GLOBALS['sql_type']) + && $GLOBALS['sql_type'] == 'REPLACE' + ) { + $sql_command = 'REPLACE'; + } else { + $sql_command = 'INSERT'; + } + + // delayed inserts? + if (isset($GLOBALS['sql_delayed'])) { + $insert_delayed = ' DELAYED'; + } else { + $insert_delayed = ''; + } + + // insert ignore? + if (isset($GLOBALS['sql_type']) + && $GLOBALS['sql_type'] == 'INSERT' + && isset($GLOBALS['sql_ignore']) + ) { + $insert_delayed .= ' IGNORE'; + } + //truncate table before insert + if (isset($GLOBALS['sql_truncate']) + && $GLOBALS['sql_truncate'] + && $sql_command == 'INSERT' + ) { + $truncate = 'TRUNCATE TABLE ' + . PMA_Util::backquoteCompat( + $table, + $compat, + $sql_backquotes + ) . ";"; + $truncatehead = $this->_possibleCRLF() + . $this->_exportComment() + . $this->_exportComment( + __('Truncate table before insert') . ' ' + . $formatted_table_name + ) + . $this->_exportComment() + . $crlf; + PMA_exportOutputHandler($truncatehead); + PMA_exportOutputHandler($truncate); + } else { + $truncate = ''; + } + + // scheme for inserting fields + if ($GLOBALS['sql_insert_syntax'] == 'complete' + || $GLOBALS['sql_insert_syntax'] == 'both' + ) { + $fields = implode(', ', $field_set); + $schema_insert = $sql_command . $insert_delayed .' INTO ' + . PMA_Util::backquoteCompat( + $table, + $compat, + $sql_backquotes + ) + // avoid EOL blank + . ' (' . $fields . ') VALUES'; + } else { + $schema_insert = $sql_command . $insert_delayed .' INTO ' + . PMA_Util::backquoteCompat( + $table, + $compat, + $sql_backquotes + ) + . ' VALUES'; + } + } + + //\x08\\x09, not required + $search = array("\x00", "\x0a", "\x0d", "\x1a"); + $replace = array('\0', '\n', '\r', '\Z'); + $current_row = 0; + $query_size = 0; + if (($GLOBALS['sql_insert_syntax'] == 'extended' + || $GLOBALS['sql_insert_syntax'] == 'both') + && (! isset($GLOBALS['sql_type']) + || $GLOBALS['sql_type'] != 'UPDATE') + ) { + $separator = ','; + $schema_insert .= $crlf; + } else { + $separator = ';'; + } + + while ($row = PMA_DBI_fetch_row($result)) { + if ($current_row == 0) { + $head = $this->_possibleCRLF() + . $this->_exportComment() + . $this->_exportComment( + __('Dumping data for table') . ' ' + . $formatted_table_name + ) + . $this->_exportComment() + . $crlf; + if (! PMA_exportOutputHandler($head)) { + return false; + } + } + // We need to SET IDENTITY_INSERT ON for MSSQL + if (isset($GLOBALS['sql_compatibility']) + && $GLOBALS['sql_compatibility'] == 'MSSQL' + && $current_row == 0 + ) { + if (! PMA_exportOutputHandler( + 'SET IDENTITY_INSERT ' + . PMA_Util::backquoteCompat( + $table, + $compat + ) + . ' ON ;'.$crlf + )) { + return false; + } + } + $current_row++; + for ($j = 0; $j < $fields_cnt; $j++) { + // NULL + if (! isset($row[$j]) || is_null($row[$j])) { + $values[] = 'NULL'; + } elseif ($fields_meta[$j]->numeric + && $fields_meta[$j]->type != 'timestamp' + && ! $fields_meta[$j]->blob + ) { + // a number + // timestamp is numeric on some MySQL 4.1, BLOBs are + // sometimes numeric + $values[] = $row[$j]; + } elseif (stristr($field_flags[$j], 'BINARY') + && $fields_meta[$j]->blob + && isset($GLOBALS['sql_hex_for_blob']) + ) { + // a true BLOB + // - mysqldump only generates hex data when the --hex-blob + // option is used, for fields having the binary attribute + // no hex is generated + // - a TEXT field returns type blob but a real blob + // returns also the 'binary' flag + + // empty blobs need to be different, but '0' is also empty + // :-( + if (empty($row[$j]) && $row[$j] != '0') { + $values[] = '\'\''; + } else { + $values[] = '0x' . bin2hex($row[$j]); + } + } elseif ($fields_meta[$j]->type == 'bit') { + // detection of 'bit' works only on mysqli extension + $values[] = "b'" . PMA_Util::sqlAddSlashes( + PMA_Util::printableBitValue( + $row[$j], $fields_meta[$j]->length + ) + ) + . "'"; + } else { + // something else -> treat as a string + $values[] = '\'' + . str_replace( + $search, $replace, + PMA_Util::sqlAddSlashes($row[$j]) + ) + . '\''; + } // end if + } // end for + + // should we make update? + if (isset($GLOBALS['sql_type']) + && $GLOBALS['sql_type'] == 'UPDATE' + ) { + + $insert_line = $schema_insert; + for ($i = 0; $i < $fields_cnt; $i++) { + if (0 == $i) { + $insert_line .= ' '; + } + if ($i > 0) { + // avoid EOL blank + $insert_line .= ','; + } + $insert_line .= $field_set[$i] . ' = ' . $values[$i]; + } + + list($tmp_unique_condition, $tmp_clause_is_unique) + = PMA_Util::getUniqueCondition( + $result, + $fields_cnt, + $fields_meta, + $row + ); + $insert_line .= ' WHERE ' . $tmp_unique_condition; + unset($tmp_unique_condition, $tmp_clause_is_unique); + + } else { + + // Extended inserts case + if ($GLOBALS['sql_insert_syntax'] == 'extended' + || $GLOBALS['sql_insert_syntax'] == 'both' + ) { + if ($current_row == 1) { + $insert_line = $schema_insert . '(' + . implode(', ', $values) . ')'; + } else { + $insert_line = '(' . implode(', ', $values) . ')'; + $sql_max_size = $GLOBALS['sql_max_query_size']; + if (isset($sql_max_size) + && $sql_max_size > 0 + && $query_size + strlen($insert_line) > $sql_max_size + ) { + if (! PMA_exportOutputHandler(';' . $crlf)) { + return false; + } + $query_size = 0; + $current_row = 1; + $insert_line = $schema_insert . $insert_line; + } + } + $query_size += strlen($insert_line); + // Other inserts case + } else { + $insert_line = $schema_insert + . '(' + . implode(', ', $values) + . ')'; + } + } + unset($values); + + if (! PMA_exportOutputHandler( + ($current_row == 1 ? '' : $separator . $crlf) + . $insert_line + )) { + return false; + } + + } // end while + + if ($current_row > 0) { + if (! PMA_exportOutputHandler(';' . $crlf)) { + return false; + } + } + + // We need to SET IDENTITY_INSERT OFF for MSSQL + if (isset($GLOBALS['sql_compatibility']) + && $GLOBALS['sql_compatibility'] == 'MSSQL' + && $current_row > 0 + ) { + $outputSucceeded = PMA_exportOutputHandler( + $crlf . 'SET IDENTITY_INSERT ' + . PMA_Util::backquoteCompat($table, $compat) + . ' OFF;' . $crlf + ); + if (! $outputSucceeded) { + return false; + } + } + } // end if ($result != false) + PMA_DBI_free_result($result); + + return true; + } // end of the 'exportData()' function +} diff --git a/hugo/libraries/plugins/export/ExportTexytext.class.php b/hugo/libraries/plugins/export/ExportTexytext.class.php new file mode 100644 index 0000000..3aa609c --- /dev/null +++ b/hugo/libraries/plugins/export/ExportTexytext.class.php @@ -0,0 +1,574 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Export to Texy! text. + * + * @package PhpMyAdmin-Export + * @subpackage Texy!text + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/* Get the export interface */ +require_once 'libraries/plugins/ExportPlugin.class.php'; + +/** + * Handles the export for the Texy! text class + * + * @package PhpMyAdmin-Export + * @subpackage Texy!text + */ +class ExportTexytext extends ExportPlugin +{ + /** + * Constructor + */ + public function __construct() + { + $this->setProperties(); + } + + /** + * Sets the export Texy! text properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/RadioPropertyItem.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + include_once "$props/options/items/TextPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('Texy! text'); + $exportPluginProperties->setExtension('txt'); + $exportPluginProperties->setMimeType('text/plain'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // what to dump (structure/data/both) main group + $dumpWhat = new OptionsPropertyMainGroup(); + $dumpWhat->setName("general_opts"); + $dumpWhat->setText(__('Dump table')); + // create primary items and add them to the group + $leaf = new RadioPropertyItem(); + $leaf->setName("structure_or_data"); + $leaf->setValues( + array( + 'structure' => __('structure'), + 'data' => __('data'), + 'structure_and_data' => __('structure and data') + ) + ); + $dumpWhat->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($dumpWhat); + + // data options main group + $dataOptions = new OptionsPropertyMainGroup(); + $dataOptions->setName("data"); + $dataOptions->setText(__('Data dump options')); + $dataOptions->setForce('structure'); + // create primary items and add them to the group + $leaf = new BoolPropertyItem(); + $leaf->setName("columns"); + $leaf->setText(__('Put columns names in the first row')); + $dataOptions->addProperty($leaf); + $leaf = new TextPropertyItem(); + $leaf->setName('null'); + $leaf->setText(__('Replace NULL with:')); + $dataOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($dataOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + return PMA_exportOutputHandler( + '===' . __('Database') . ' ' . $db . "\n\n" + ); + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + /** + * Outputs the content of a table in NHibernate format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + global $what; + + if (! PMA_exportOutputHandler( + '== ' . __('Dumping data for table') . ' ' . $table . "\n\n" + )) { + return false; + } + + // Gets the data from the database + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + $fields_cnt = PMA_DBI_num_fields($result); + + // If required, get fields name at the first line + if (isset($GLOBALS[$what . '_columns'])) { + $text_output = "|------\n"; + for ($i = 0; $i < $fields_cnt; $i++) { + $text_output .= '|' + . htmlspecialchars( + stripslashes(PMA_DBI_field_name($result, $i)) + ); + } // end for + $text_output .= "\n|------\n"; + if (! PMA_exportOutputHandler($text_output)) { + return false; + } + } // end if + + // Format the data + while ($row = PMA_DBI_fetch_row($result)) { + $text_output = ''; + for ($j = 0; $j < $fields_cnt; $j++) { + if (! isset($row[$j]) || is_null($row[$j])) { + $value = $GLOBALS[$what . '_null']; + } elseif ($row[$j] == '0' || $row[$j] != '') { + $value = $row[$j]; + } else { + $value = ' '; + } + $text_output .= '|' + . str_replace( + '|', '|', htmlspecialchars($value) + ); + } // end for + $text_output .= "\n"; + if (! PMA_exportOutputHandler($text_output)) { + return false; + } + } // end while + PMA_DBI_free_result($result); + + return true; + } + + /** + * Returns a stand-in CREATE definition to resolve view dependencies + * + * @param string $db the database name + * @param string $view the view name + * @param string $crlf the end of line sequence + * + * @return string resulting definition + */ + function getTableDefStandIn($db, $view, $crlf) + { + $text_output = ''; + + /** + * Get the unique keys in the table + */ + $unique_keys = array(); + $keys = PMA_DBI_get_table_indexes($db, $view); + foreach ($keys as $key) { + if ($key['Non_unique'] == 0) { + $unique_keys[] = $key['Column_name']; + } + } + + /** + * Gets fields properties + */ + PMA_DBI_select_db($db); + + /** + * Displays the table structure + */ + + $text_output .= "|------\n" + . '|' . __('Column') + . '|' . __('Type') + . '|' . __('Null') + . '|' . __('Default') + . "\n|------\n"; + + $columns = PMA_DBI_get_columns($db, $view); + foreach ($columns as $column) { + $text_output .= $this->formatOneColumnDefinition($column, $unique_keys); + $text_output .= "\n"; + } // end foreach + + return $text_output; + } + + /** + * Returns $table's CREATE definition + * + * @param string $db the database name + * @param string $table the table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column + * comments as comments in the structure; + * this is deprecated but the parameter is + * left here because export.php calls + * $this->exportStructure() also for other + * export types which use this parameter + * @param bool $do_mime whether to include mime comments + * @param bool $show_dates whether to include creation/update/check dates + * @param bool $add_semicolon whether to add semicolon and end-of-line + * at the end + * @param bool $view whether we're handling a view + * + * @return string resulting schema + */ + function getTableDef( + $db, + $table, + $crlf, + $error_url, + $do_relation, + $do_comments, + $do_mime, + $show_dates = false, + $add_semicolon = true, + $view = false + ) { + global $cfgRelation; + + $text_output = ''; + + /** + * Get the unique keys in the table + */ + $unique_keys = array(); + $keys = PMA_DBI_get_table_indexes($db, $table); + foreach ($keys as $key) { + if ($key['Non_unique'] == 0) { + $unique_keys[] = $key['Column_name']; + } + } + + /** + * Gets fields properties + */ + PMA_DBI_select_db($db); + + // Check if we can use Relations + if ($do_relation && ! empty($cfgRelation['relation'])) { + // Find which tables are related with the current one and write it in + // an array + $res_rel = PMA_getForeigners($db, $table); + + if ($res_rel && count($res_rel) > 0) { + $have_rel = true; + } else { + $have_rel = false; + } + } else { + $have_rel = false; + } // end if + + /** + * Displays the table structure + */ + + $columns_cnt = 4; + if ($do_relation && $have_rel) { + $columns_cnt++; + } + if ($do_comments && $cfgRelation['commwork']) { + $columns_cnt++; + } + if ($do_mime && $cfgRelation['mimework']) { + $columns_cnt++; + } + + $text_output .= "|------\n"; + $text_output .= '|' . __('Column'); + $text_output .= '|' . __('Type'); + $text_output .= '|' . __('Null'); + $text_output .= '|' . __('Default'); + if ($do_relation && $have_rel) { + $text_output .= '|' . __('Links to'); + } + if ($do_comments) { + $text_output .= '|' . __('Comments'); + $comments = PMA_getComments($db, $table); + } + if ($do_mime && $cfgRelation['mimework']) { + $text_output .= '|' . htmlspecialchars('MIME'); + $mime_map = PMA_getMIME($db, $table, true); + } + $text_output .= "\n|------\n"; + + $columns = PMA_DBI_get_columns($db, $table); + foreach ($columns as $column) { + $text_output .= $this->formatOneColumnDefinition($column, $unique_keys); + $field_name = $column['Field']; + + if ($do_relation && $have_rel) { + $text_output .= '|' + . (isset($res_rel[$field_name]) + ? htmlspecialchars( + $res_rel[$field_name]['foreign_table'] + . ' (' . $res_rel[$field_name]['foreign_field'] . ')' + ) + : ''); + } + if ($do_comments && $cfgRelation['commwork']) { + $text_output .= '|' + . (isset($comments[$field_name]) + ? htmlspecialchars($comments[$field_name]) + : ''); + } + if ($do_mime && $cfgRelation['mimework']) { + $text_output .= '|' + . (isset($mime_map[$field_name]) + ? htmlspecialchars( + str_replace('_', '/', $mime_map[$field_name]['mimetype']) + ) + : ''); + } + + $text_output .= "\n"; + } // end foreach + + return $text_output; + } // end of the '$this->getTableDef()' function + + /** + * Outputs triggers + * + * @param string $db database name + * @param string $table table name + * + * @return string Formatted triggers list + */ + function getTriggers($db, $table) + { + $text_output .= "|------\n"; + $text_output .= '|' . __('Column'); + $dump = "|------\n"; + $dump .= '|' . __('Name'); + $dump .= '|' . __('Time'); + $dump .= '|' . __('Event'); + $dump .= '|' . __('Definition'); + $dump .= "\n|------\n"; + + $triggers = PMA_DBI_get_triggers($db, $table); + + foreach ($triggers as $trigger) { + $dump .= '|' . $trigger['name']; + $dump .= '|' . $trigger['action_timing']; + $dump .= '|' . $trigger['event_manipulation']; + $dump .= '|' . + str_replace( + '|', + '|', + htmlspecialchars($trigger['definition']) + ); + $dump .= "\n"; + } + + return $dump; + } + + /** + * Outputs table's structure + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $export_mode 'create_table', 'triggers', 'create_view', + * 'stand_in' + * @param string $export_type 'server', 'database', 'table' + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column + * comments as comments in the structure; + * this is deprecated but the parameter is + * left here because export.php calls + * $this->exportStructure() also for other + * export types which use this parameter + * @param bool $do_mime whether to include mime comments + * @param bool $dates whether to include creation/update/check dates + * + * @return bool Whether it succeeded + */ + function exportStructure( + $db, + $table, + $crlf, + $error_url, + $export_mode, + $export_type, + $do_relation = false, + $do_comments = false, + $do_mime = false, + $dates = false + ) { + $dump = ''; + + switch($export_mode) { + case 'create_table': + $dump .= '== ' . __('Table structure for table') . ' ' .$table . "\n\n"; + $dump .= $this->getTableDef( + $db, $table, $crlf, $error_url, $do_relation, $do_comments, + $do_mime, $dates + ); + break; + case 'triggers': + $dump = ''; + $triggers = PMA_DBI_get_triggers($db, $table); + if ($triggers) { + $dump .= '== ' . __('Triggers') . ' ' .$table . "\n\n"; + $dump .= $this->getTriggers($db, $table); + } + break; + case 'create_view': + $dump .= '== ' . __('Structure for view') . ' ' .$table . "\n\n"; + $dump .= $this->getTableDef( + $db, $table, $crlf, $error_url, $do_relation, $do_comments, + $do_mime, $dates, true, true + ); + break; + case 'stand_in': + $dump .= '== ' . __('Stand-in structure for view') + . ' ' .$table . "\n\n"; + // export a stand-in definition to resolve view dependencies + $dump .= $this->getTableDefStandIn($db, $table, $crlf); + } // end switch + + return PMA_exportOutputHandler($dump); + } + + /** + * Formats the definition for one column + * + * @param array $column info about this column + * @param array $unique_keys unique keys for this table + * + * @return string Formatted column definition + */ + function formatOneColumnDefinition( + $column, $unique_keys + ) { + $extracted_columnspec + = PMA_Util::extractColumnSpec($column['Type']); + $type = $extracted_columnspec['print_type']; + if (empty($type)) { + $type = ' '; + } + + if (! isset($column['Default'])) { + if ($column['Null'] != 'NO') { + $column['Default'] = 'NULL'; + } + } + + $fmt_pre = ''; + $fmt_post = ''; + if (in_array($column['Field'], $unique_keys)) { + $fmt_pre = '**' . $fmt_pre; + $fmt_post = $fmt_post . '**'; + } + if ($column['Key']=='PRI') { + $fmt_pre = '//' . $fmt_pre; + $fmt_post = $fmt_post . '//'; + } + $definition = '|' + . $fmt_pre . htmlspecialchars($column['Field']) . $fmt_post; + $definition .= '|' . htmlspecialchars($type); + $definition .= '|' + . (($column['Null'] == '' || $column['Null'] == 'NO') + ? __('No') : __('Yes')); + $definition .= '|' + . htmlspecialchars( + isset($column['Default']) ? $column['Default'] : '' + ); + return $definition; + } +} +?>
\ No newline at end of file diff --git a/hugo/libraries/plugins/export/ExportXml.class.php b/hugo/libraries/plugins/export/ExportXml.class.php new file mode 100644 index 0000000..711824c --- /dev/null +++ b/hugo/libraries/plugins/export/ExportXml.class.php @@ -0,0 +1,536 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Set of functions used to build XML dumps of tables + * + * @package PhpMyAdmin-Export + * @subpackage XML + */ +if (! defined('PHPMYADMIN')) { + exit; +} +if (! strlen($GLOBALS['db'])) { /* Can't do server export */ + $GLOBALS['skip_import'] = true; + return; +} + +/* Get the export interface */ +require_once 'libraries/plugins/ExportPlugin.class.php'; + +/** + * Handles the export for the XML class + * + * @package PhpMyAdmin-Export + * @subpackage XML + */ +class ExportXml extends ExportPlugin +{ + /** + * Table name + * + * @var string + */ + private $_table; + + /** + * Table names + * + * @var array + */ + private $_tables; + + /** + * Constructor + */ + public function __construct() + { + $this->setProperties(); + } + + /** + * Initialize the local variables that are used for export PDF + * + * @return void + */ + protected function initSpecificVariables() + { + global $table, $tables; + $this->_setTable($table); + $this->_setTables($tables); + } + + /** + * Sets the export XML properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + include_once "$props/options/items/BoolPropertyItem.class.php"; + + // create the export plugin property item + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('XML'); + $exportPluginProperties->setExtension('xml'); + $exportPluginProperties->setMimeType('text/xml'); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new HiddenPropertyItem(); + $leaf->setName("structure_or_data"); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // export structure main group + $structure = new OptionsPropertyMainGroup(); + $structure->setName("structure"); + $structure->setText(__('Object creation options (all are recommended)')); + // create primary items and add them to the group + if (! PMA_DRIZZLE) { + $leaf = new BoolPropertyItem(); + $leaf->setName("export_functions"); + $leaf->setText(__('Functions')); + $structure->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName("export_procedures"); + $leaf->setText(__('Procedures')); + $structure->addProperty($leaf); + } + $leaf = new BoolPropertyItem(); + $leaf->setName("export_tables"); + $leaf->setText(__('Tables')); + $structure->addProperty($leaf); + if (! PMA_DRIZZLE) { + $leaf = new BoolPropertyItem(); + $leaf->setName("export_triggers"); + $leaf->setText(__('Triggers')); + $structure->addProperty($leaf); + $leaf = new BoolPropertyItem(); + $leaf->setName("export_views"); + $leaf->setText(__('Views')); + $structure->addProperty($leaf); + } + $exportSpecificOptions->addProperty($structure); + + // data main group + $data = new OptionsPropertyMainGroup(); + $data->setName("data"); + $data->setText(__('Data dump options')); + // create primary items and add them to the group + $leaf = new BoolPropertyItem(); + $leaf->setName("export_contents"); + $leaf->setText(__('Export contents')); + $data->addProperty($leaf); + $exportSpecificOptions->addProperty($data); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header. It is the first method to be called, so all + * the required variables are initialized here. + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + $this->initSpecificVariables(); + global $crlf, $cfg, $db; + $table = $this->_getTable(); + $tables = $this->_getTables(); + + $export_struct = isset($GLOBALS['xml_export_functions']) + || isset($GLOBALS['xml_export_procedures']) + || isset($GLOBALS['xml_export_tables']) + || isset($GLOBALS['xml_export_triggers']) + || isset($GLOBALS['xml_export_views']); + $export_data = isset($GLOBALS['xml_export_contents']) ? true : false; + + if ($GLOBALS['output_charset_conversion']) { + $charset = $GLOBALS['charset_of_file']; + } else { + $charset = 'utf-8'; + } + + $head = '<?xml version="1.0" encoding="' . $charset . '"?>' . $crlf + . '<!--' . $crlf + . '- phpMyAdmin XML Dump' . $crlf + . '- version ' . PMA_VERSION . $crlf + . '- http://www.phpmyadmin.net' . $crlf + . '-' . $crlf + . '- ' . __('Host') . ': ' . $cfg['Server']['host']; + if (! empty($cfg['Server']['port'])) { + $head .= ':' . $cfg['Server']['port']; + } + $head .= $crlf + . '- ' . __('Generation Time') . ': ' + . PMA_Util::localisedDate() . $crlf + . '- ' . __('Server version') . ': ' . PMA_MYSQL_STR_VERSION . $crlf + . '- ' . __('PHP Version') . ': ' . phpversion() . $crlf + . '-->' . $crlf . $crlf; + + $head .= '<pma_xml_export version="1.0"' + . (($export_struct) + ? ' xmlns:pma="http://www.phpmyadmin.net/some_doc_url/"' + : '') + . '>' . $crlf; + + if ($export_struct) { + if (PMA_DRIZZLE) { + $result = PMA_DBI_fetch_result( + "SELECT + 'utf8' AS DEFAULT_CHARACTER_SET_NAME, + DEFAULT_COLLATION_NAME + FROM data_dictionary.SCHEMAS + WHERE SCHEMA_NAME = '" + . PMA_Util::sqlAddSlashes($db) . "'" + ); + } else { + $result = PMA_DBI_fetch_result( + 'SELECT `DEFAULT_CHARACTER_SET_NAME`, `DEFAULT_COLLATION_NAME`' + . ' FROM `information_schema`.`SCHEMATA` WHERE `SCHEMA_NAME`' + . ' = \''.PMA_Util::sqlAddSlashes($db).'\' LIMIT 1' + ); + } + $db_collation = $result[0]['DEFAULT_COLLATION_NAME']; + $db_charset = $result[0]['DEFAULT_CHARACTER_SET_NAME']; + + $head .= ' <!--' . $crlf; + $head .= ' - Structure schemas' . $crlf; + $head .= ' -->' . $crlf; + $head .= ' <pma:structure_schemas>' . $crlf; + $head .= ' <pma:database name="' . htmlspecialchars($db) + . '" collation="' . $db_collation . '" charset="' . $db_charset + . '">' . $crlf; + + if (count($tables) == 0) { + $tables[] = $table; + } + + foreach ($tables as $table) { + // Export tables and views + $result = PMA_DBI_fetch_result( + 'SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.' + . PMA_Util::backquote($table), + 0 + ); + $tbl = $result[$table][1]; + + $is_view = PMA_Table::isView($db, $table); + + if ($is_view) { + $type = 'view'; + } else { + $type = 'table'; + } + + if ($is_view && ! isset($GLOBALS['xml_export_views'])) { + continue; + } + + if (! $is_view && ! isset($GLOBALS['xml_export_tables'])) { + continue; + } + + $head .= ' <pma:' . $type . ' name="' . $table . '">' + . $crlf; + + $tbl = " " . htmlspecialchars($tbl); + $tbl = str_replace("\n", "\n ", $tbl); + + $head .= $tbl . ';' . $crlf; + $head .= ' </pma:' . $type . '>' . $crlf; + + if (isset($GLOBALS['xml_export_triggers']) + && $GLOBALS['xml_export_triggers'] + ) { + // Export triggers + $triggers = PMA_DBI_get_triggers($db, $table); + if ($triggers) { + foreach ($triggers as $trigger) { + $code = $trigger['create']; + $head .= ' <pma:trigger name="' + . $trigger['name'] . '">' . $crlf; + + // Do some formatting + $code = substr(rtrim($code), 0, -3); + $code = " " . htmlspecialchars($code); + $code = str_replace("\n", "\n ", $code); + + $head .= $code . $crlf; + $head .= ' </pma:trigger>' . $crlf; + } + + unset($trigger); + unset($triggers); + } + } + } + + if (isset($GLOBALS['xml_export_functions']) + && $GLOBALS['xml_export_functions'] + ) { + // Export functions + $functions = PMA_DBI_get_procedures_or_functions($db, 'FUNCTION'); + if ($functions) { + foreach ($functions as $function) { + $head .= ' <pma:function name="' + . $function . '">' . $crlf; + + // Do some formatting + $sql = PMA_DBI_get_definition($db, 'FUNCTION', $function); + $sql = rtrim($sql); + $sql = " " . htmlspecialchars($sql); + $sql = str_replace("\n", "\n ", $sql); + + $head .= $sql . $crlf; + $head .= ' </pma:function>' . $crlf; + } + + unset($function); + unset($functions); + } + } + + if (isset($GLOBALS['xml_export_procedures']) + && $GLOBALS['xml_export_procedures'] + ) { + // Export procedures + $procedures = PMA_DBI_get_procedures_or_functions($db, 'PROCEDURE'); + if ($procedures) { + foreach ($procedures as $procedure) { + $head .= ' <pma:procedure name="' + . $procedure . '">' . $crlf; + + // Do some formatting + $sql = PMA_DBI_get_definition($db, 'PROCEDURE', $procedure); + $sql = rtrim($sql); + $sql = " " . htmlspecialchars($sql); + $sql = str_replace("\n", "\n ", $sql); + + $head .= $sql . $crlf; + $head .= ' </pma:procedure>' . $crlf; + } + + unset($procedure); + unset($procedures); + } + } + + unset($result); + + $head .= ' </pma:database>' . $crlf; + $head .= ' </pma:structure_schemas>' . $crlf; + + if ($export_data) { + $head .= $crlf; + } + } + + return PMA_exportOutputHandler($head); + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + $foot = '</pma_xml_export>'; + + return PMA_exportOutputHandler($foot); + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + global $crlf; + + if (isset($GLOBALS['xml_export_contents']) + && $GLOBALS['xml_export_contents'] + ) { + $head = ' <!--' . $crlf + . ' - ' . __('Database') . ': ' . '\'' . $db . '\'' . $crlf + . ' -->' . $crlf + . ' <database name="' . htmlspecialchars($db) . '">' . $crlf; + + return PMA_exportOutputHandler($head); + } else { + return true; + } + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + global $crlf; + + if (isset($GLOBALS['xml_export_contents']) + && $GLOBALS['xml_export_contents'] + ) { + return PMA_exportOutputHandler(' </database>' . $crlf); + } else { + return true; + } + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs the content of a table in XML format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData ($db, $table, $crlf, $error_url, $sql_query) + { + if (isset($GLOBALS['xml_export_contents']) + && $GLOBALS['xml_export_contents'] + ) { + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + + $columns_cnt = PMA_DBI_num_fields($result); + $columns = array(); + for ($i = 0; $i < $columns_cnt; $i++) { + $columns[$i] = stripslashes(PMA_DBI_field_name($result, $i)); + } + unset($i); + + $buffer = ' <!-- ' . __('Table') . ' ' . $table . ' -->' . $crlf; + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + + while ($record = PMA_DBI_fetch_row($result)) { + $buffer = ' <table name="' + . htmlspecialchars($table) . '">' . $crlf; + for ($i = 0; $i < $columns_cnt; $i++) { + // If a cell is NULL, still export it to preserve + // the XML structure + if (! isset($record[$i]) || is_null($record[$i])) { + $record[$i] = 'NULL'; + } + $buffer .= ' <column name="' + . htmlspecialchars($columns[$i]) . '">' + . htmlspecialchars((string)$record[$i]) + . '</column>' . $crlf; + } + $buffer .= ' </table>' . $crlf; + + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + } + PMA_DBI_free_result($result); + } + + return true; + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the table name + * + * @return void + */ + private function _getTable() + { + return $this->_table; + } + + /** + * Sets the table name + * + * @param string $table table name + * + * @return void + */ + private function _setTable($table) + { + $this->_table = $table; + } + + /** + * Gets the table names + * + * @return array + */ + private function _getTables() + { + return $this->_tables; + } + + /** + * Sets the table names + * + * @param array $tables table names + * + * @return void + */ + private function _setTables($tables) + { + $this->_tables = $tables; + } +} +?> diff --git a/hugo/libraries/plugins/export/ExportYaml.class.php b/hugo/libraries/plugins/export/ExportYaml.class.php new file mode 100644 index 0000000..044daee --- /dev/null +++ b/hugo/libraries/plugins/export/ExportYaml.class.php @@ -0,0 +1,214 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Set of functions used to build YAML dumps of tables + * + * @package PhpMyAdmin-Export + * @subpackage YAML + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/* Get the export interface */ +require_once 'libraries/plugins/ExportPlugin.class.php'; + +/** + * Handles the export for the YAML format + * + * @package PhpMyAdmin-Export + * @subpackage YAML + */ +class ExportYaml extends ExportPlugin +{ + /** + * Constructor + */ + public function __construct() + { + $this->setProperties(); + } + + /** + * Sets the export YAML properties + * + * @return void + */ + protected function setProperties() + { + $props = 'libraries/properties/'; + include_once "$props/plugins/ExportPluginProperties.class.php"; + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + include_once "$props/options/items/HiddenPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('YAML'); + $exportPluginProperties->setExtension('yml'); + $exportPluginProperties->setMimeType('text/yaml'); + $exportPluginProperties->setForceFile(true); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + // create primary items and add them to the group + $leaf = new HiddenPropertyItem(); + $leaf->setName("structure_or_data"); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + PMA_exportOutputHandler( + '%YAML 1.1' . $GLOBALS['crlf'] . '---' . $GLOBALS['crlf'] + ); + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + PMA_exportOutputHandler('...' . $GLOBALS['crlf']); + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + return true; + } + + /** + * Outputs the content of a table in JSON format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + $result = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED); + + $columns_cnt = PMA_DBI_num_fields($result); + for ($i = 0; $i < $columns_cnt; $i++) { + $columns[$i] = stripslashes(PMA_DBI_field_name($result, $i)); + } + unset($i); + + $buffer = ''; + $record_cnt = 0; + while ($record = PMA_DBI_fetch_row($result)) { + $record_cnt++; + + // Output table name as comment if this is the first record of the table + if ($record_cnt == 1) { + $buffer = '# ' . $db . '.' . $table . $crlf; + $buffer .= '-' . $crlf; + } else { + $buffer = '-' . $crlf; + } + + for ($i = 0; $i < $columns_cnt; $i++) { + if (! isset($record[$i])) { + continue; + } + + $column = $columns[$i]; + + if (is_null($record[$i])) { + $buffer .= ' ' . $column . ': null' . $crlf; + continue; + } + + if (is_numeric($record[$i])) { + $buffer .= ' ' . $column . ': ' . $record[$i] . $crlf; + continue; + } + + $record[$i] = str_replace( + array('\\', '"', "\n", "\r"), + array('\\\\', '\"', '\n', '\r'), + $record[$i] + ); + $buffer .= ' ' . $column . ': "' . $record[$i] . '"' . $crlf; + } + + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + } + PMA_DBI_free_result($result); + + return true; + } // end getTableYAML +} +?>
\ No newline at end of file diff --git a/hugo/libraries/plugins/export/PMA_ExportPdf.class.php b/hugo/libraries/plugins/export/PMA_ExportPdf.class.php new file mode 100644 index 0000000..1913d5e --- /dev/null +++ b/hugo/libraries/plugins/export/PMA_ExportPdf.class.php @@ -0,0 +1,408 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * TableProperty class + * + * @package PhpMyAdmin-Export + * @subpackage PDF + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/* Get the PDF class */ +require_once 'libraries/PDF.class.php'; + +/** + * Adapted from a LGPL script by Philip Clarke + * + * @package PhpMyAdmin-Export + * @subpackage PDF + */ +class PMA_ExportPdf extends PMA_PDF +{ + var $tablewidths; + var $headerset; + + /** + * Add page if needed. + * + * @param float $h cell height. Default value: 0 + * @param mixed $y starting y position, leave empty for current position + * @param boolean $addpage if true add a page, otherwise only return + * the true/false state + * + * @return boolean true in case of page break, false otherwise. + */ + function checkPageBreak($h = 0, $y = '', $addpage = true) + { + if ($this->empty_string($y)) { + $y = $this->y; + } + $current_page = $this->page; + if ((($y + $h) > $this->PageBreakTrigger) + AND (! $this->InFooter) + AND ($this->AcceptPageBreak()) + ) { + if ($addpage) { + //Automatic page break + $x = $this->x; + $this->AddPage($this->CurOrientation); + $this->y = $this->dataY; + $oldpage = $this->page - 1; + + $this_page_orm = $this->pagedim[$this->page]['orm']; + $old_page_orm = $this->pagedim[$oldpage]['orm']; + $this_page_olm = $this->pagedim[$this->page]['olm']; + $old_page_olm = $this->pagedim[$oldpage]['olm']; + if ($this->rtl) { + if ($this_page_orm!= $old_page_orm) { + $this->x = $x - ($this_page_orm - $old_page_orm); + } else { + $this->x = $x; + } + } else { + if ($this_page_olm != $old_page_olm) { + $this->x = $x + ($this_page_olm - $old_page_olm); + } else { + $this->x = $x; + } + } + } + return true; + } + if ($current_page != $this->page) { + // account for columns mode + return true; + } + return false; + } + + /** + * This method is used to render the page header. + * + * @return void + */ + function Header() + { + global $maxY; + // We don't want automatic page breaks while generating header + // as this can lead to infinite recursion as auto generated page + // will want header as well causing another page break + // FIXME: Better approach might be to try to compact the content + $this->SetAutoPageBreak(false); + // Check if header for this page already exists + if (! isset($this->headerset[$this->page])) { + $fullwidth = 0; + foreach ($this->tablewidths as $width) { + $fullwidth += $width; + } + $this->SetY(($this->tMargin) - ($this->FontSizePt / $this->k) * 5); + $this->cellFontSize = $this->FontSizePt ; + $this->SetFont( + PMA_PDF_FONT, + '', + ($this->titleFontSize + ? $this->titleFontSize + : $this->FontSizePt) + ); + $this->Cell(0, $this->FontSizePt, $this->titleText, 0, 1, 'C'); + $this->SetFont(PMA_PDF_FONT, '', $this->cellFontSize); + $this->SetY(($this->tMargin) - ($this->FontSizePt / $this->k) * 2.5); + $this->Cell( + 0, + $this->FontSizePt, + __('Database') . ': ' . $this->currentDb . ', ' + . __('Table') . ': ' . $this->currentTable, + 0, 1, 'L' + ); + $l = ($this->lMargin); + foreach ($this->colTitles as $col => $txt) { + $this->SetXY($l, ($this->tMargin)); + $this->MultiCell( + $this->tablewidths[$col], + $this->FontSizePt, + $txt + ); + $l += $this->tablewidths[$col] ; + $maxY = ($maxY < $this->getY()) ? $this->getY() : $maxY ; + } + $this->SetXY($this->lMargin, $this->tMargin); + $this->setFillColor(200, 200, 200); + $l = ($this->lMargin); + foreach ($this->colTitles as $col => $txt) { + $this->SetXY($l, $this->tMargin); + $this->cell( + $this->tablewidths[$col], + $maxY-($this->tMargin), + '', + 1, + 0, + 'L', + 1 + ); + $this->SetXY($l, $this->tMargin); + $this->MultiCell( + $this->tablewidths[$col], + $this->FontSizePt, + $txt, + 0, + 'C' + ); + $l += $this->tablewidths[$col]; + } + $this->setFillColor(255, 255, 255); + // set headerset + $this->headerset[$this->page] = 1; + } + + $this->dataY = $maxY; + $this->SetAutoPageBreak(true); + } + + function morepagestable($lineheight = 8) + { + // some things to set and 'remember' + $l = $this->lMargin; + $startheight = $h = $this->dataY; + $startpage = $currpage = $this->page; + + // calculate the whole width + $fullwidth = 0; + foreach ($this->tablewidths as $width) { + $fullwidth += $width; + } + + // Now let's start to write the table + $row = 0; + $tmpheight = array(); + $maxpage = $this->page; + + while ($data = PMA_DBI_fetch_row($this->results)) { + $this->page = $currpage; + // write the horizontal borders + $this->Line($l, $h, $fullwidth+$l, $h); + // write the content and remember the height of the highest col + foreach ($data as $col => $txt) { + $this->page = $currpage; + $this->SetXY($l, $h); + if ($this->tablewidths[$col] > 0) { + $this->MultiCell( + $this->tablewidths[$col], + $lineheight, + $txt, + 0, + $this->colAlign[$col] + ); + $l += $this->tablewidths[$col]; + } + + if (! isset($tmpheight[$row.'-'.$this->page])) { + $tmpheight[$row.'-'.$this->page] = 0; + } + if ($tmpheight[$row.'-'.$this->page] < $this->GetY()) { + $tmpheight[$row.'-'.$this->page] = $this->GetY(); + } + if ($this->page > $maxpage) { + $maxpage = $this->page; + } + unset($data[$col]); + } + + // get the height we were in the last used page + $h = $tmpheight[$row.'-'.$maxpage]; + // set the "pointer" to the left margin + $l = $this->lMargin; + // set the $currpage to the last page + $currpage = $maxpage; + unset($data[$row]); + $row++; + } + // draw the borders + // we start adding a horizontal line on the last page + $this->page = $maxpage; + $this->Line($l, $h, $fullwidth+$l, $h); + // now we start at the top of the document and walk down + for ($i = $startpage; $i <= $maxpage; $i++) { + $this->page = $i; + $l = $this->lMargin; + $t = ($i == $startpage) ? $startheight : $this->tMargin; + $lh = ($i == $maxpage) ? $h : $this->h-$this->bMargin; + $this->Line($l, $t, $l, $lh); + foreach ($this->tablewidths as $width) { + $l += $width; + $this->Line($l, $t, $l, $lh); + } + } + // set it to the last page, if not it'll cause some problems + $this->page = $maxpage; + } + + /** + * Sets a set of attributes. + * + * @param array $attr array containing the attributes + * + * @return void + */ + function setAttributes($attr = array()) + { + foreach ($attr as $key => $val) { + $this->$key = $val ; + } + } + + /** + * Defines the top margin. + * The method can be called before creating the first page. + * + * @param float $topMargin the margin + * + * @return void + */ + function setTopMargin($topMargin) + { + $this->tMargin = $topMargin; + } + + function mysqlReport($query) + { + unset($this->tablewidths); + unset($this->colTitles); + unset($this->titleWidth); + unset($this->colFits); + unset($this->display_column); + unset($this->colAlign); + + /** + * Pass 1 for column widths + */ + $this->results = PMA_DBI_query($query, null, PMA_DBI_QUERY_UNBUFFERED); + $this->numFields = PMA_DBI_num_fields($this->results); + $this->fields = PMA_DBI_get_fields_meta($this->results); + + // sColWidth = starting col width (an average size width) + $availableWidth = $this->w - $this->lMargin - $this->rMargin; + $this->sColWidth = $availableWidth / $this->numFields; + $totalTitleWidth = 0; + + // loop through results header and set initial + // col widths/ titles/ alignment + // if a col title is less than the starting col width, + // reduce that column size + $colFits = array(); + for ($i = 0; $i < $this->numFields; $i++) { + $stringWidth = $this->getstringwidth($this->fields[$i]->name) + 6 ; + // save the real title's width + $titleWidth[$i] = $stringWidth; + $totalTitleWidth += $stringWidth; + + // set any column titles less than the start width to + // the column title width + if ($stringWidth < $this->sColWidth) { + $colFits[$i] = $stringWidth ; + } + $this->colTitles[$i] = $this->fields[$i]->name; + $this->display_column[$i] = true; + + switch ($this->fields[$i]->type) { + case 'int': + $this->colAlign[$i] = 'R'; + break; + case 'blob': + case 'tinyblob': + case 'mediumblob': + case 'longblob': + /** + * @todo do not deactivate completely the display + * but show the field's name and [BLOB] + */ + if (stristr($this->fields[$i]->flags, 'BINARY')) { + $this->display_column[$i] = false; + unset($this->colTitles[$i]); + } + $this->colAlign[$i] = 'L'; + break; + default: + $this->colAlign[$i] = 'L'; + } + } + + // title width verification + if ($totalTitleWidth > $availableWidth) { + $adjustingMode = true; + } else { + $adjustingMode = false; + // we have enough space for all the titles at their + // original width so use the true title's width + foreach ($titleWidth as $key => $val) { + $colFits[$key] = $val; + } + } + + // loop through the data; any column whose contents + // is greater than the column size is resized + /** + * @todo force here a LIMIT to avoid reading all rows + */ + while ($row = PMA_DBI_fetch_row($this->results)) { + foreach ($colFits as $key => $val) { + $stringWidth = $this->getstringwidth($row[$key]) + 6 ; + if ($adjustingMode && ($stringWidth > $this->sColWidth)) { + // any column whose data's width is bigger than + // the start width is now discarded + unset($colFits[$key]); + } else { + // if data's width is bigger than the current column width, + // enlarge the column (but avoid enlarging it if the + // data's width is very big) + if ($stringWidth > $val + && $stringWidth < ($this->sColWidth * 3) + ) { + $colFits[$key] = $stringWidth ; + } + } + } + } + + $totAlreadyFitted = 0; + foreach ($colFits as $key => $val) { + // set fitted columns to smallest size + $this->tablewidths[$key] = $val; + // to work out how much (if any) space has been freed up + $totAlreadyFitted += $val; + } + + if ($adjustingMode) { + $surplus = (sizeof($colFits) * $this->sColWidth) - $totAlreadyFitted; + $surplusToAdd = $surplus / ($this->numFields - sizeof($colFits)); + } else { + $surplusToAdd = 0; + } + + for ($i = 0; $i < $this->numFields; $i++) { + if (! in_array($i, array_keys($colFits))) { + $this->tablewidths[$i] = $this->sColWidth + $surplusToAdd; + } + if ($this->display_column[$i] == false) { + $this->tablewidths[$i] = 0; + } + } + + ksort($this->tablewidths); + + PMA_DBI_free_result($this->results); + + // Pass 2 + + $this->results = PMA_DBI_query($query, null, PMA_DBI_QUERY_UNBUFFERED); + $this->setY($this->tMargin); + $this->AddPage(); + $this->SetFont(PMA_PDF_FONT, '', 9); + $this->morepagestable($this->FontSizePt); + PMA_DBI_free_result($this->results); + + } // end of mysqlReport function + +} // end of PMA_Export_PDF class +?> diff --git a/hugo/libraries/plugins/export/README b/hugo/libraries/plugins/export/README new file mode 100644 index 0000000..68d5a26 --- /dev/null +++ b/hugo/libraries/plugins/export/README @@ -0,0 +1,276 @@ +This directory holds export plugins for phpMyAdmin. Any new plugin should +basically follow the structure presented here. Official plugins need to +have str* messages with their definition in language files, but if you build +some plugins for your use, you can directly use texts in plugin. + +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * [Name] export plugin for phpMyAdmin + * + * @package PhpMyAdmin-Export + * @subpackage [Name] + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/* Get the export interface */ +require_once 'libraries/plugins/ExportPlugin.class.php'; + +/** + * Handles the export for the [Name] format + * + * @package PhpMyAdmin-Export + */ +class Export[Name] extends ExportPlugin +{ + /** + * optional - declare variables and descriptions + * + * @var type + */ + private $_myOptionalVariable; + + /** + * optional - declare global variables and descriptions + * + * @var type + */ + private $_globalVariableName; + + /** + * Constructor + */ + public function __construct() + { + $this->setProperties(); + } + + // optional - declare global variables and use getters later + /** + * Initialize the local variables that are used specific for export SQL + * + * @global type $global_variable_name + * [..] + * + * @return void + */ + protected function initSpecificVariables() + { + global $global_variable_name; + $this->_setGlobalVariableName($global_variable_name); + } + + /** + * Sets the export plugin properties. + * Called in the constructor. + * + * @return void + */ + protected function setProperties() + { + // set properties + $props = 'libraries/properties/'; + // include the main class for properties for the export plug-ins + include_once "$props/plugins/ExportPluginProperties.class.php"; + // include the group properties classes + include_once "$props/options/groups/OptionsPropertyRootGroup.class.php"; + include_once "$props/options/groups/OptionsPropertyMainGroup.class.php"; + // include the needed single property items + include_once "$props/options/items/RadioPropertyItem.class.php"; + + $exportPluginProperties = new ExportPluginProperties(); + $exportPluginProperties->setText('[name]'); // the name of your plug-in + $exportPluginProperties->setExtension('[ext]'); // extension this plug-in can handle + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup(); + $exportSpecificOptions->setName("Format Specific Options"); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup(); + $generalOptions->setName("general_opts"); + + // optional : + // create primary items and add them to the group + // type - one of the classes listed in libraries/properties/options/items/ + // name - form element name + // text - description in GUI + // size - size of text element + // len - maximal size of input + // values - possible values of the item + $leaf = new RadioPropertyItem(); + $leaf->setName("structure_or_data"); + $leaf->setValues( + array( + 'structure' => __('structure'), + 'data' => __('data'), + 'structure_and_data' => __('structure and data') + ) + ); + $generalOptions->addProperty($leaf); + + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + $this->properties = $exportPluginProperties; + } + + /** + * This method is called when any PluginManager to which the observer + * is attached calls PluginManager::notify() + * + * @param SplSubject $subject The PluginManager notifying the observer + * of an update. + * + * @return void + */ + public function update (SplSubject $subject) + { + } + + /** + * Outputs export header + * + * @return bool Whether it succeeded + */ + public function exportHeader () + { + // implementation + return true; + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + // implementation + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + // implementation + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBFooter ($db) + { + // implementation + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBCreate($db) + { + // implementation + return true; + } + + /** + * Outputs the content of a table in [Name] format + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data + * + * @return bool Whether it succeeded + */ + public function exportData($db, $table, $crlf, $error_url, $sql_query) + { + // implementation; + return true; + } + + // optional - implement other methods defined in ExportPlugin.class.php: + // - exportRoutines() + // - exportStructure() + // - getTableDefStandIn() + // - getTriggers() + + // optional - implement other private methods in order to avoid + // having huge methods or avoid duplicate code. Make use of them + // as well as of the getters and setters declared both here + // and in the ExportPlugin class + + + // optional: + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Getter description + * + * @return type + */ + private function _getMyOptionalVariable() + { + return $this->_myOptionalVariable; + } + + /** + * Setter description + * + * @param type $my_optional_variable description + * + * @return void + */ + private function _setMyOptionalVariable($my_optional_variable) + { + $this->_myOptionalVariable = $my_optional_variable; + } + + /** + * Getter description + * + * @return type + */ + private function _getGlobalVariableName() + { + return $this->_globalVariableName; + } + + /** + * Setter description + * + * @param type $global_variable_name description + * + * @return void + */ + private function _setGlobalVariableName($global_variable_name) + { + $this->_globalVariableName = $global_variable_name; + } +} +?>
\ No newline at end of file diff --git a/hugo/libraries/plugins/export/TableProperty.class.php b/hugo/libraries/plugins/export/TableProperty.class.php new file mode 100644 index 0000000..a928a6c --- /dev/null +++ b/hugo/libraries/plugins/export/TableProperty.class.php @@ -0,0 +1,288 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Holds the TableProperty class + * + * @package PhpMyAdmin-Export + * @subpackage CodeGen + */ +if (! defined('PHPMYADMIN')) { + exit; +} + +/** + * TableProperty class + * + * @package PhpMyAdmin-Export + * @subpackage CodeGen + */ +class TableProperty +{ + /** + * Name + * + * @var string + */ + public $name; + + /** + * Type + * + * @var string + */ + public $type; + + /** + * Wheter the key is nullable or not + * + * @var bool + */ + public $nullable; + + /** + * The key + * + * @var int + */ + public $key; + + /** + * Default value + * + * @var mixed + */ + public $defaultValue; + + /** + * Extension + * + * @var string + */ + public $ext; + + /** + * Constructor + * + * @param array $row table row + * + * @return void + */ + function __construct($row) + { + $this->name = trim($row[0]); + $this->type = trim($row[1]); + $this->nullable = trim($row[2]); + $this->key = trim($row[3]); + $this->defaultValue = trim($row[4]); + $this->ext = trim($row[5]); + } + + /** + * Gets the pure type + * + * @return string type + */ + function getPureType() + { + $pos = strpos($this->type, "("); + if ($pos > 0) { + return substr($this->type, 0, $pos); + } + return $this->type; + } + + /** + * Tells whether the key is null or not + * + * @return bool true if the key is not null, false otherwise + */ + function isNotNull() + { + return $this->nullable == "NO" ? "true" : "false"; + } + + /** + * Tells whether the key is unique or not + * + * @return bool true if the key is unique, false otherwise + */ + function isUnique() + { + return $this->key == "PRI" || $this->key == "UNI" ? "true" : "false"; + } + + /** + * Gets the .NET primitive type + * + * @return string type + */ + function getDotNetPrimitiveType() + { + if (strpos($this->type, "int") === 0) { + return "int"; + } + if (strpos($this->type, "long") === 0) { + return "long"; + } + if (strpos($this->type, "char") === 0) { + return "string"; + } + if (strpos($this->type, "varchar") === 0) { + return "string"; + } + if (strpos($this->type, "text") === 0) { + return "string"; + } + if (strpos($this->type, "longtext") === 0) { + return "string"; + } + if (strpos($this->type, "tinyint") === 0) { + return "bool"; + } + if (strpos($this->type, "datetime") === 0) { + return "DateTime"; + } + return "unknown"; + } + + /** + * Gets the .NET object type + * + * @return string type + */ + function getDotNetObjectType() + { + if (strpos($this->type, "int") === 0) { + return "Int32"; + } + if (strpos($this->type, "long") === 0) { + return "Long"; + } + if (strpos($this->type, "char") === 0) { + return "String"; + } + if (strpos($this->type, "varchar") === 0) { + return "String"; + } + if (strpos($this->type, "text") === 0) { + return "String"; + } + if (strpos($this->type, "longtext") === 0) { + return "String"; + } + if (strpos($this->type, "tinyint") === 0) { + return "Boolean"; + } + if (strpos($this->type, "datetime") === 0) { + return "DateTime"; + } + return "Unknown"; + } + + /** + * Gets the index name + * + * @return string containing the name of the index + */ + function getIndexName() + { + if (strlen($this->key) > 0) { + return "index=\"" + . htmlspecialchars($this->name, ENT_COMPAT, 'UTF-8') + . "\""; + } + return ""; + } + + /** + * Tells whether the key is primary or not + * + * @return bool true if the key is primary, false otherwise + */ + function isPK() + { + return $this->key=="PRI"; + } + + /** + * Formats a string for C# + * + * @param string $text string to be formatted + * + * @return string formatted text + */ + function formatCs($text) + { + $text = str_replace( + "#name#", + ExportCodegen::cgMakeIdentifier($this->name, false), + $text + ); + return $this->format($text); + } + + /** + * Formats a string for XML + * + * @param string $text string to be formatted + * + * @return string formatted text + */ + function formatXml($text) + { + $text = str_replace( + "#name#", + htmlspecialchars($this->name, ENT_COMPAT, 'UTF-8'), + $text + ); + $text = str_replace( + "#indexName#", + $this->getIndexName(), + $text + ); + return $this->format($text); + } + + /** + * Formats a string + * + * @param string $text string to be formatted + * + * @return string formatted text + */ + function format($text) + { + $text = str_replace( + "#ucfirstName#", + ExportCodegen::cgMakeIdentifier($this->name), + $text + ); + $text = str_replace( + "#dotNetPrimitiveType#", + $this->getDotNetPrimitiveType(), + $text + ); + $text = str_replace( + "#dotNetObjectType#", + $this->getDotNetObjectType(), + $text + ); + $text = str_replace( + "#type#", + $this->getPureType(), + $text + ); + $text = str_replace( + "#notNull#", + $this->isNotNull(), + $text + ); + $text = str_replace( + "#unique#", + $this->isUnique(), + $text + ); + return $text; + } +} +?>
\ No newline at end of file |
