diff --git a/export.php b/export.php index 37efc02c62..623173a1ab 100644 --- a/export.php +++ b/export.php @@ -22,9 +22,11 @@ foreach ($_POST as $one_post_param => $one_post_value) { PMA_checkParameters(array('what', 'export_type')); -// Scan plugins -$export_list = PMA_getPlugins( - 'libraries/export/', +// export class instance, not array of properties, as before +$export_plugin = PMA_getPlugin( + "export", + $what, + 'libraries/plugins/export/', array( 'export_type' => $export_type, 'single_table' => isset($single_table) @@ -35,8 +37,10 @@ $export_list = PMA_getPlugins( $type = $what; // Check export type -if (! isset($export_list[$type])) { +if (! isset($export_plugin)) { PMA_fatalError(__('Bad type!')); +} else { + $export_plugin_properties = $export_plugin->getProperties(); } /** @@ -83,7 +87,8 @@ if ($_REQUEST['output_format'] == 'astext') { } // Does export require to be into file? -if (isset($export_list[$type]['force_file']) && ! $asfile) { +if (isset($export_plugin_properties['force_file']) && ! $asfile) { + $message = PMA_Message::error(__('Selected export type has to be saved in file!')); include_once 'libraries/header.inc.php'; if ($export_type == 'server') { @@ -297,13 +302,13 @@ if ($asfile) { // Grab basic dump extension and mime type // Check if the user already added extension; get the substring where the extension would be if it was included - $extension_start_pos = strlen($filename) - strlen($export_list[$type]['extension']) - 1; + $extension_start_pos = strlen($filename) - strlen($export_plugin_properties['extension']) - 1; $user_extension = substr($filename, $extension_start_pos, strlen($filename)); - $required_extension = "." . $export_list[$type]['extension']; + $required_extension = "." . $export_plugin_properties['extension']; if (strtolower($user_extension) != $required_extension) { $filename .= $required_extension; } - $mime_type = $export_list[$type]['mime_type']; + $mime_type = $export_plugin_properties['mime_type']; // If dump is going to be compressed, set correct mime_type and add // compression to extension @@ -424,7 +429,7 @@ if (!$save_on_server) { do { // Add possibly some comments to export - if (!PMA_exportHeader()) { + if (! $export_plugin->exportHeader($db)) { break; } @@ -456,10 +461,10 @@ do { if ((isset($tmp_select) && strpos(' ' . $tmp_select, '|' . $current_db . '|')) || ! isset($tmp_select) ) { - if (!PMA_exportDBHeader($current_db)) { + if (! $export_plugin->exportDBHeader($current_db)) { break 2; } - if (!PMA_exportDBCreate($current_db)) { + if (! $export_plugin->exportDBCreate($current_db)) { break 2; } if (function_exists('PMA_exportRoutines') && strpos($GLOBALS['sql_structure_or_data'], 'structure') !== false && isset($GLOBALS['sql_procedure_function'])) { @@ -489,7 +494,7 @@ do { // if this is a view or a merge table, don't export data if (($GLOBALS[$what . '_structure_or_data'] == 'data' || $GLOBALS[$what . '_structure_or_data'] == 'structure_and_data') && !($is_view || PMA_Table::isMerge($current_db, $table))) { $local_query = 'SELECT * FROM ' . PMA_backquote($current_db) . '.' . PMA_backquote($table); - if (!PMA_exportData($current_db, $table, $crlf, $err_url, $local_query)) { + if (! $export_plugin->exportData($current_db, $table, $crlf, $err_url, $local_query)) { break 3; } } @@ -555,7 +560,7 @@ do { // if this is a view or a merge table, don't export data if (($GLOBALS[$what . '_structure_or_data'] == 'data' || $GLOBALS[$what . '_structure_or_data'] == 'structure_and_data') && !($is_view || PMA_Table::isMerge($db, $table))) { $local_query = 'SELECT * FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table); - if (!PMA_exportData($db, $table, $crlf, $err_url, $local_query)) { + if (! $export_plugin->exportData($db, $table, $crlf, $err_url, $local_query)) { break 2; } } @@ -626,7 +631,7 @@ do { } else { $local_query = 'SELECT * FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table) . $add_query; } - if (!PMA_exportData($db, $table, $crlf, $err_url, $local_query)) { + if (! $export_plugin->exportData($db, $table, $crlf, $err_url, $local_query)) { break; } } @@ -641,11 +646,11 @@ do { break 2; } } - if (!PMA_exportDBFooter($db)) { + if (! $export_plugin->exportDBFooter($db)) { break; } } - if (!PMA_exportFooter()) { + if (! $export_plugin->exportFooter()) { break; } diff --git a/import.php b/import.php index 49fb2edb1b..fa5630be42 100644 --- a/import.php +++ b/import.php @@ -409,13 +409,20 @@ if (! $error && isset($skip)) { if (! $error) { // Check for file existance - if (!file_exists('libraries/import/' . $format . '.php')) { + require_once("libraries/plugin_interface.lib.php"); + $import_plugin = PMA_getPlugin( + "import", + $format, + 'libraries/plugins/import/' + ); + if ($import_plugin == null) { $error = true; - $message = PMA_Message::error(__('Could not load import plugins, please check your installation!')); + $message = PMA_Message::error( + __('Could not load import plugins, please check your installation!') + ); } else { // Do the real import - $plugin_param = $import_type; - include 'libraries/import/' . $format . '.php'; + $import_plugin->doImport(); } } diff --git a/libraries/common.lib.php b/libraries/common.lib.php index db1d425950..9dec937678 100644 --- a/libraries/common.lib.php +++ b/libraries/common.lib.php @@ -3337,16 +3337,19 @@ function PMA_selectUploadFile($import_list, $uploaddir) ) . ''; $extensions = ''; - foreach ($import_list as $val) { + foreach ($import_list as $plugin) { + $properties = $plugin->getProperties(); if (! empty($extensions)) { $extensions .= '|'; } - $extensions .= $val['extension']; + $extensions .= $properties['extension']; } $matcher = '@\.(' . $extensions . ')(\.(' . PMA_supportedDecompressions() . '))?$@'; - $active = (isset($GLOBALS['timeout_passed']) && $GLOBALS['timeout_passed'] && isset($local_import_file)) + $active = (isset($GLOBALS['timeout_passed']) + && $GLOBALS['timeout_passed'] + && isset($local_import_file)) ? $local_import_file : ''; $files = PMA_getFileSelectOptions( diff --git a/libraries/display_export.lib.php b/libraries/display_export.lib.php index f21a71bc9d..0731f64a85 100644 --- a/libraries/display_export.lib.php +++ b/libraries/display_export.lib.php @@ -33,11 +33,20 @@ function PMA_exportIsActive($what, $val) } /* Scan for plugins */ -$export_list = PMA_getPlugins('./libraries/export/', array('export_type' => $export_type, 'single_table' => isset($single_table))); +$export_list = PMA_getPlugins( + "export", + 'libraries/plugins/export/', + array( + 'export_type' => $export_type, + 'single_table' => isset($single_table) + ) +); /* Fail if we didn't find any plugin */ if (empty($export_list)) { - PMA_Message::error(__('Could not load export plugins, please check your installation!'))->display(); + PMA_Message::error(__( + 'Could not load export plugins, please check your installation!' + ))->display(); include './libraries/footer.inc.php'; } ?> diff --git a/libraries/display_import.lib.php b/libraries/display_import.lib.php index f8ff0c25eb..164f8d6ab1 100644 --- a/libraries/display_import.lib.php +++ b/libraries/display_import.lib.php @@ -16,11 +16,17 @@ require_once './libraries/plugin_interface.lib.php'; require_once './libraries/display_import_ajax.lib.php'; /* Scan for plugins */ -$import_list = PMA_getPlugins('./libraries/import/', $import_type); +$import_list = PMA_getPlugins( + "import", + 'libraries/plugins/import/', + $import_type +); /* Fail if we didn't find any plugin */ if (empty($import_list)) { - PMA_Message::error(__('Could not load import plugins, please check your installation!'))->display(); + PMA_Message::error(__( + 'Could not load import plugins, please check your installation!' + ))->display(); include './libraries/footer.inc.php'; } ?> diff --git a/libraries/import.lib.php b/libraries/import.lib.php index 1213881671..6acd04cf46 100644 --- a/libraries/import.lib.php +++ b/libraries/import.lib.php @@ -316,7 +316,9 @@ function PMA_importGetNextChunk($size = 32768) if (strncmp($result, "\xEF\xBB\xBF", 3) == 0) { $result = substr($result, 3); // UTF-16 BE, LE - } elseif (strncmp($result, "\xFE\xFF", 2) == 0 || strncmp($result, "\xFF\xFE", 2) == 0) { + } elseif (strncmp($result, "\xFE\xFF", 2) == 0 + || strncmp($result, "\xFF\xFE", 2) == 0 + ) { $result = substr($result, 2); } } diff --git a/libraries/plugin_interface.lib.php b/libraries/plugin_interface.lib.php index 98e5e3cfb1..39969001e4 100644 --- a/libraries/plugin_interface.lib.php +++ b/libraries/plugin_interface.lib.php @@ -7,15 +7,41 @@ */ /** - * Reads all plugin information from directory $plugins_dir. + * Includes and instantiates the specified plugin type for a certain format * - * @param string $plugins_dir directrory with plugins - * @param mixed $plugin_param parameter to plugin by which they can - * decide whether they can work + * @param string $plugin_type the type of the plugin (import, export, etc) + * @param string $plugin_format the format of the plugin (sql, xml, et ) + * @param string $plugins_dir directrory with plugins + * @param mixed $plugin_param parameter to plugin by which they can + * decide whether they can work * - * @return array list of plugins + * @return new plugin instance */ -function PMA_getPlugins($plugins_dir, $plugin_param) +function PMA_getPlugin($plugin_type, $plugin_format, $plugins_dir, $plugin_param = false) +{ + // todo replace strtoupper with CamelCaps (ex: HtmlWord) + $class_name = strtoupper($plugin_type[0]) + . strtolower(substr($plugin_type, 1)) + . strtoupper($plugin_format); + $file = $class_name . ".class.php"; + if (is_file($plugins_dir . $file)) { + include_once $plugins_dir . $file; + return new $class_name; + } + + return null; +} +/** + * Reads all plugin information from directory $plugins_dir + * + * @param string $plugin_type the type of the plugin (import, export, etc) + * @param string $plugins_dir directrory with plugins + * @param mixed $plugin_param parameter to plugin by which they can + * decide whether they can work + * + * @return array list of plugin instances + */ +function PMA_getPlugins($plugin_type, $plugins_dir, $plugin_param) { /* Scan for plugins */ $plugin_list = array(); @@ -25,8 +51,18 @@ function PMA_getPlugins($plugins_dir, $plugin_param) // (for example ._csv.php) so the following regexp // matches a file which does not start with a dot but ends // with ".php" - if (is_file($plugins_dir . $file) && preg_match('@^[^\.](.)*\.php$@i', $file)) { + $class_type = strtoupper($plugin_type[0]) + . strtolower(substr($plugin_type, 1)); + if (is_file($plugins_dir . $file) + && preg_match( + '@^' . $class_type . '(.+)\.class\.php$@i', + $file, + $matches + ) + ) { include_once $plugins_dir . $file; + $class_name = $class_type . $matches[1]; + $plugin_list [] = new $class_name; } } } @@ -61,8 +97,11 @@ function PMA_pluginCheckboxCheck($section, $opt) // If the form is being repopulated using $_GET data, that is priority if (isset($_GET[$opt]) || ! isset($_GET['repopulate']) - && ((isset($GLOBALS['timeout_passed']) && $GLOBALS['timeout_passed'] && isset($_REQUEST[$opt])) - || (isset($GLOBALS['cfg'][$section][$opt]) && $GLOBALS['cfg'][$section][$opt])) + && ((isset($GLOBALS['timeout_passed']) + && $GLOBALS['timeout_passed'] + && isset($_REQUEST[$opt])) + || (isset($GLOBALS['cfg'][$section][$opt]) + && $GLOBALS['cfg'][$section][$opt])) ) { return ' checked="checked"'; } @@ -109,7 +148,7 @@ function PMA_pluginGetDefault($section, $opt) * @param string $section name of config section in * $GLOBALS['cfg'][$section] for plugin * @param string $name name of select element - * @param array &$list array with plugin configuration defined in plugin file + * @param array &$list array with plugin instances * @param string $cfgname name of config value, if none same as $name * * @return string html select tag @@ -121,20 +160,30 @@ function PMA_pluginGetChoice($section, $name, &$list, $cfgname = null) } $ret = '' . "\n"; // Whether each plugin has to be saved as a file - foreach ($list as $plugin_name => $val) { + foreach ($list as $plugin) { + $plugin_name = strtolower(substr(get_class($plugin), strlen($section))); + $properties = $plugin->getProperties(); $ret .= ''; $count = 0; - $ret .= '

' . PMA_getString($val['text']) . '

'; - if (isset($val['options']) && count($val['options']) > 0) { - foreach ($val['options'] as $id => $opt) { - if ($opt['type'] != 'hidden' && $opt['type'] != 'begin_group' && $opt['type'] != 'end_group' && $opt['type'] != 'begin_subgroup' && $opt['type'] != 'end_subgroup') { + $ret .= '

' . PMA_getString($properties['text']) . '

'; + if (isset($properties['options']) && count($properties['options']) > 0) { + foreach ($properties['options'] as $id => $opt) { + if ($opt['type'] != 'hidden' + && $opt['type'] != 'begin_group' + && $opt['type'] != 'end_group' + && $opt['type'] != 'begin_subgroup' + && $opt['type'] != 'end_subgroup' + ) { $count++; } $ret .= PMA_pluginGetOneOption($section, $plugin_name, $id, $opt); diff --git a/libraries/plugins/AuthenticationPlugin.class.php b/libraries/plugins/AuthenticationPlugin.class.php new file mode 100644 index 0000000000..9b2ea57aac --- /dev/null +++ b/libraries/plugins/AuthenticationPlugin.class.php @@ -0,0 +1,51 @@ + \ No newline at end of file diff --git a/libraries/plugins/ExportPlugin.class.php b/libraries/plugins/ExportPlugin.class.php new file mode 100644 index 0000000000..ae845f4830 --- /dev/null +++ b/libraries/plugins/ExportPlugin.class.php @@ -0,0 +1,215 @@ +setCrlf($crlf); + $this->setCfg($cfg); + $this->setDb($db); + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the export specific format plugin properties + * + * @return array + */ + public function getProperties() + { + return $this->properties; + } + + /** + * Sets the export plugins properties and is implemented by each export + * plugin + * + * @return void + */ + abstract protected function setProperties(); + + /** + * Gets the type of the newline character + * + * @return string + */ + public function getCrlf() + { + return $this->_crlf; + } + + /** + * Sets the type of the newline character + * + * @param String $crlf type of the newline character + * + * @return void + */ + protected function setCrlf($crlf) + { + $this->_crlf = $crlf; + } + + /** + * Gets the configuration settings + * + * @return array + */ + public function getCfg() + { + return $this->_cfg; + } + + /** + * Sets the configuration settings + * + * @param array $cfg array with configuration settings + * + * @return void + */ + protected function setCfg($cfg) + { + $this->_cfg = $cfg; + } + + /** + * Gets the database name + * + * @return string + */ + public function getDb() + { + return $this->_db; + } + + /** + * Sets the database name + * + * @param String $db database name + * + * @return void + */ + protected function setDb($db) + { + $this->_db = $db; + } +} +?> \ No newline at end of file diff --git a/libraries/plugins/ImportPlugin.class.php b/libraries/plugins/ImportPlugin.class.php new file mode 100644 index 0000000000..e2a11d07ab --- /dev/null +++ b/libraries/plugins/ImportPlugin.class.php @@ -0,0 +1,112 @@ +setError($error); + $this->setTimeout_passed($timeout_passed); + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the import specific format plugin properties + * + * @return array + */ + public function getProperties() + { + return $this->properties; + } + + /** + * Sets the export plugins properties and is implemented by each import + * plugin + * + * @return void + */ + abstract protected function setProperties(); + + public function getError() + { + return $this->_error; + } + + public function setError($error) + { + $this->_error = $error; + } + + public function getTimeout_passed() + { + return $this->_timeout_passed; + } + + public function setTimeout_passed($timeout_passed) + { + $this->_timeout_passed = $timeout_passed; + } +} +?> \ No newline at end of file diff --git a/libraries/plugins/PluginManager.class.php b/libraries/plugins/PluginManager.class.php new file mode 100644 index 0000000000..52c981346d --- /dev/null +++ b/libraries/plugins/PluginManager.class.php @@ -0,0 +1,130 @@ +_storage = new SplObjectStorage(); + } + + /** + * Attaches an SplObserver so that it can be notified of updates + * + * @param SplObserver $observer The SplObserver to attach + * + * @return void + */ + function attach (SplObserver $observer ) + { + $this->_storage->attach($observer); + } + + /** + * Detaches an observer from the subject to no longer notify it of updates + * + * @param SplObserver $observer The SplObserver to detach + * + * @return void + */ + function detach (SplObserver $observer) + { + $this->_storage->detach($observer); + } + + /** + * It is called after setStatus() was run by a certain plugin, and has + * the role of sending a notification to all of the plugins in $_storage, + * by calling the update() method for each of them. + * + * @return void + */ + function notify () + { + } + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + /** + * Gets the list with all the plugins that attach to it + * + * @return type SplObjectStorage + */ + public function getStorage() + { + return $this->_storage; + } + + /** + * Setter for $_storage + * + * @param SplObjectStorage $_storage the list with all the plugins that + * attach to it + * + * @return void + */ + public function setStorage($_storage) + { + $this->_storage = $_storage; + } + + /** + * Gets the information about the current plugin state + * It is called by all the plugins in $_storage in their update() method + * + * @return type mixed + */ + public function getStatus() + { + return $this->_status; + } + + /** + * Setter for $_status + * If a plugin changes its status, this has to be remembered in order to + * notify the rest of the plugins that they should update + * + * @param mixed $_status contains information about the current plugin state + * + * @return void + */ + public function setStatus($_status) + { + $this->_status = $_status; + } +} +?> \ No newline at end of file diff --git a/libraries/plugins/PluginObserver.class.php b/libraries/plugins/PluginObserver.class.php new file mode 100644 index 0000000000..190f02d747 --- /dev/null +++ b/libraries/plugins/PluginObserver.class.php @@ -0,0 +1,81 @@ +_pluginManager = $pluginManager; + } + + /** + * 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 + */ + abstract public function update (SplSubject $subject); + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + /** + * Gets the PluginManager instance that contains the list with all the + * plugins that attached to it + * + * @return type PluginManager + */ + public function getPluginManager() + { + return $this->_pluginManager; + } + + /** + * Setter for $_pluginManager + * + * @param PluginManager $_pluginManager the private instance that it will + * attach to + * + * @return void + */ + public function setPluginManager($_pluginManager) + { + $this->_pluginManager = $_pluginManager; + } +} +?> \ No newline at end of file diff --git a/libraries/plugins/TransformationsPlugin.class.php b/libraries/plugins/TransformationsPlugin.class.php new file mode 100644 index 0000000000..be17845425 --- /dev/null +++ b/libraries/plugins/TransformationsPlugin.class.php @@ -0,0 +1,66 @@ + \ No newline at end of file diff --git a/libraries/plugins/export/ExportXML.class.php b/libraries/plugins/export/ExportXML.class.php new file mode 100644 index 0000000000..6403ce7968 --- /dev/null +++ b/libraries/plugins/export/ExportXML.class.php @@ -0,0 +1,521 @@ +setProperties(); + + } + + /** + * Initialize the local variables that are used specific for export SQL + * + * @global type $table + * @global type $tables + * + * @return void + */ + private function initLocalVariables() + { + global $table; + global $tables; + $this->setTable($table); + $this->setTables($tables); + } + + /** + * Sets the export XML properties + * + * @return void + */ + protected function setProperties() + { + $this->properties = array( + 'text' => __('XML'), + 'extension' => 'xml', + 'mime_type' => 'text/xml', + 'options' => array(), + 'options_text' => __('Options') + ); + + $this->properties['options'] = array( + array( + 'type' => 'begin_group', + 'name' => 'general_opts' + ), + array( + 'type' => 'hidden', + 'name' => 'structure_or_data' + ), + array( + 'type' => 'end_group' + ) + ); + + /* Export structure */ + $this->properties['options'][] = array( + 'type' => 'begin_group', + 'name' => 'structure', + 'text' => __('Object creation options (all are recommended)') + ); + if (! PMA_DRIZZLE) { + $this->properties['options'][] = array( + 'type' => 'bool', + 'name' => 'export_functions', + 'text' => __('Functions') + ); + $this->properties['options'][] = array( + 'type' => 'bool', + 'name' => 'export_procedures', + 'text' => __('Procedures') + ); + } + $this->properties['options'][] = array( + 'type' => 'bool', + 'name' => 'export_tables', + 'text' => __('Tables') + ); + if (! PMA_DRIZZLE) { + $this->properties['options'][] = array( + 'type' => 'bool', + 'name' => 'export_triggers', + 'text' => __('Triggers') + ); + $this->properties['options'][] = array( + 'type' => 'bool', + 'name' => 'export_views', + 'text' => __('Views') + ); + } + $this->properties['options'][] = array( + 'type' => 'end_group' + ); + + /* Data */ + $this->properties['options'][] = array( + 'type' => 'begin_group', + 'name' => 'data', + 'text' => __('Data dump options') + ); + $this->properties['options'][] = array( + 'type' => 'bool', + 'name' => 'export_contents', + 'text' => __('Export contents') + ); + $this->properties['options'][] = array( + 'type' => 'end_group' + ); + } + + /** + * 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 () + { + // initialize the general export variables + $this->initExportCommonVariables(); + + // initialize the specific export sql variables + $this->initLocalVariables(); + + $crlf = $this->getCrlf(); + $cfg = $this->getCfg(); + $db = $this->getDb(); + $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 = '' . $crlf + . '' . $crlf . $crlf; + + $head .= '' . $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_sqlAddSlashes($db) . "'" + ); + } else { + $result = PMA_DBI_fetch_result( + 'SELECT `DEFAULT_CHARACTER_SET_NAME`, `DEFAULT_COLLATION_NAME`' + . ' FROM `information_schema`.`SCHEMATA` WHERE `SCHEMA_NAME`' + . ' = \''.PMA_sqlAddSlashes($db).'\' LIMIT 1' + ); + } + $db_collation = $result[0]['DEFAULT_COLLATION_NAME']; + $db_charset = $result[0]['DEFAULT_CHARACTER_SET_NAME']; + + $head .= ' ' . $crlf; + $head .= ' ' . $crlf; + $head .= ' ' . $crlf; + + if (count($tables) == 0) { + $tables[] = $table; + } + + foreach ($tables as $table) { + // Export tables and views + $result = PMA_DBI_fetch_result( + 'SHOW CREATE TABLE ' . PMA_backquote($db) . '.' + . PMA_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 .= ' ' + . $crlf; + + $tbl = " " . htmlspecialchars($tbl); + $tbl = str_replace("\n", "\n ", $tbl); + + $head .= $tbl . ';' . $crlf; + $head .= ' ' . $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 .= ' ' . $crlf; + + // Do some formatting + $code = substr(rtrim($code), 0, -3); + $code = " " . htmlspecialchars($code); + $code = str_replace("\n", "\n ", $code); + + $head .= $code . $crlf; + $head .= ' ' . $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 .= ' ' . $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 .= ' ' . $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 .= ' ' . $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 .= ' ' . $crlf; + } + + unset($procedure); + unset($procedures); + } + } + + unset($result); + + $head .= ' ' . $crlf; + $head .= ' ' . $crlf; + + if ($export_data) { + $head .= $crlf; + } + } + + return PMA_exportOutputHandler($head); + } + + /** + * Outputs export footer + * + * @return bool Whether it succeeded + */ + public function exportFooter () + { + $foot = ''; + + return PMA_exportOutputHandler($foot); + } + + /** + * Outputs database header + * + * @param string $db Database name + * + * @return bool Whether it succeeded + */ + public function exportDBHeader ($db) + { + $crlf = $this->getCrlf(); + + if (isset($GLOBALS['xml_export_contents']) + && $GLOBALS['xml_export_contents'] + ) { + $head = ' ' . $crlf + . ' ' . $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) + { + $crlf = $this->getCrlf(); + + if (isset($GLOBALS['xml_export_contents']) + && $GLOBALS['xml_export_contents'] + ) { + return PMA_exportOutputHandler(' ' . $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 = ' ' . $crlf; + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + + while ($record = PMA_DBI_fetch_row($result)) { + $buffer = ' ' . $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 .= ' ' + . htmlspecialchars((string)$record[$i]) + . '' . $crlf; + } + $buffer .= '
' . $crlf; + + if (! PMA_exportOutputHandler($buffer)) { + return false; + } + } + PMA_DBI_free_result($result); + } + + return true; + } + + + /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */ + + + private function getTable() + { + return $this->table; + } + + private function setTable($table) + { + $this->table = $table; + } + + private function getTables() + { + return $this->tables; + } + + private function setTables($tables) + { + $this->tables = $tables; + } +} +?> \ No newline at end of file