diff options
| author | Charles <sircharlesaze@gmail.com> | 2020-01-09 10:55:03 +0100 |
|---|---|---|
| committer | Charles <sircharlesaze@gmail.com> | 2020-01-09 13:09:38 +0100 |
| commit | 04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa (patch) | |
| tree | 5c691241355c943a3c68ddb06b8cf8c60aa11319 /srcs/phpmyadmin/libraries/classes/Plugins/Import/ImportXml.php | |
| parent | 7e0d85db834d6351ed85d01e5126ac31dc510b86 (diff) | |
| download | ft_server-04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa.tar.gz ft_server-04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa.tar.bz2 ft_server-04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa.zip | |
phpmyadmin working
Diffstat (limited to 'srcs/phpmyadmin/libraries/classes/Plugins/Import/ImportXml.php')
| -rw-r--r-- | srcs/phpmyadmin/libraries/classes/Plugins/Import/ImportXml.php | 375 |
1 files changed, 375 insertions, 0 deletions
diff --git a/srcs/phpmyadmin/libraries/classes/Plugins/Import/ImportXml.php b/srcs/phpmyadmin/libraries/classes/Plugins/Import/ImportXml.php new file mode 100644 index 0000000..833d4e4 --- /dev/null +++ b/srcs/phpmyadmin/libraries/classes/Plugins/Import/ImportXml.php @@ -0,0 +1,375 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * XML import plugin for phpMyAdmin + * + * @todo Improve efficiency + * @package PhpMyAdmin-Import + * @subpackage XML + */ +declare(strict_types=1); + +namespace PhpMyAdmin\Plugins\Import; + +use PhpMyAdmin\Import; +use PhpMyAdmin\Message; +use PhpMyAdmin\Plugins\ImportPlugin; +use PhpMyAdmin\Properties\Plugins\ImportPluginProperties; +use PhpMyAdmin\Util; +use SimpleXMLElement; + +/** + * Handles the import for the XML format + * + * @package PhpMyAdmin-Import + * @subpackage XML + */ +class ImportXml extends ImportPlugin +{ + /** + * Constructor + */ + public function __construct() + { + parent::__construct(); + $this->setProperties(); + } + + /** + * Sets the import plugin properties. + * Called in the constructor. + * + * @return void + */ + protected function setProperties() + { + $importPluginProperties = new ImportPluginProperties(); + $importPluginProperties->setText(__('XML')); + $importPluginProperties->setExtension('xml'); + $importPluginProperties->setMimeType('text/xml'); + $importPluginProperties->setOptions([]); + $importPluginProperties->setOptionsText(__('Options')); + + $this->properties = $importPluginProperties; + } + + /** + * Handles the whole import logic + * + * @param array $sql_data 2-element array with sql data + * + * @return void + */ + public function doImport(array &$sql_data = []) + { + global $error, $timeout_passed, $finished, $db; + + $i = 0; + $len = 0; + $buffer = ""; + + /** + * Read in the file via Import::getNextChunk so that + * it can process compressed files + */ + while (! ($finished && $i >= $len) && ! $error && ! $timeout_passed) { + $data = $this->import->getNextChunk(); + if ($data === false) { + /* subtract data we didn't handle yet and stop processing */ + $GLOBALS['offset'] -= strlen($buffer); + break; + } elseif ($data !== true) { + /* Append new data to buffer */ + $buffer .= $data; + unset($data); + } + } + + unset($data); + + /** + * Disable loading of external XML entities. + */ + libxml_disable_entity_loader(); + + /** + * Load the XML string + * + * The option LIBXML_COMPACT is specified because it can + * result in increased performance without the need to + * alter the code in any way. It's basically a freebee. + */ + $xml = @simplexml_load_string($buffer, "SimpleXMLElement", LIBXML_COMPACT); + + unset($buffer); + + /** + * The XML was malformed + */ + if ($xml === false) { + Message::error( + __( + 'The XML file specified was either malformed or incomplete.' + . ' Please correct the issue and try again.' + ) + ) + ->display(); + unset($xml); + $GLOBALS['finished'] = false; + + return; + } + + /** + * Table accumulator + */ + $tables = []; + /** + * Row accumulator + */ + $rows = []; + + /** + * Temp arrays + */ + $tempRow = []; + $tempCells = []; + + /** + * CREATE code included (by default: no) + */ + $struct_present = false; + + /** + * Analyze the data in each table + */ + $namespaces = $xml->getNamespaces(true); + + /** + * Get the database name, collation and charset + */ + $db_attr = $xml->children(isset($namespaces['pma']) ? $namespaces['pma'] : null) + ->{'structure_schemas'}->{'database'}; + + if ($db_attr instanceof SimpleXMLElement) { + $db_attr = $db_attr->attributes(); + $db_name = (string) $db_attr['name']; + $collation = (string) $db_attr['collation']; + $charset = (string) $db_attr['charset']; + } else { + /** + * If the structure section is not present + * get the database name from the data section + */ + $db_attr = $xml->children() + ->attributes(); + $db_name = (string) $db_attr['name']; + $collation = null; + $charset = null; + } + + /** + * The XML was malformed + */ + if ($db_name === null) { + Message::error( + __( + 'The XML file specified was either malformed or incomplete.' + . ' Please correct the issue and try again.' + ) + ) + ->display(); + unset($xml); + $GLOBALS['finished'] = false; + + return; + } + + /** + * Retrieve the structure information + */ + if (isset($namespaces['pma'])) { + /** + * Get structures for all tables + * + * @var SimpleXMLElement $struct + */ + $struct = $xml->children($namespaces['pma']); + + $create = []; + + /** @var SimpleXMLElement $val1 */ + foreach ($struct as $val1) { + /** @var SimpleXMLElement $val2 */ + foreach ($val1 as $val2) { + // Need to select the correct database for the creation of + // tables, views, triggers, etc. + /** + * @todo Generating a USE here blocks importing of a table + * into another database. + */ + $attrs = $val2->attributes(); + $create[] = "USE " + . Util::backquote( + $attrs["name"] + ); + + foreach ($val2 as $val3) { + /** + * Remove the extra cosmetic spacing + */ + $val3 = str_replace(" ", "", (string) $val3); + $create[] = $val3; + } + } + } + + $struct_present = true; + } + + /** + * Move down the XML tree to the actual data + */ + $xml = $xml->children() + ->children(); + + $data_present = false; + + /** + * Only attempt to analyze/collect data if there is data present + */ + if ($xml && @count($xml->children())) { + $data_present = true; + + /** + * Process all database content + */ + foreach ($xml as $v1) { + $tbl_attr = $v1->attributes(); + + $isInTables = false; + $num_tables = count($tables); + for ($i = 0; $i < $num_tables; ++$i) { + if (! strcmp($tables[$i][Import::TBL_NAME], (string) $tbl_attr['name'])) { + $isInTables = true; + break; + } + } + + if (! $isInTables) { + $tables[] = [(string) $tbl_attr['name']]; + } + + foreach ($v1 as $v2) { + $row_attr = $v2->attributes(); + if (! array_search((string) $row_attr['name'], $tempRow)) { + $tempRow[] = (string) $row_attr['name']; + } + $tempCells[] = (string) $v2; + } + + $rows[] = [ + (string) $tbl_attr['name'], + $tempRow, + $tempCells, + ]; + + $tempRow = []; + $tempCells = []; + } + + unset($tempRow); + unset($tempCells); + unset($xml); + + /** + * Bring accumulated rows into the corresponding table + */ + $num_tables = count($tables); + for ($i = 0; $i < $num_tables; ++$i) { + $num_rows = count($rows); + for ($j = 0; $j < $num_rows; ++$j) { + if (! strcmp($tables[$i][Import::TBL_NAME], $rows[$j][Import::TBL_NAME])) { + if (! isset($tables[$i][Import::COL_NAMES])) { + $tables[$i][] = $rows[$j][Import::COL_NAMES]; + } + + $tables[$i][Import::ROWS][] = $rows[$j][Import::ROWS]; + } + } + } + + unset($rows); + + if (! $struct_present) { + $analyses = []; + + $len = count($tables); + for ($i = 0; $i < $len; ++$i) { + $analyses[] = $this->import->analyzeTable($tables[$i]); + } + } + } + + unset($xml); + unset($tempCells); + unset($rows); + + /** + * Only build SQL from data if there is data present + */ + if ($data_present) { + /** + * Set values to NULL if they were not present + * to maintain Import::buildSql() call integrity + */ + if (! isset($analyses)) { + $analyses = null; + if (! $struct_present) { + $create = null; + } + } + } + + /** + * string $db_name (no backquotes) + * + * array $table = array(table_name, array() column_names, array()() rows) + * array $tables = array of "$table"s + * + * array $analysis = array(array() column_types, array() column_sizes) + * array $analyses = array of "$analysis"s + * + * array $create = array of SQL strings + * + * array $options = an associative array of options + */ + + /* Set database name to the currently selected one, if applicable */ + if (strlen((string) $db)) { + /* Override the database name in the XML file, if one is selected */ + $db_name = $db; + $options = ['create_db' => false]; + } else { + if ($db_name === null) { + $db_name = 'XML_DB'; + } + + /* Set database collation/charset */ + $options = [ + 'db_collation' => $collation, + 'db_charset' => $charset, + ]; + } + + /* Created and execute necessary SQL statements from data */ + $this->import->buildSql($db_name, $tables, $analyses, $create, $options, $sql_data); + + unset($analyses); + unset($tables); + unset($create); + + /* Commit any possible data in buffers */ + $this->import->runQuery('', '', $sql_data); + } +} |
