Initial commit

This commit is contained in:
2022-11-21 09:47:28 +01:00
commit 76cec83d26
11652 changed files with 1980467 additions and 0 deletions

View File

@ -0,0 +1,443 @@
<?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
*/
namespace PMA\libraries\plugins\export;
use PMA\libraries\plugins\ExportPlugin;
use PMA\libraries\properties\plugins\ExportPluginProperties;
use PMA\libraries\properties\options\items\HiddenPropertyItem;
use PMA\libraries\properties\options\groups\OptionsPropertyMainGroup;
use PMA\libraries\properties\options\groups\OptionsPropertyRootGroup;
use PMA;
use PMA\libraries\properties\options\items\SelectPropertyItem;
use PMA\libraries\plugins\export\TableProperty;
/**
* 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()
{
$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(
"Format Specific Options"
);
// general options main group
$generalOptions = new OptionsPropertyMainGroup("general_opts");
// create primary items and add them to the group
$leaf = new HiddenPropertyItem("structure_or_data");
$generalOptions->addProperty($leaf);
$leaf = new SelectPropertyItem(
"format",
__('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;
}
/**
* 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
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBHeader($db, $db_alias = '')
{
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
* @param string $export_type 'server', 'database', 'table'
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBCreate($db, $export_type, $db_alias = '')
{
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
* @param array $aliases Aliases of db/table/columns
*
* @return bool Whether it succeeded
*/
public function exportData(
$db,
$table,
$crlf,
$error_url,
$sql_query,
$aliases = array()
) {
$CG_FORMATS = $this->_getCgFormats();
$CG_HANDLERS = $this->_getCgHandlers();
$format = $GLOBALS['codegen_format'];
if (isset($CG_FORMATS[$format])) {
$method = $CG_HANDLERS[$format];
return PMA_exportOutputHandler(
$this->$method($db, $table, $crlf, $aliases)
);
}
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
* @param array $aliases Aliases of db/table/columns
*
* @return string containing C# code lines, separated by "\n"
*/
private function _handleNHibernateCSBody($db, $table, $crlf, $aliases = array())
{
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
$lines = array();
$result = $GLOBALS['dbi']->query(
sprintf(
'DESC %s.%s',
PMA\libraries\Util::backquote($db),
PMA\libraries\Util::backquote($table)
)
);
if ($result) {
/** @var TableProperty[] $tableProperties */
$tableProperties = array();
while ($row = $GLOBALS['dbi']->fetchRow($result)) {
$col_as = $this->getAlias($aliases, $row[0], 'col', $db, $table);
if (!empty($col_as)) {
$row[0] = $col_as;
}
$tableProperties[] = new TableProperty($row);
}
$GLOBALS['dbi']->freeResult($result);
$lines[] = 'using System;';
$lines[] = 'using System.Collections;';
$lines[] = 'using System.Collections.Generic;';
$lines[] = 'using System.Text;';
$lines[] = 'namespace ' . ExportCodegen::cgMakeIdentifier($db_alias);
$lines[] = '{';
$lines[] = ' #region '
. ExportCodegen::cgMakeIdentifier($table_alias);
$lines[] = ' public class '
. ExportCodegen::cgMakeIdentifier($table_alias);
$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_alias) . '() { }';
$temp = array();
foreach ($tableProperties as $tableProperty) {
if (!$tableProperty->isPK()) {
$temp[] = $tableProperty->formatCs(
'#dotNetPrimitiveType# #name#'
);
}
}
$lines[] = ' public '
. ExportCodegen::cgMakeIdentifier($table_alias)
. '('
. 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($crlf, $lines);
}
/**
* XML Handler
*
* @param string $db database name
* @param string $table table name
* @param string $crlf line separator
* @param array $aliases Aliases of db/table/columns
*
* @return string containing XML code lines, separated by "\n"
*/
private function _handleNHibernateXMLBody(
$db,
$table,
$crlf,
$aliases = array()
) {
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
$lines = array();
$lines[] = '<?xml version="1.0" encoding="utf-8" ?' . '>';
$lines[] = '<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" '
. 'namespace="' . ExportCodegen::cgMakeIdentifier($db_alias) . '" '
. 'assembly="' . ExportCodegen::cgMakeIdentifier($db_alias) . '">';
$lines[] = ' <class '
. 'name="' . ExportCodegen::cgMakeIdentifier($table_alias) . '" '
. 'table="' . ExportCodegen::cgMakeIdentifier($table_alias) . '">';
$result = $GLOBALS['dbi']->query(
sprintf(
"DESC %s.%s",
PMA\libraries\Util::backquote($db),
PMA\libraries\Util::backquote($table)
)
);
if ($result) {
while ($row = $GLOBALS['dbi']->fetchRow($result)) {
$col_as = $this->getAlias($aliases, $row[0], 'col', $db, $table);
if (!empty($col_as)) {
$row[0] = $col_as;
}
$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>'
);
}
}
$GLOBALS['dbi']->freeResult($result);
}
$lines[] = ' </class>';
$lines[] = '</hibernate-mapping>';
return implode($crlf, $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;
}
}

View File

@ -0,0 +1,331 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* CSV export code
*
* @package PhpMyAdmin-Export
* @subpackage CSV
*/
namespace PMA\libraries\plugins\export;
use PMA\libraries\properties\options\items\BoolPropertyItem;
use PMA\libraries\plugins\ExportPlugin;
use PMA\libraries\properties\plugins\ExportPluginProperties;
use PMA\libraries\properties\options\items\HiddenPropertyItem;
use PMA\libraries\properties\options\groups\OptionsPropertyMainGroup;
use PMA\libraries\properties\options\groups\OptionsPropertyRootGroup;
use PMA;
use PMA\libraries\properties\options\items\TextPropertyItem;
/**
* Handles the export for the CSV format
*
* @package PhpMyAdmin-Export
* @subpackage CSV
*/
class ExportCsv extends ExportPlugin
{
/**
* Constructor
*/
public function __construct()
{
$this->setProperties();
}
/**
* Sets the export CSV properties
*
* @return void
*/
protected function setProperties()
{
$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(
"Format Specific Options"
);
// general options main group
$generalOptions = new OptionsPropertyMainGroup("general_opts");
// create leaf items and add them to the group
$leaf = new TextPropertyItem(
"separator",
__('Columns separated with:')
);
$generalOptions->addProperty($leaf);
$leaf = new TextPropertyItem(
"enclosed",
__('Columns enclosed with:')
);
$generalOptions->addProperty($leaf);
$leaf = new TextPropertyItem(
"escaped",
__('Columns escaped with:')
);
$generalOptions->addProperty($leaf);
$leaf = new TextPropertyItem(
"terminated",
__('Lines terminated with:')
);
$generalOptions->addProperty($leaf);
$leaf = new TextPropertyItem(
'null',
__('Replace NULL with:')
);
$generalOptions->addProperty($leaf);
$leaf = new BoolPropertyItem(
'removeCRLF',
__('Remove carriage return/line feed characters within columns')
);
$generalOptions->addProperty($leaf);
$leaf = new BoolPropertyItem(
'columns',
__('Put columns names in the first row')
);
$generalOptions->addProperty($leaf);
$leaf = new HiddenPropertyItem(
'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;
}
/**
* 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)
|| mb_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
* @param string $db_alias Alias of db
*
* @return bool Whether it succeeded
*/
public function exportDBHeader($db, $db_alias = '')
{
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
* @param string $export_type 'server', 'database', 'table'
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBCreate($db, $export_type, $db_alias = '')
{
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
* @param array $aliases Aliases of db/table/columns
*
* @return bool Whether it succeeded
*/
public function exportData(
$db,
$table,
$crlf,
$error_url,
$sql_query,
$aliases = array()
) {
global $what, $csv_terminated, $csv_separator, $csv_enclosed, $csv_escaped;
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
// Gets the data from the database
$result = $GLOBALS['dbi']->query(
$sql_query,
null,
PMA\libraries\DatabaseInterface::QUERY_UNBUFFERED
);
$fields_cnt = $GLOBALS['dbi']->numFields($result);
// If required, get fields name at the first line
if (isset($GLOBALS['csv_columns'])) {
$schema_insert = '';
for ($i = 0; $i < $fields_cnt; $i++) {
$col_as = $GLOBALS['dbi']->fieldName($result, $i);
if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
$col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
}
$col_as = stripslashes($col_as);
if ($csv_enclosed == '') {
$schema_insert .= $col_as;
} else {
$schema_insert .= $csv_enclosed
. str_replace(
$csv_enclosed,
$csv_escaped . $csv_enclosed,
$col_as
)
. $csv_enclosed;
}
$schema_insert .= $csv_separator;
} // end for
$schema_insert = trim(mb_substr($schema_insert, 0, -1));
if (!PMA_exportOutputHandler($schema_insert . $csv_terminated)) {
return false;
}
} // end if
// Format the data
while ($row = $GLOBALS['dbi']->fetchRow($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
$GLOBALS['dbi']->freeResult($result);
return true;
}
}

View File

@ -0,0 +1,88 @@
<?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
*/
namespace PMA\libraries\plugins\export;
use PMA\libraries\properties\options\items\BoolPropertyItem;
use PMA\libraries\properties\plugins\ExportPluginProperties;
use PMA\libraries\properties\options\items\HiddenPropertyItem;
use PMA\libraries\properties\options\groups\OptionsPropertyMainGroup;
use PMA\libraries\properties\options\groups\OptionsPropertyRootGroup;
use PMA\libraries\properties\options\items\SelectPropertyItem;
use PMA\libraries\properties\options\items\TextPropertyItem;
/**
* 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()
{
$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(
"Format Specific Options"
);
// general options main group
$generalOptions = new OptionsPropertyMainGroup("general_opts");
// create primary items and add them to the group
$leaf = new TextPropertyItem(
'null',
__('Replace NULL with:')
);
$generalOptions->addProperty($leaf);
$leaf = new BoolPropertyItem(
'removeCRLF',
__('Remove carriage return/line feed characters within columns')
);
$generalOptions->addProperty($leaf);
$leaf = new BoolPropertyItem(
'columns',
__('Put columns names in the first row')
);
$generalOptions->addProperty($leaf);
$leaf = new SelectPropertyItem(
'edition',
__('Excel edition:')
);
$leaf->setValues(
array(
'win' => 'Windows',
'mac_excel2003' => 'Excel 2003 / Macintosh',
'mac_excel2008' => 'Excel 2008 / Macintosh',
)
);
$generalOptions->addProperty($leaf);
$leaf = new HiddenPropertyItem(
'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;
}
}

View File

@ -0,0 +1,665 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* HTML-Word export code
*
* @package PhpMyAdmin-Export
* @subpackage HTML-Word
*/
namespace PMA\libraries\plugins\export;
use PMA\libraries\properties\options\items\BoolPropertyItem;
use PMA\libraries\properties\options\groups\OptionsPropertyMainGroup;
use PMA\libraries\properties\options\groups\OptionsPropertyRootGroup;
use PMA\libraries\plugins\ExportPlugin;
use PMA\libraries\properties\plugins\ExportPluginProperties;
use PMA\libraries\DatabaseInterface;
use PMA\libraries\Util;
use PMA\libraries\properties\options\items\RadioPropertyItem;
use PMA\libraries\properties\options\items\TextPropertyItem;
/**
* 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()
{
$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(
"Format Specific Options"
);
// what to dump (structure/data/both)
$dumpWhat = new OptionsPropertyMainGroup(
"dump_what", __('Dump table')
);
// create primary items and add them to the group
$leaf = new RadioPropertyItem("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(
"dump_what", __('Data dump options')
);
$dataOptions->setForce('structure');
// create primary items and add them to the group
$leaf = new TextPropertyItem(
"null",
__('Replace NULL with:')
);
$dataOptions->addProperty($leaf);
$leaf = new BoolPropertyItem(
"columns",
__('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;
}
/**
* Outputs export header
*
* @return bool Whether it succeeded
*/
public function exportHeader()
{
global $charset;
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) ? $charset : '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
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBHeader($db, $db_alias = '')
{
if (empty($db_alias)) {
$db_alias = $db;
}
return PMA_exportOutputHandler(
'<h1>' . __('Database') . ' ' . htmlspecialchars($db_alias) . '</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
* @param string $export_type 'server', 'database', 'table'
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBCreate($db, $export_type, $db_alias = '')
{
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
* @param array $aliases Aliases of db/table/columns
*
* @return bool Whether it succeeded
*/
public function exportData(
$db,
$table,
$crlf,
$error_url,
$sql_query,
$aliases = array()
) {
global $what;
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
if (!PMA_exportOutputHandler(
'<h2>'
. __('Dumping data for table') . ' ' . htmlspecialchars($table_alias)
. '</h2>'
)
) {
return false;
}
if (!PMA_exportOutputHandler(
'<table class="width100" cellspacing="1">'
)
) {
return false;
}
// Gets the data from the database
$result = $GLOBALS['dbi']->query(
$sql_query,
null,
DatabaseInterface::QUERY_UNBUFFERED
);
$fields_cnt = $GLOBALS['dbi']->numFields($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++) {
$col_as = $GLOBALS['dbi']->fieldName($result, $i);
if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
$col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
}
$col_as = stripslashes($col_as);
$schema_insert .= '<td class="print"><strong>'
. htmlspecialchars($col_as)
. '</strong></td>';
} // end for
$schema_insert .= '</tr>';
if (!PMA_exportOutputHandler($schema_insert)) {
return false;
}
} // end if
// Format the data
while ($row = $GLOBALS['dbi']->fetchRow($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
$GLOBALS['dbi']->freeResult($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
* @param array $aliases Aliases of db/table/columns
*
* @return string resulting definition
*/
public function getTableDefStandIn($db, $view, $crlf, $aliases = array())
{
$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 = $GLOBALS['dbi']->getTableIndexes($db, $view);
foreach ($keys as $key) {
if ($key['Non_unique'] == 0) {
$unique_keys[] = $key['Column_name'];
}
}
$columns = $GLOBALS['dbi']->getColumns($db, $view);
foreach ($columns as $column) {
$col_as = $column['Field'];
if (!empty($aliases[$db]['tables'][$view]['columns'][$col_as])) {
$col_as = $aliases[$db]['tables'][$view]['columns'][$col_as];
}
$schema_insert .= $this->formatOneColumnDefinition(
$column,
$unique_keys,
$col_as
);
$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 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
* at the end
* @param bool $view whether we're handling a view
* @param array $aliases Aliases of db/table/columns
*
* @return string resulting schema
*/
public function getTableDef(
$db,
$table,
$do_relation,
$do_comments,
$do_mime,
$view = false,
$aliases = array()
) {
// set $cfgRelation here, because there is a chance that it's modified
// since the class initialization
global $cfgRelation;
$schema_insert = '';
/**
* Gets fields properties
*/
$GLOBALS['dbi']->selectDb($db);
// Check if we can use Relations
list($res_rel, $have_rel) = PMA_getRelationsAndStatus(
$do_relation && !empty($cfgRelation['relation']),
$db,
$table
);
/**
* Displays the table structure
*/
$schema_insert .= '<table class="width100" cellspacing="1">';
$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 = $GLOBALS['dbi']->getColumns($db, $table);
/**
* Get the unique keys in the table
*/
$unique_keys = array();
$keys = $GLOBALS['dbi']->getTableIndexes($db, $table);
foreach ($keys as $key) {
if ($key['Non_unique'] == 0) {
$unique_keys[] = $key['Column_name'];
}
}
foreach ($columns as $column) {
$col_as = $column['Field'];
if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
$col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
}
$schema_insert .= $this->formatOneColumnDefinition(
$column,
$unique_keys,
$col_as
);
$field_name = $column['Field'];
if ($do_relation && $have_rel) {
$schema_insert .= '<td class="print">'
. htmlspecialchars(
$this->getRelationString(
$res_rel,
$field_name,
$db,
$aliases
)
)
. '</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 = $GLOBALS['dbi']->getTriggers($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
* @param array $aliases Aliases of db/table/columns
*
* @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,
$aliases = array()
) {
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
$dump = '';
switch ($export_mode) {
case 'create_table':
$dump .= '<h2>'
. __('Table structure for table') . ' '
. htmlspecialchars($table_alias)
. '</h2>';
$dump .= $this->getTableDef(
$db,
$table,
$do_relation,
$do_comments,
$do_mime,
false,
$aliases
);
break;
case 'triggers':
$dump = '';
$triggers = $GLOBALS['dbi']->getTriggers($db, $table);
if ($triggers) {
$dump .= '<h2>'
. __('Triggers') . ' ' . htmlspecialchars($table_alias)
. '</h2>';
$dump .= $this->getTriggers($db, $table);
}
break;
case 'create_view':
$dump .= '<h2>'
. __('Structure for view') . ' ' . htmlspecialchars($table_alias)
. '</h2>';
$dump .= $this->getTableDef(
$db,
$table,
$do_relation,
$do_comments,
$do_mime,
true,
$aliases
);
break;
case 'stand_in':
$dump .= '<h2>'
. __('Stand-in structure for view') . ' '
. htmlspecialchars($table_alias)
. '</h2>';
// export a stand-in definition to resolve view dependencies
$dump .= $this->getTableDefStandIn($db, $table, $crlf, $aliases);
} // 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
* @param string $col_alias Column Alias
*
* @return string Formatted column definition
*/
protected function formatOneColumnDefinition(
$column,
$unique_keys,
$col_alias = ''
) {
if (empty($col_alias)) {
$col_alias = $column['Field'];
}
$definition = '<tr class="print-category">';
$extracted_columnspec = Util::extractColumnSpec($column['Type']);
$type = htmlspecialchars($extracted_columnspec['print_type']);
if (empty($type)) {
$type = '&nbsp;';
}
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($col_alias) . $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;
}
}

View File

@ -0,0 +1,238 @@
<?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
*/
namespace PMA\libraries\plugins\export;
use PMA\libraries\properties\options\items\BoolPropertyItem;
use PMA\libraries\plugins\ExportPlugin;
use PMA\libraries\properties\plugins\ExportPluginProperties;
use PMA\libraries\properties\options\items\HiddenPropertyItem;
use PMA\libraries\properties\options\groups\OptionsPropertyMainGroup;
use PMA\libraries\properties\options\groups\OptionsPropertyRootGroup;
use PMA;
/**
* 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()
{
$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(
"Format Specific Options"
);
// general options main group
$generalOptions = new OptionsPropertyMainGroup("general_opts");
// create primary items and add them to the group
$leaf = new HiddenPropertyItem("structure_or_data");
$generalOptions->addProperty($leaf);
// JSON_PRETTY_PRINT is available since 5.4.0
if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
$leaf = new BoolPropertyItem(
'pretty_print',
__('Output pretty-printed JSON (Use human-readable formatting)')
);
$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;
}
/**
* Outputs export header
*
* @return bool Whether it succeeded
*/
public function exportHeader()
{
PMA_exportOutputHandler(
'/**' . $GLOBALS['crlf']
. ' Export to JSON plugin for PHPMyAdmin' . $GLOBALS['crlf']
. ' @version ' . PMA_VERSION . $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
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBHeader($db, $db_alias = '')
{
if (empty($db_alias)) {
$db_alias = $db;
}
PMA_exportOutputHandler(
'// Database \'' . $db_alias . '\'' . $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
* @param string $export_type 'server', 'database', 'table'
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBCreate($db, $export_type, $db_alias = '')
{
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
* @param array $aliases Aliases of db/table/columns
*
* @return bool Whether it succeeded
*/
public function exportData(
$db,
$table,
$crlf,
$error_url,
$sql_query,
$aliases = array()
) {
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
$result = $GLOBALS['dbi']->query(
$sql_query,
null,
PMA\libraries\DatabaseInterface::QUERY_UNBUFFERED
);
$columns_cnt = $GLOBALS['dbi']->numFields($result);
$columns = array();
for ($i = 0; $i < $columns_cnt; $i++) {
$col_as = $GLOBALS['dbi']->fieldName($result, $i);
if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
$col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
}
$columns[$i] = stripslashes($col_as);
}
$record_cnt = 0;
while ($record = $GLOBALS['dbi']->fetchRow($result)) {
$record_cnt++;
// Output table name as comment if this is the first record of the table
if ($record_cnt == 1) {
$buffer = $crlf . '// ' . $db_alias . '.' . $table_alias
. $crlf . $crlf;
$buffer .= '[';
} else {
$buffer = ', ';
}
if (!PMA_exportOutputHandler($buffer)) {
return false;
}
$data = array();
for ($i = 0; $i < $columns_cnt; $i++) {
$data[$columns[$i]] = $record[$i];
}
if (isset($GLOBALS['json_pretty_print'])
&& $GLOBALS['json_pretty_print']
) {
$encoded = json_encode($data, JSON_PRETTY_PRINT);
} else {
$encoded = json_encode($data);
}
if (!PMA_exportOutputHandler($encoded)) {
return false;
}
}
if ($record_cnt) {
if (!PMA_exportOutputHandler(']' . $crlf)) {
return false;
}
}
$GLOBALS['dbi']->freeResult($result);
return true;
}
}

View File

@ -0,0 +1,675 @@
<?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
*/
namespace PMA\libraries\plugins\export;
use PMA\libraries\properties\options\items\BoolPropertyItem;
use PMA\libraries\properties\plugins\ExportPluginProperties;
use PMA\libraries\properties\options\groups\OptionsPropertyMainGroup;
use PMA\libraries\properties\options\groups\OptionsPropertyRootGroup;
use PMA\libraries\plugins\ExportPlugin;
use PMA\libraries\DatabaseInterface;
use PMA\libraries\Util;
use PMA\libraries\properties\options\items\RadioPropertyItem;
use PMA\libraries\properties\options\items\TextPropertyItem;
/**
* 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;
}
$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(
"Format Specific Options"
);
// general options main group
$generalOptions = new OptionsPropertyMainGroup("general_opts");
// create primary items and add them to the group
$leaf = new BoolPropertyItem(
"caption",
__('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(
"dump_what", __('Dump table')
);
// create primary items and add them to the group
$leaf = new RadioPropertyItem("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(
"structure", __('Object creation options')
);
$structureOptions->setForce('data');
// create primary items and add them to the group
$leaf = new TextPropertyItem(
"structure_caption",
__('Table caption:')
);
$leaf->setDoc('faq6-27');
$structureOptions->addProperty($leaf);
$leaf = new TextPropertyItem(
"structure_continued_caption",
__('Table caption (continued):')
);
$leaf->setDoc('faq6-27');
$structureOptions->addProperty($leaf);
$leaf = new TextPropertyItem(
"structure_label",
__('Label key:')
);
$leaf->setDoc('faq6-27');
$structureOptions->addProperty($leaf);
if (!empty($GLOBALS['cfgRelation']['relation'])) {
$leaf = new BoolPropertyItem(
"relation",
__('Display foreign key relationships')
);
$structureOptions->addProperty($leaf);
}
$leaf = new BoolPropertyItem(
"comments",
__('Display comments')
);
$structureOptions->addProperty($leaf);
if (!empty($GLOBALS['cfgRelation']['mimework'])) {
$leaf = new BoolPropertyItem(
"mime",
__('Display MIME types')
);
$structureOptions->addProperty($leaf);
}
// add the main group to the root group
$exportSpecificOptions->addProperty($structureOptions);
}
// data options main group
$dataOptions = new OptionsPropertyMainGroup(
"data", __('Data dump options')
);
$dataOptions->setForce('structure');
// create primary items and add them to the group
$leaf = new BoolPropertyItem(
"columns",
__('Put columns names in the first row:')
);
$dataOptions->addProperty($leaf);
$leaf = new TextPropertyItem(
"data_caption",
__('Table caption:')
);
$leaf->setDoc('faq6-27');
$dataOptions->addProperty($leaf);
$leaf = new TextPropertyItem(
"data_continued_caption",
__('Table caption (continued):')
);
$leaf->setDoc('faq6-27');
$dataOptions->addProperty($leaf);
$leaf = new TextPropertyItem(
"data_label",
__('Label key:')
);
$leaf->setDoc('faq6-27');
$dataOptions->addProperty($leaf);
$leaf = new TextPropertyItem(
'null',
__('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;
}
/**
* Outputs export header
*
* @return bool Whether it succeeded
*/
public function exportHeader()
{
global $crlf;
global $cfg;
$head = '% phpMyAdmin LaTeX Dump' . $crlf
. '% version ' . PMA_VERSION . $crlf
. '% https://www.phpmyadmin.net/' . $crlf
. '%' . $crlf
. '% ' . __('Host:') . ' ' . $cfg['Server']['host'];
if (!empty($cfg['Server']['port'])) {
$head .= ':' . $cfg['Server']['port'];
}
$head .= $crlf
. '% ' . __('Generation Time:') . ' '
. 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
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBHeader($db, $db_alias = '')
{
if (empty($db_alias)) {
$db_alias = $db;
}
global $crlf;
$head = '% ' . $crlf
. '% ' . __('Database:') . ' ' . '\'' . $db_alias . '\'' . $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
* @param string $export_type 'server', 'database', 'table'
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBCreate($db, $export_type, $db_alias = '')
{
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
* @param array $aliases Aliases of db/table/columns
*
* @return bool Whether it succeeded
*/
public function exportData(
$db,
$table,
$crlf,
$error_url,
$sql_query,
$aliases = array()
) {
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
$result = $GLOBALS['dbi']->tryQuery(
$sql_query,
null,
DatabaseInterface::QUERY_UNBUFFERED
);
$columns_cnt = $GLOBALS['dbi']->numFields($result);
$columns = array();
$columns_alias = array();
for ($i = 0; $i < $columns_cnt; $i++) {
$columns[$i] = $col_as = $GLOBALS['dbi']->fieldName($result, $i);
if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
$col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
}
$columns_alias[$i] = $col_as;
}
$buffer = $crlf . '%' . $crlf . '% ' . __('Data:') . ' ' . $table_alias
. $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{'
. Util::expandUserString(
$GLOBALS['latex_data_caption'],
array(
'texEscape',
get_class($this),
),
array('table' => $table_alias, 'database' => $db_alias)
)
. '} \\label{'
. Util::expandUserString(
$GLOBALS['latex_data_label'],
null,
array('table' => $table_alias, 'database' => $db_alias)
)
. '} \\\\';
}
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_alias[$i])) . '}} & ';
}
$buffer = mb_substr($buffer, 0, -2) . '\\\\ \\hline \hline ';
if (!PMA_exportOutputHandler($buffer . ' \\endfirsthead ' . $crlf)) {
return false;
}
if (isset($GLOBALS['latex_caption'])) {
if (!PMA_exportOutputHandler(
'\\caption{'
. Util::expandUserString(
$GLOBALS['latex_data_continued_caption'],
array(
'texEscape',
get_class($this),
),
array('table' => $table_alias, 'database' => $db_alias)
)
. '} \\\\ '
)
) {
return false;
}
}
if (!PMA_exportOutputHandler($buffer . '\\endhead \\endfoot' . $crlf)) {
return false;
}
} else {
if (!PMA_exportOutputHandler('\\\\ \hline')) {
return false;
}
}
// print the whole table
while ($record = $GLOBALS['dbi']->fetchAssoc($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;
}
$GLOBALS['dbi']->freeResult($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
* @param array $aliases Aliases of db/table/columns
*
* @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,
$aliases = array()
) {
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
global $cfgRelation;
/* We do not export triggers */
if ($export_mode == 'triggers') {
return true;
}
/**
* Get the unique keys in the table
*/
$unique_keys = array();
$keys = $GLOBALS['dbi']->getTableIndexes($db, $table);
foreach ($keys as $key) {
if ($key['Non_unique'] == 0) {
$unique_keys[] = $key['Column_name'];
}
}
/**
* Gets fields properties
*/
$GLOBALS['dbi']->selectDb($db);
// Check if we can use Relations
list($res_rel, $have_rel) = PMA_getRelationsAndStatus(
$do_relation && !empty($cfgRelation['relation']),
$db,
$table
);
/**
* Displays the table structure
*/
$buffer = $crlf . '%' . $crlf . '% ' . __('Structure:') . ' '
. $table_alias . $crlf . '%' . $crlf . ' \\begin{longtable}{';
if (!PMA_exportOutputHandler($buffer)) {
return false;
}
$alignment = '|l|c|c|c|';
if ($do_relation && $have_rel) {
$alignment .= 'l|';
}
if ($do_comments) {
$alignment .= 'l|';
}
if ($do_mime && $cfgRelation['mimework']) {
$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{'
. Util::expandUserString(
$GLOBALS['latex_structure_caption'],
array(
'texEscape',
get_class($this),
),
array('table' => $table_alias, 'database' => $db_alias)
)
. '} \\label{'
. Util::expandUserString(
$GLOBALS['latex_structure_label'],
null,
array('table' => $table_alias, 'database' => $db_alias)
)
. '} \\\\' . $crlf;
}
$buffer .= $header . ' \\\\ \\hline \\hline' . $crlf
. '\\endfirsthead' . $crlf;
// Table caption on next pages
if (isset($GLOBALS['latex_caption'])) {
$buffer .= ' \\caption{'
. Util::expandUserString(
$GLOBALS['latex_structure_continued_caption'],
array(
'texEscape',
get_class($this),
),
array('table' => $table_alias, 'database' => $db_alias)
)
. '} \\\\ ' . $crlf;
}
$buffer .= $header . ' \\\\ \\hline \\hline \\endhead \\endfoot ' . $crlf;
if (!PMA_exportOutputHandler($buffer)) {
return false;
}
$fields = $GLOBALS['dbi']->getColumns($db, $table);
foreach ($fields as $row) {
$extracted_columnspec = 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 = $col_as = $row['Field'];
if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
$col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
}
$local_buffer = $col_as . "\000" . $type . "\000"
. (($row['Null'] == '' || $row['Null'] == 'NO')
? __('No') : __('Yes'))
. "\000" . (isset($row['Default']) ? $row['Default'] : '');
if ($do_relation && $have_rel) {
$local_buffer .= "\000";
$local_buffer .= $this->getRelationString(
$res_rel,
$field_name,
$db,
$aliases
);
}
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 = mb_strpos($local_buffer, "\000");
$local_buffer = '\\textit{'
.
mb_substr($local_buffer, 0, $pos)
. '}' .
mb_substr($local_buffer, $pos);
}
if (in_array($field_name, $unique_keys)) {
$pos = mb_strpos($local_buffer, "\000");
$local_buffer = '\\textbf{'
.
mb_substr($local_buffer, 0, $pos)
. '}' .
mb_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;
}
}

View File

@ -0,0 +1,379 @@
<?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
*/
namespace PMA\libraries\plugins\export;
use PMA\libraries\properties\options\items\BoolPropertyItem;
use PMA\libraries\plugins\ExportPlugin;
use PMA\libraries\properties\plugins\ExportPluginProperties;
use PMA\libraries\properties\options\groups\OptionsPropertyMainGroup;
use PMA\libraries\properties\options\groups\OptionsPropertyRootGroup;
use PMA\libraries\properties\options\groups\OptionsPropertySubgroup;
use PMA;
use PMA\libraries\properties\options\items\RadioPropertyItem;
/**
* 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()
{
$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(
"Format Specific Options"
);
// general options main group
$generalOptions = new OptionsPropertyMainGroup(
"general_opts", __('Dump table')
);
// what to dump (structure/data/both)
$subgroup = new OptionsPropertySubgroup(
"dump_table", __("Dump table")
);
$leaf = new RadioPropertyItem('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(
"caption",
__('Export table names')
);
$generalOptions->addProperty($leaf);
// export table headers
$leaf = new BoolPropertyItem(
"headers",
__('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;
}
/**
* 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
* @param string $db_alias Alias of db
*
* @return bool Whether it succeeded
*/
public function exportDBHeader($db, $db_alias = '')
{
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
* @param string $export_type 'server', 'database', 'table'
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBCreate($db, $export_type, $db_alias = '')
{
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
* @param array $aliases Aliases of db/table/columns
*
* @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,
$aliases = array()
) {
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
$output = '';
switch ($export_mode) {
case 'create_table':
$columns = $GLOBALS['dbi']->getColumns($db, $table);
$columns = array_values($columns);
$row_cnt = count($columns);
// Print structure comment
$output = $this->_exportComment(
"Table structure for "
. PMA\libraries\Util::backquote($table_alias)
);
// Begin the table construction
$output .= "{| class=\"wikitable\" style=\"text-align:center;\""
. $this->_exportCRLF();
// Add the table name
if (isset($GLOBALS['mediawiki_caption'])) {
$output .= "|+'''" . $table_alias . "'''" . $this->_exportCRLF();
}
// Add the table headers
if (isset($GLOBALS['mediawiki_headers'])) {
$output .= "|- style=\"background:#ffdead;\"" . $this->_exportCRLF();
$output .= "! style=\"background:#ffffff\" | "
. $this->_exportCRLF();
for ($i = 0; $i < $row_cnt; ++$i) {
$col_as = $columns[$i]['Field'];
if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])
) {
$col_as
= $aliases[$db]['tables'][$table]['columns'][$col_as];
}
$output .= " | " . $col_as . $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
* @param array $aliases Aliases of db/table/columns
*
* @return bool Whether it succeeded
*/
public function exportData(
$db,
$table,
$crlf,
$error_url,
$sql_query,
$aliases = array()
) {
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
// Print data comment
$output = $this->_exportComment(
"Table data for " . PMA\libraries\Util::backquote($table_alias)
);
// 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 (isset($GLOBALS['mediawiki_caption'])) {
$output .= "|+'''" . $table_alias . "'''" . $this->_exportCRLF();
}
// Add the table headers
if (isset($GLOBALS['mediawiki_headers'])) {
// Get column names
$column_names = $GLOBALS['dbi']->getColumnNames($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) {
if (!empty($aliases[$db]['tables'][$table]['columns'][$column])
) {
$column
= $aliases[$db]['tables'][$table]['columns'][$column];
}
$output .= " ! " . $column . "" . $this->_exportCRLF();
}
}
}
// Get the table data from the database
$result = $GLOBALS['dbi']->query(
$sql_query,
null,
PMA\libraries\DatabaseInterface::QUERY_UNBUFFERED
);
$fields_cnt = $GLOBALS['dbi']->numFields($result);
while ($row = $GLOBALS['dbi']->fetchRow($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 .= htmlspecialchars($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";
}
}

View File

@ -0,0 +1,342 @@
<?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
*/
namespace PMA\libraries\plugins\export;
use PMA\libraries\properties\options\items\BoolPropertyItem;
use PMA\libraries\plugins\ExportPlugin;
use PMA\libraries\properties\plugins\ExportPluginProperties;
use PMA\libraries\properties\options\items\HiddenPropertyItem;
use PMA\libraries\properties\options\groups\OptionsPropertyMainGroup;
use PMA\libraries\properties\options\groups\OptionsPropertyRootGroup;
use PMA\libraries\DatabaseInterface;
use PMA\libraries\properties\options\items\TextPropertyItem;
$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()
{
$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(
"Format Specific Options"
);
// general options main group
$generalOptions = new OptionsPropertyMainGroup("general_opts");
// create primary items and add them to the group
$leaf = new TextPropertyItem(
"null",
__('Replace NULL with:')
);
$generalOptions->addProperty($leaf);
$leaf = new BoolPropertyItem(
"columns",
__('Put columns names in the first row')
);
$generalOptions->addProperty($leaf);
$leaf = new HiddenPropertyItem("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;
}
/**
* 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
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBHeader($db, $db_alias = '')
{
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
* @param string $export_type 'server', 'database', 'table'
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBCreate($db, $export_type, $db_alias = '')
{
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
* @param array $aliases Aliases of db/table/columns
*
* @return bool Whether it succeeded
*/
public function exportData(
$db,
$table,
$crlf,
$error_url,
$sql_query,
$aliases = array()
) {
global $what;
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
// Gets the data from the database
$result = $GLOBALS['dbi']->query(
$sql_query,
null,
DatabaseInterface::QUERY_UNBUFFERED
);
$fields_cnt = $GLOBALS['dbi']->numFields($result);
$fields_meta = $GLOBALS['dbi']->getFieldsMeta($result);
$field_flags = array();
for ($j = 0; $j < $fields_cnt; $j++) {
$field_flags[$j] = $GLOBALS['dbi']->fieldFlags($result, $j);
}
$GLOBALS['ods_buffer']
.= '<table:table table:name="' . htmlspecialchars($table_alias) . '">';
// 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++) {
$col_as = $GLOBALS['dbi']->fieldName($result, $i);
if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
$col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
}
$GLOBALS['ods_buffer']
.= '<table:table-cell office:value-type="string">'
. '<text:p>'
. htmlspecialchars(
stripslashes($col_as)
)
. '</text:p>'
. '</table:table-cell>';
} // end for
$GLOBALS['ods_buffer'] .= '</table:table-row>';
} // end if
// Format the data
while ($row = $GLOBALS['dbi']->fetchRow($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
$GLOBALS['dbi']->freeResult($result);
$GLOBALS['ods_buffer'] .= '</table:table>';
return true;
}
}

View File

@ -0,0 +1,802 @@
<?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
*/
namespace PMA\libraries\plugins\export;
use PMA\libraries\properties\options\items\BoolPropertyItem;
use PMA\libraries\properties\plugins\ExportPluginProperties;
use PMA\libraries\properties\options\groups\OptionsPropertyMainGroup;
use PMA\libraries\properties\options\groups\OptionsPropertyRootGroup;
use PMA\libraries\DatabaseInterface;
use PMA\libraries\plugins\ExportPlugin;
use PMA\libraries\Util;
use PMA\libraries\properties\options\items\RadioPropertyItem;
use PMA\libraries\properties\options\items\TextPropertyItem;
$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;
}
$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(
"Format Specific Options"
);
// what to dump (structure/data/both) main group
$dumpWhat = new OptionsPropertyMainGroup(
"general_opts", __('Dump table')
);
// create primary items and add them to the group
$leaf = new RadioPropertyItem("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(
"structure", __('Object creation options')
);
$structureOptions->setForce('data');
// create primary items and add them to the group
if (!empty($GLOBALS['cfgRelation']['relation'])) {
$leaf = new BoolPropertyItem(
"relation",
__('Display foreign key relationships')
);
$structureOptions->addProperty($leaf);
}
$leaf = new BoolPropertyItem(
"comments",
__('Display comments')
);
$structureOptions->addProperty($leaf);
if (!empty($GLOBALS['cfgRelation']['mimework'])) {
$leaf = new BoolPropertyItem(
"mime",
__('Display MIME types')
);
$structureOptions->addProperty($leaf);
}
// add the main group to the root group
$exportSpecificOptions->addProperty($structureOptions);
}
// data options main group
$dataOptions = new OptionsPropertyMainGroup(
"data", __('Data dump options')
);
$dataOptions->setForce('structure');
// create primary items and add them to the group
$leaf = new BoolPropertyItem(
"columns",
__('Put columns names in the first row')
);
$dataOptions->addProperty($leaf);
$leaf = new TextPropertyItem(
'null',
__('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;
}
/**
* 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
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBHeader($db, $db_alias = '')
{
if (empty($db_alias)) {
$db_alias = $db;
}
$GLOBALS['odt_buffer']
.= '<text:h text:outline-level="1" text:style-name="Heading_1"'
. ' text:is-list-header="true">'
. __('Database') . ' ' . htmlspecialchars($db_alias)
. '</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
* @param string $export_type 'server', 'database', 'table'
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBCreate($db, $export_type, $db_alias = '')
{
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
* @param array $aliases Aliases of db/table/columns
*
* @return bool Whether it succeeded
*/
public function exportData(
$db,
$table,
$crlf,
$error_url,
$sql_query,
$aliases = array()
) {
global $what;
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
// Gets the data from the database
$result = $GLOBALS['dbi']->query(
$sql_query,
null,
DatabaseInterface::QUERY_UNBUFFERED
);
$fields_cnt = $GLOBALS['dbi']->numFields($result);
$fields_meta = $GLOBALS['dbi']->getFieldsMeta($result);
$field_flags = array();
for ($j = 0; $j < $fields_cnt; $j++) {
$field_flags[$j] = $GLOBALS['dbi']->fieldFlags($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_alias)
. '</text:h>'
. '<table:table'
. ' table:name="' . htmlspecialchars($table_alias) . '_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++) {
$col_as = $GLOBALS['dbi']->fieldName($result, $i);
if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
$col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
}
$GLOBALS['odt_buffer']
.= '<table:table-cell office:value-type="string">'
. '<text:p>'
. htmlspecialchars(
stripslashes($col_as)
)
. '</text:p>'
. '</table:table-cell>';
} // end for
$GLOBALS['odt_buffer'] .= '</table:table-row>';
} // end if
// Format the data
while ($row = $GLOBALS['dbi']->fetchRow($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
$GLOBALS['dbi']->freeResult($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
* @param array $aliases Aliases of db/table/columns
*
* @return string resulting definition
*/
public function getTableDefStandIn($db, $view, $crlf, $aliases = array())
{
$db_alias = $db;
$view_alias = $view;
$this->initAlias($aliases, $db_alias, $view_alias);
/**
* Gets fields properties
*/
$GLOBALS['dbi']->selectDb($db);
/**
* Displays the table structure
*/
$GLOBALS['odt_buffer']
.= '<table:table table:name="'
. htmlspecialchars($view_alias) . '_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 = $GLOBALS['dbi']->getColumns($db, $view);
foreach ($columns as $column) {
$col_as = $column['Field'];
if (!empty($aliases[$db]['tables'][$view]['columns'][$col_as])) {
$col_as = $aliases[$db]['tables'][$view]['columns'][$col_as];
}
$GLOBALS['odt_buffer'] .= $this->formatOneColumnDefinition(
$column,
$col_as
);
$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
* @param array $aliases Aliases of db/table/columns
*
* @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,
$aliases = array()
) {
global $cfgRelation;
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
/**
* Gets fields properties
*/
$GLOBALS['dbi']->selectDb($db);
// Check if we can use Relations
list($res_rel, $have_rel) = PMA_getRelationsAndStatus(
$do_relation && !empty($cfgRelation['relation']),
$db,
$table
);
/**
* Displays the table structure
*/
$GLOBALS['odt_buffer'] .= '<table:table table:name="'
. htmlspecialchars($table_alias) . '_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 = $GLOBALS['dbi']->getColumns($db, $table);
foreach ($columns as $column) {
$col_as = $field_name = $column['Field'];
if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
$col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
}
$GLOBALS['odt_buffer'] .= $this->formatOneColumnDefinition(
$column,
$col_as
);
if ($do_relation && $have_rel) {
$foreigner = PMA_searchColumnInForeigners($res_rel, $field_name);
if ($foreigner) {
$rtable = $foreigner['foreign_table'];
$rfield = $foreigner['foreign_field'];
if (!empty($aliases[$db]['tables'][$rtable]['columns'][$rfield])
) {
$rfield
= $aliases[$db]['tables'][$rtable]['columns'][$rfield];
}
if (!empty($aliases[$db]['tables'][$rtable]['alias'])) {
$rtable = $aliases[$db]['tables'][$rtable]['alias'];
}
$relation = htmlspecialchars($rtable . ' (' . $rfield . ')');
$GLOBALS['odt_buffer']
.= '<table:table-cell office:value-type="string">'
. '<text:p>'
. htmlspecialchars($relation)
. '</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
* @param array $aliases Aliases of db/table/columns
*
* @return bool true
*/
protected function getTriggers($db, $table, $aliases = array())
{
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
$GLOBALS['odt_buffer'] .= '<table:table'
. ' table:name="' . htmlspecialchars($table_alias) . '_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 = $GLOBALS['dbi']->getTriggers($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
* @param array $aliases Aliases of db/table/columns
*
* @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,
$aliases = array()
) {
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
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_alias)
. '</text:h>';
$this->getTableDef(
$db,
$table,
$crlf,
$error_url,
$do_relation,
$do_comments,
$do_mime,
$dates,
true,
false,
$aliases
);
break;
case 'triggers':
$triggers = $GLOBALS['dbi']->getTriggers($db, $table, $aliases);
if ($triggers) {
$GLOBALS['odt_buffer']
.= '<text:h text:outline-level="2" text:style-name="Heading_2"'
. ' text:is-list-header="true">'
. __('Triggers') . ' '
. htmlspecialchars($table_alias)
. '</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_alias)
. '</text:h>';
$this->getTableDef(
$db,
$table,
$crlf,
$error_url,
$do_relation,
$do_comments,
$do_mime,
$dates,
true,
true,
$aliases
);
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_alias)
. '</text:h>';
// export a stand-in definition to resolve view dependencies
$this->getTableDefStandIn($db, $table, $crlf, $aliases);
} // end switch
return true;
} // end of the '$this->exportStructure' function
/**
* Formats the definition for one column
*
* @param array $column info about this column
* @param string $col_as column alias
*
* @return string Formatted column definition
*/
protected function formatOneColumnDefinition($column, $col_as = '')
{
if (empty($col_as)) {
$col_as = $column['Field'];
}
$definition = '<table:table-row>';
$definition .= '<table:table-cell office:value-type="string">'
. '<text:p>' . htmlspecialchars($col_as) . '</text:p>'
. '</table:table-cell>';
$extracted_columnspec
= Util::extractColumnSpec($column['Type']);
$type = htmlspecialchars($extracted_columnspec['print_type']);
if (empty($type)) {
$type = '&nbsp;';
}
$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'] = '';
}
}
$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;
}
}

View File

@ -0,0 +1,390 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Produce a PDF report (export) from a query
*
* @package PhpMyAdmin-Export
* @subpackage PDF
*/
namespace PMA\libraries\plugins\export;
use PMA\libraries\plugins\ExportPlugin;
use PMA\libraries\properties\plugins\ExportPluginProperties;
use PMA\libraries\properties\options\groups\OptionsPropertyMainGroup;
use PMA\libraries\properties\options\groups\OptionsPropertyRootGroup;
use PMA\libraries\plugins\export\PMA_ExportPdf;
use PMA\libraries\properties\options\items\RadioPropertyItem;
use PMA\libraries\properties\options\items\TextPropertyItem;
/**
* Skip the plugin if TCPDF is not available.
*/
if (!@file_exists(TCPDF_INC)) {
$GLOBALS['skip_import'] = true;
return;
}
require_once 'libraries/transformations.lib.php';
/**
* Handles the export for the PDF class
*
* @package PhpMyAdmin-Export
* @subpackage PDF
*/
class ExportPdf extends ExportPlugin
{
/**
* PMA\libraries\plugins\export\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()
{
if (!empty($_POST['pdf_report_title'])) {
$this->_setPdfReportTitle($_POST['pdf_report_title']);
}
$this->_setPdf(new PMA_ExportPdf('L', 'pt', 'A3'));
}
/**
* Sets the export PDF properties
*
* @return void
*/
protected function setProperties()
{
$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(
"Format Specific Options"
);
// general options main group
$generalOptions = new OptionsPropertyMainGroup("general_opts");
// create primary items and add them to the group
$leaf = new TextPropertyItem(
"report_title",
__('Report title:')
);
$generalOptions->addProperty($leaf);
// add the group to the root group
$exportSpecificOptions->addProperty($generalOptions);
// what to dump (structure/data/both) main group
$dumpWhat = new OptionsPropertyMainGroup(
"dump_what", __('Dump table')
);
$leaf = new RadioPropertyItem("structure_or_data");
$leaf->setValues(
array(
'structure' => __('structure'),
'data' => __('data'),
'structure_and_data' => __('structure and data'),
)
);
$dumpWhat->addProperty($leaf);
// add the group to the root group
$exportSpecificOptions->addProperty($dumpWhat);
// set the options for the export plugin property item
$exportPluginProperties->setOptions($exportSpecificOptions);
$this->properties = $exportPluginProperties;
}
/**
* 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
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBHeader($db, $db_alias = '')
{
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
* @param string $export_type 'server', 'database', 'table'
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBCreate($db, $export_type, $db_alias = '')
{
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
* @param array $aliases Aliases of db/table/columns
*
* @return bool Whether it succeeded
*/
public function exportData(
$db,
$table,
$crlf,
$error_url,
$sql_query,
$aliases = array()
) {
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
$pdf = $this->_getPdf();
$attr = array(
'currentDb' => $db,
'currentTable' => $table,
'dbAlias' => $db_alias,
'tableAlias' => $table_alias,
'aliases' => $aliases,
);
$pdf->setAttributes($attr);
$pdf->purpose = __('Dumping data');
$pdf->mysqlReport($sql_query);
return true;
} // end of the 'PMA_exportData()' function
/**
* Outputs table 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
* @param array $aliases aliases for db/table/columns
*
* @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,
$aliases = array()
) {
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
$pdf = $this->_getPdf();
// getting purpose to show at top
switch ($export_mode) {
case 'create_table':
$purpose = __('Table structure');
break;
case 'triggers':
$purpose = __('Triggers');
break;
case 'create_view':
$purpose = __('View structure');
break;
case 'stand_in':
$purpose = __('Stand in');
} // end switch
$attr = array(
'currentDb' => $db,
'currentTable' => $table,
'dbAlias' => $db_alias,
'tableAlias' => $table_alias,
'aliases' => $aliases,
'purpose' => $purpose,
);
$pdf->setAttributes($attr);
/**
* comment display set true as presently in pdf
* format, no option is present to take user input.
*/
$do_comments = true;
switch ($export_mode) {
case 'create_table':
$pdf->getTableDef(
$db,
$table,
$do_relation,
$do_comments,
$do_mime,
false,
$aliases
);
break;
case 'triggers':
$pdf->getTriggers($db, $table);
break;
case 'create_view':
$pdf->getTableDef(
$db,
$table,
$do_relation,
$do_comments,
$do_mime,
false,
$aliases
);
break;
case 'stand_in':
/* export a stand-in definition to resolve view dependencies
* Yet to develop this function
* $pdf->getTableDefStandIn($db, $table, $crlf);
*/
} // end switch
return true;
}
/* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
/**
* Gets the PMA\libraries\plugins\export\PMA_ExportPdf instance
*
* @return PMA_ExportPdf
*/
private function _getPdf()
{
return $this->_pdf;
}
/**
* Instantiates the PMA\libraries\plugins\export\PMA_ExportPdf class
*
* @param PMA_ExportPdf $pdf The 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;
}
}

View File

@ -0,0 +1,255 @@
<?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
*/
namespace PMA\libraries\plugins\export;
use PMA\libraries\plugins\ExportPlugin;
use PMA\libraries\properties\plugins\ExportPluginProperties;
use PMA\libraries\properties\options\items\HiddenPropertyItem;
use PMA\libraries\properties\options\groups\OptionsPropertyMainGroup;
use PMA\libraries\properties\options\groups\OptionsPropertyRootGroup;
use PMA;
/**
* 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()
{
$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(
"Format Specific Options"
);
// general options main group
$generalOptions = new OptionsPropertyMainGroup("general_opts");
// create primary items and add them to the group
$leaf = new HiddenPropertyItem("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;
}
/**
* Removes end of comment from a string
*
* @param string $string String to replace
*
* @return string
*/
public function commentString($string)
{
return strtr($string, '*/', '-');
}
/**
* 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 ' . PMA_VERSION . $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
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBHeader($db, $db_alias = '')
{
if (empty($db_alias)) {
$db_alias = $db;
}
PMA_exportOutputHandler(
'/**' . $GLOBALS['crlf']
. ' * Database ' . $this->commentString(PMA\libraries\Util::backquote($db_alias))
. $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
* @param string $export_type 'server', 'database', 'table'
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBCreate($db, $export_type, $db_alias = '')
{
return true;
}
/**
* Outputs the content of a table in PHP array 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
* @param array $aliases Aliases of db/table/columns
*
* @return bool Whether it succeeded
*/
public function exportData(
$db,
$table,
$crlf,
$error_url,
$sql_query,
$aliases = array()
) {
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
$result = $GLOBALS['dbi']->query(
$sql_query,
null,
PMA\libraries\DatabaseInterface::QUERY_UNBUFFERED
);
$columns_cnt = $GLOBALS['dbi']->numFields($result);
$columns = array();
for ($i = 0; $i < $columns_cnt; $i++) {
$col_as = $GLOBALS['dbi']->fieldName($result, $i);
if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
$col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
}
$columns[$i] = stripslashes($col_as);
}
// fix variable names (based on
// https://www.php.net/manual/language.variables.basics.php)
if (!preg_match(
'/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/',
$table_alias
)
) {
// fix invalid characters in variable names by replacing them with
// underscores
$tablefixed = preg_replace(
'/[^a-zA-Z0-9_\x7f-\xff]/',
'_',
$table_alias
);
// variable name must not start with a number or dash...
if (preg_match('/^[a-zA-Z_\x7f-\xff]/', $tablefixed) === 0) {
$tablefixed = '_' . $tablefixed;
}
} else {
$tablefixed = $table;
}
$buffer = '';
$record_cnt = 0;
// Output table name as comment
$buffer .= $crlf . '/* '
. $this->commentString(PMA\libraries\Util::backquote($db_alias)) . '.'
. $this->commentString(PMA\libraries\Util::backquote($table_alias)) . ' */' . $crlf;
$buffer .= '$' . $tablefixed . ' = array(';
while ($record = $GLOBALS['dbi']->fetchRow($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;
}
$GLOBALS['dbi']->freeResult($result);
return true;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,616 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Export to Texy! text.
*
* @package PhpMyAdmin-Export
* @subpackage Texy!text
*/
namespace PMA\libraries\plugins\export;
use PMA\libraries\properties\options\items\BoolPropertyItem;
use PMA\libraries\properties\plugins\ExportPluginProperties;
use PMA\libraries\properties\options\groups\OptionsPropertyMainGroup;
use PMA\libraries\properties\options\groups\OptionsPropertyRootGroup;
use PMA\libraries\DatabaseInterface;
use PMA\libraries\plugins\ExportPlugin;
use PMA\libraries\Util;
use PMA\libraries\properties\options\items\RadioPropertyItem;
use PMA\libraries\properties\options\items\TextPropertyItem;
/**
* 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()
{
$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(
"Format Specific Options"
);
// what to dump (structure/data/both) main group
$dumpWhat = new OptionsPropertyMainGroup(
"general_opts", __('Dump table')
);
// create primary items and add them to the group
$leaf = new RadioPropertyItem("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(
"data", __('Data dump options')
);
$dataOptions->setForce('structure');
// create primary items and add them to the group
$leaf = new BoolPropertyItem(
"columns",
__('Put columns names in the first row')
);
$dataOptions->addProperty($leaf);
$leaf = new TextPropertyItem(
'null',
__('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;
}
/**
* 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
* @param string $db_alias Alias of db
*
* @return bool Whether it succeeded
*/
public function exportDBHeader($db, $db_alias = '')
{
if (empty($db_alias)) {
$db_alias = $db;
}
return PMA_exportOutputHandler(
'===' . __('Database') . ' ' . $db_alias . "\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
* @param string $export_type 'server', 'database', 'table'
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBCreate($db, $export_type, $db_alias = '')
{
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
* @param array $aliases Aliases of db/table/columns
*
* @return bool Whether it succeeded
*/
public function exportData(
$db,
$table,
$crlf,
$error_url,
$sql_query,
$aliases = array()
) {
global $what;
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
if (!PMA_exportOutputHandler(
'== ' . __('Dumping data for table') . ' ' . $table_alias . "\n\n"
)
) {
return false;
}
// Gets the data from the database
$result = $GLOBALS['dbi']->query(
$sql_query,
null,
DatabaseInterface::QUERY_UNBUFFERED
);
$fields_cnt = $GLOBALS['dbi']->numFields($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++) {
$col_as = $GLOBALS['dbi']->fieldName($result, $i);
if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
$col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
}
$text_output .= '|'
. htmlspecialchars(stripslashes($col_as));
} // end for
$text_output .= "\n|------\n";
if (!PMA_exportOutputHandler($text_output)) {
return false;
}
} // end if
// Format the data
while ($row = $GLOBALS['dbi']->fetchRow($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(
'|',
'&#124;',
htmlspecialchars($value)
);
} // end for
$text_output .= "\n";
if (!PMA_exportOutputHandler($text_output)) {
return false;
}
} // end while
$GLOBALS['dbi']->freeResult($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
* @param array $aliases Aliases of db/table/columns
*
* @return string resulting definition
*/
public function getTableDefStandIn($db, $view, $crlf, $aliases = array())
{
$text_output = '';
/**
* Get the unique keys in the table
*/
$unique_keys = array();
$keys = $GLOBALS['dbi']->getTableIndexes($db, $view);
foreach ($keys as $key) {
if ($key['Non_unique'] == 0) {
$unique_keys[] = $key['Column_name'];
}
}
/**
* Gets fields properties
*/
$GLOBALS['dbi']->selectDb($db);
/**
* Displays the table structure
*/
$text_output .= "|------\n"
. '|' . __('Column')
. '|' . __('Type')
. '|' . __('Null')
. '|' . __('Default')
. "\n|------\n";
$columns = $GLOBALS['dbi']->getColumns($db, $view);
foreach ($columns as $column) {
$col_as = $column['Field'];
if (!empty($aliases[$db]['tables'][$view]['columns'][$col_as])) {
$col_as = $aliases[$db]['tables'][$view]['columns'][$col_as];
}
$text_output .= $this->formatOneColumnDefinition(
$column,
$unique_keys,
$col_as
);
$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
* @param array $aliases Aliases of db/table/columns
*
* @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,
$aliases = array()
) {
global $cfgRelation;
$text_output = '';
/**
* Get the unique keys in the table
*/
$unique_keys = array();
$keys = $GLOBALS['dbi']->getTableIndexes($db, $table);
foreach ($keys as $key) {
if ($key['Non_unique'] == 0) {
$unique_keys[] = $key['Column_name'];
}
}
/**
* Gets fields properties
*/
$GLOBALS['dbi']->selectDb($db);
// Check if we can use Relations
list($res_rel, $have_rel) = PMA_getRelationsAndStatus(
$do_relation && !empty($cfgRelation['relation']),
$db,
$table
);
/**
* Displays the table structure
*/
$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 = $GLOBALS['dbi']->getColumns($db, $table);
foreach ($columns as $column) {
$col_as = $column['Field'];
if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
$col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
}
$text_output .= $this->formatOneColumnDefinition(
$column,
$unique_keys,
$col_as
);
$field_name = $column['Field'];
if ($do_relation && $have_rel) {
$text_output .= '|' . htmlspecialchars(
$this->getRelationString(
$res_rel,
$field_name,
$db,
$aliases
)
);
}
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
*/
public function getTriggers($db, $table)
{
$dump = "|------\n";
$dump .= '|' . __('Name');
$dump .= '|' . __('Time');
$dump .= '|' . __('Event');
$dump .= '|' . __('Definition');
$dump .= "\n|------\n";
$triggers = $GLOBALS['dbi']->getTriggers($db, $table);
foreach ($triggers as $trigger) {
$dump .= '|' . $trigger['name'];
$dump .= '|' . $trigger['action_timing'];
$dump .= '|' . $trigger['event_manipulation'];
$dump .= '|' .
str_replace(
'|',
'&#124;',
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
* @param array $aliases Aliases of db/table/columns
*
* @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,
$aliases = array()
) {
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
$dump = '';
switch ($export_mode) {
case 'create_table':
$dump .= '== ' . __('Table structure for table') . ' '
. $table_alias . "\n\n";
$dump .= $this->getTableDef(
$db,
$table,
$crlf,
$error_url,
$do_relation,
$do_comments,
$do_mime,
$dates,
true,
false,
$aliases
);
break;
case 'triggers':
$dump = '';
$triggers = $GLOBALS['dbi']->getTriggers($db, $table);
if ($triggers) {
$dump .= '== ' . __('Triggers') . ' ' . $table_alias . "\n\n";
$dump .= $this->getTriggers($db, $table);
}
break;
case 'create_view':
$dump .= '== ' . __('Structure for view') . ' ' . $table_alias . "\n\n";
$dump .= $this->getTableDef(
$db,
$table,
$crlf,
$error_url,
$do_relation,
$do_comments,
$do_mime,
$dates,
true,
true,
$aliases
);
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, $aliases);
} // 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
* @param string $col_alias Column Alias
*
* @return string Formatted column definition
*/
public function formatOneColumnDefinition(
$column,
$unique_keys,
$col_alias = ''
) {
if (empty($col_alias)) {
$col_alias = $column['Field'];
}
$extracted_columnspec
= Util::extractColumnSpec($column['Type']);
$type = $extracted_columnspec['print_type'];
if (empty($type)) {
$type = '&nbsp;';
}
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($col_alias) . $fmt_post;
$definition .= '|' . htmlspecialchars($type);
$definition .= '|'
. (($column['Null'] == '' || $column['Null'] == 'NO')
? __('No') : __('Yes'));
$definition .= '|'
. htmlspecialchars(
isset($column['Default']) ? $column['Default'] : ''
);
return $definition;
}
}

View File

@ -0,0 +1,577 @@
<?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
*/
namespace PMA\libraries\plugins\export;
use PMA\libraries\properties\options\items\BoolPropertyItem;
use PMA\libraries\properties\plugins\ExportPluginProperties;
use PMA\libraries\properties\options\items\HiddenPropertyItem;
use PMA\libraries\properties\options\groups\OptionsPropertyMainGroup;
use PMA\libraries\properties\options\groups\OptionsPropertyRootGroup;
use PMA\libraries\DatabaseInterface;
use PMA\libraries\plugins\ExportPlugin;
use PMA\libraries\Util;
if (!mb_strlen($GLOBALS['db'])) { /* Can't do server export */
$GLOBALS['skip_import'] = true;
return;
}
/**
* 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()
{
// 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(
"Format Specific Options"
);
// general options main group
$generalOptions = new OptionsPropertyMainGroup("general_opts");
// create primary items and add them to the group
$leaf = new HiddenPropertyItem("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", __('Object creation options (all are recommended)')
);
// create primary items and add them to the group
$leaf = new BoolPropertyItem(
"export_events",
__('Events')
);
$structure->addProperty($leaf);
$leaf = new BoolPropertyItem(
"export_functions",
__('Functions')
);
$structure->addProperty($leaf);
$leaf = new BoolPropertyItem(
"export_procedures",
__('Procedures')
);
$structure->addProperty($leaf);
$leaf = new BoolPropertyItem(
"export_tables",
__('Tables')
);
$structure->addProperty($leaf);
$leaf = new BoolPropertyItem(
"export_triggers",
__('Triggers')
);
$structure->addProperty($leaf);
$leaf = new BoolPropertyItem(
"export_views",
__('Views')
);
$structure->addProperty($leaf);
$exportSpecificOptions->addProperty($structure);
// data main group
$data = new OptionsPropertyMainGroup(
"data", __('Data dump options')
);
// create primary items and add them to the group
$leaf = new BoolPropertyItem(
"export_contents",
__('Export contents')
);
$data->addProperty($leaf);
$exportSpecificOptions->addProperty($data);
// set the options for the export plugin property item
$exportPluginProperties->setOptions($exportSpecificOptions);
$this->properties = $exportPluginProperties;
}
/**
* Generates output for SQL defintions of routines
*
* @param string $db Database name
* @param string $type Item type to be used in XML output
* @param string $dbitype Item type used in DBI qieries
*
* @return string XML with definitions
*/
private function _exportRoutines($db, $type, $dbitype)
{
// Export routines
$routines = $GLOBALS['dbi']->getProceduresOrFunctions(
$db,
$dbitype
);
return $this->_exportDefinitions($db, $type, $dbitype, $routines);
}
/**
* Generates output for SQL defintions
*
* @param string $db Database name
* @param string $type Item type to be used in XML output
* @param string $dbitype Item type used in DBI qieries
* @param array $names Names of items to export
*
* @return string XML with definitions
*/
private function _exportDefinitions($db, $type, $dbitype, $names)
{
global $crlf;
$head = '';
if ($names) {
foreach ($names as $name) {
$head .= ' <pma:' . $type . ' name="'
. htmlspecialchars($name) . '">' . $crlf;
// Do some formatting
$sql = $GLOBALS['dbi']->getDefinition($db, $dbitype, $name);
$sql = htmlspecialchars(rtrim($sql));
$sql = str_replace("\n", "\n ", $sql);
$head .= " " . $sql . $crlf;
$head .= ' </pma:' . $type . '>' . $crlf;
}
}
return $head;
}
/**
* 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'];
} else {
$charset = 'utf-8';
}
$head = '<?xml version="1.0" encoding="' . $charset . '"?>' . $crlf
. '<!--' . $crlf
. '- phpMyAdmin XML Dump' . $crlf
. '- version ' . PMA_VERSION . $crlf
. '- https://www.phpmyadmin.net' . $crlf
. '-' . $crlf
. '- ' . __('Host:') . ' ' . htmlspecialchars($cfg['Server']['host']);
if (!empty($cfg['Server']['port'])) {
$head .= ':' . $cfg['Server']['port'];
}
$head .= $crlf
. '- ' . __('Generation Time:') . ' '
. 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="https://www.phpmyadmin.net/some_doc_url/"'
: '')
. '>' . $crlf;
if ($export_struct) {
$result = $GLOBALS['dbi']->fetchResult(
'SELECT `DEFAULT_CHARACTER_SET_NAME`, `DEFAULT_COLLATION_NAME`'
. ' FROM `information_schema`.`SCHEMATA` WHERE `SCHEMA_NAME`'
. ' = \'' . $GLOBALS['dbi']->escapeString($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="' . htmlspecialchars($db_collation) . '" charset="' . htmlspecialchars($db_charset)
. '">' . $crlf;
if (count($tables) == 0) {
$tables[] = $table;
}
foreach ($tables as $table) {
// Export tables and views
$result = $GLOBALS['dbi']->fetchResult(
'SHOW CREATE TABLE ' . Util::backquote($db) . '.'
. Util::backquote($table),
0
);
$tbl = $result[$table][1];
$is_view = $GLOBALS['dbi']->getTable($db, $table)
->isView();
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="' . htmlspecialchars($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 = $GLOBALS['dbi']->getTriggers($db, $table);
if ($triggers) {
foreach ($triggers as $trigger) {
$code = $trigger['create'];
$head .= ' <pma:trigger name="'
. htmlspecialchars($trigger['name']) . '">' . $crlf;
// Do some formatting
$code = mb_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']
) {
$head .= $this->_exportRoutines($db, 'function', 'FUNCTION');
}
if (isset($GLOBALS['xml_export_procedures'])
&& $GLOBALS['xml_export_procedures']
) {
$head .= $this->_exportRoutines($db, 'procedure', 'PROCEDURE');
}
if (isset($GLOBALS['xml_export_events'])
&& $GLOBALS['xml_export_events']
) {
// Export events
$events = $GLOBALS['dbi']->fetchResult(
"SELECT EVENT_NAME FROM information_schema.EVENTS "
. "WHERE EVENT_SCHEMA='" . $GLOBALS['dbi']->escapeString($db)
. "'"
);
$head .= $this->_exportDefinitions(
$db, 'event', 'EVENT', $events
);
}
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
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBHeader($db, $db_alias = '')
{
global $crlf;
if (empty($db_alias)) {
$db_alias = $db;
}
if (isset($GLOBALS['xml_export_contents'])
&& $GLOBALS['xml_export_contents']
) {
$head = ' <!--' . $crlf
. ' - ' . __('Database:') . ' ' . '\''
. htmlspecialchars($db_alias) . '\'' . $crlf
. ' -->' . $crlf . ' <database name="'
. htmlspecialchars($db_alias) . '">' . $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
* @param string $export_type 'server', 'database', 'table'
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBCreate($db, $export_type, $db_alias = '')
{
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
* @param array $aliases Aliases of db/table/columns
*
* @return bool Whether it succeeded
*/
public function exportData(
$db,
$table,
$crlf,
$error_url,
$sql_query,
$aliases = array()
) {
// Do not export data for merge tables
if ($GLOBALS['dbi']->getTable($db, $table)->isMerge()) {
return true;
}
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
if (isset($GLOBALS['xml_export_contents'])
&& $GLOBALS['xml_export_contents']
) {
$result = $GLOBALS['dbi']->query(
$sql_query,
null,
DatabaseInterface::QUERY_UNBUFFERED
);
$columns_cnt = $GLOBALS['dbi']->numFields($result);
$columns = array();
for ($i = 0; $i < $columns_cnt; $i++) {
$columns[$i] = stripslashes($GLOBALS['dbi']->fieldName($result, $i));
}
unset($i);
$buffer = ' <!-- ' . __('Table') . ' '
. htmlspecialchars($table_alias) . ' -->' . $crlf;
if (!PMA_exportOutputHandler($buffer)) {
return false;
}
while ($record = $GLOBALS['dbi']->fetchRow($result)) {
$buffer = ' <table name="'
. htmlspecialchars($table_alias) . '">' . $crlf;
for ($i = 0; $i < $columns_cnt; $i++) {
$col_as = $columns[$i];
if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])
) {
$col_as
= $aliases[$db]['tables'][$table]['columns'][$col_as];
}
// 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($col_as) . '">'
. htmlspecialchars((string)$record[$i])
. '</column>' . $crlf;
}
$buffer .= ' </table>' . $crlf;
if (!PMA_exportOutputHandler($buffer)) {
return false;
}
}
$GLOBALS['dbi']->freeResult($result);
}
return true;
}
/* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
/**
* Gets the table name
*
* @return string
*/
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;
}
}

View File

@ -0,0 +1,217 @@
<?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
*/
namespace PMA\libraries\plugins\export;
use PMA\libraries\plugins\ExportPlugin;
use PMA\libraries\properties\plugins\ExportPluginProperties;
use PMA\libraries\properties\options\items\HiddenPropertyItem;
use PMA\libraries\properties\options\groups\OptionsPropertyMainGroup;
use PMA\libraries\properties\options\groups\OptionsPropertyRootGroup;
use PMA;
/**
* 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()
{
$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(
"Format Specific Options"
);
// general options main group
$generalOptions = new OptionsPropertyMainGroup("general_opts");
// create primary items and add them to the group
$leaf = new HiddenPropertyItem("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;
}
/**
* 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
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBHeader($db, $db_alias = '')
{
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
* @param string $export_type 'server', 'database', 'table'
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBCreate($db, $export_type, $db_alias = '')
{
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
* @param array $aliases Aliases of db/table/columns
*
* @return bool Whether it succeeded
*/
public function exportData(
$db,
$table,
$crlf,
$error_url,
$sql_query,
$aliases = array()
) {
$db_alias = $db;
$table_alias = $table;
$this->initAlias($aliases, $db_alias, $table_alias);
$result = $GLOBALS['dbi']->query(
$sql_query,
null,
PMA\libraries\DatabaseInterface::QUERY_UNBUFFERED
);
$columns_cnt = $GLOBALS['dbi']->numFields($result);
$columns = array();
for ($i = 0; $i < $columns_cnt; $i++) {
$col_as = $GLOBALS['dbi']->fieldName($result, $i);
if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
$col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
}
$columns[$i] = stripslashes($col_as);
}
$buffer = '';
$record_cnt = 0;
while ($record = $GLOBALS['dbi']->fetchRow($result)) {
$record_cnt++;
// Output table name as comment if this is the first record of the table
if ($record_cnt == 1) {
$buffer = '# ' . $db_alias . '.' . $table_alias . $crlf;
$buffer .= '-' . $crlf;
} else {
$buffer = '-' . $crlf;
}
for ($i = 0; $i < $columns_cnt; $i++) {
if (!isset($record[$i])) {
continue;
}
if (is_null($record[$i])) {
$buffer .= ' ' . $columns[$i] . ': null' . $crlf;
continue;
}
if (is_numeric($record[$i])) {
$buffer .= ' ' . $columns[$i] . ': ' . $record[$i] . $crlf;
continue;
}
$record[$i] = str_replace(
array('\\', '"', "\n", "\r"),
array('\\\\', '\"', '\n', '\r'),
$record[$i]
);
$buffer .= ' ' . $columns[$i] . ': "' . $record[$i] . '"' . $crlf;
}
if (!PMA_exportOutputHandler($buffer)) {
return false;
}
}
$GLOBALS['dbi']->freeResult($result);
return true;
} // end getTableYAML
}

View File

@ -0,0 +1,811 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* PMA\libraries\plugins\export\TableProperty class
*
* @package PhpMyAdmin-Export
* @subpackage PDF
*/
namespace PMA\libraries\plugins\export;
use PMA\libraries\DatabaseInterface;
use PMA\libraries\PDF;
use PMA\libraries\Util;
use TCPDF_STATIC;
/**
* Adapted from a LGPL script by Philip Clarke
*
* @package PhpMyAdmin-Export
* @subpackage PDF
*/
class PMA_ExportPdf extends PDF
{
var $tablewidths;
var $headerset;
/**
* Add page if needed.
*
* @param float|int $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.
*/
public function checkPageBreak($h = 0, $y = '', $addpage = true)
{
if (TCPDF_STATIC::empty_string($y)) {
$y = $this->y;
}
$current_page = $this->page;
if ((($y + $h) > $this->PageBreakTrigger)
&& (!$this->InFooter)
&& ($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
*/
public 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(
PDF::PMA_PDF_FONT,
'',
($this->titleFontSize
? $this->titleFontSize
: $this->FontSizePt)
);
$this->Cell(0, $this->FontSizePt, $this->titleText, 0, 1, 'C');
$this->SetFont(PDF::PMA_PDF_FONT, '', $this->cellFontSize);
$this->SetY(($this->tMargin) - ($this->FontSizePt / $this->k) * 2.5);
$this->Cell(
0,
$this->FontSizePt,
__('Database:') . ' ' . $this->dbAlias . ', '
. __('Table:') . ' ' . $this->tableAlias . ', '
. __('Purpose:') . ' ' . $this->purpose,
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);
}
/**
* Generate table
*
* @param int $lineheight Height of line
*
* @return void
*/
public 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 = $GLOBALS['dbi']->fetchRow($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
*/
public 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
*/
public function setTopMargin($topMargin)
{
$this->tMargin = $topMargin;
}
/**
* Prints triggers
*
* @param string $db database name
* @param string $table table name
*
* @return void
*/
public function getTriggers($db, $table)
{
$i = 0;
$triggers = $GLOBALS['dbi']->getTriggers($db, $table);
foreach ($triggers as $trigger) {
$i++;
break;
}
if ($i == 0) {
return; //prevents printing blank trigger list for any table
}
unset($this->tablewidths);
unset($this->colTitles);
unset($this->titleWidth);
unset($this->colFits);
unset($this->display_column);
unset($this->colAlign);
/**
* Making table heading
* Keeping column width constant
*/
$this->colTitles[0] = __('Name');
$this->tablewidths[0] = 90;
$this->colTitles[1] = __('Time');
$this->tablewidths[1] = 80;
$this->colTitles[2] = __('Event');
$this->tablewidths[2] = 40;
$this->colTitles[3] = __('Definition');
$this->tablewidths[3] = 240;
for ($columns_cnt = 0; $columns_cnt < 4; $columns_cnt++) {
$this->colAlign[$columns_cnt] = 'L';
$this->display_column[$columns_cnt] = true;
}
// Starting to fill table with required info
$this->setY($this->tMargin);
$this->AddPage();
$this->SetFont(PDF::PMA_PDF_FONT, '', 9);
$l = $this->lMargin;
$startheight = $h = $this->dataY;
$startpage = $currpage = $this->page;
// calculate the whole width
$fullwidth = 0;
foreach ($this->tablewidths as $width) {
$fullwidth += $width;
}
$row = 0;
$tmpheight = array();
$maxpage = $this->page;
$data = array();
$triggers = $GLOBALS['dbi']->getTriggers($db, $table);
foreach ($triggers as $trigger) {
$data[] = $trigger['name'];
$data[] = $trigger['action_timing'];
$data[] = $trigger['event_manipulation'];
$data[] = $trigger['definition'];
$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],
$this->FontSizePt,
$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;
}
}
// 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++;
}
// 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;
}
/**
* Print $table's CREATE definition
*
* @param string $db the database name
* @param string $table the table name
* @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 $view whether we're handling a view
* @param array $aliases aliases of db/table/columns
*
* @return void
*/
public function getTableDef(
$db,
$table,
$do_relation,
$do_comments,
$do_mime,
$view = false,
$aliases = array()
) {
// set $cfgRelation here, because there is a chance that it's modified
// since the class initialization
global $cfgRelation;
unset($this->tablewidths);
unset($this->colTitles);
unset($this->titleWidth);
unset($this->colFits);
unset($this->display_column);
unset($this->colAlign);
/**
* Gets fields properties
*/
$GLOBALS['dbi']->selectDb($db);
/**
* All these three checks do_relation, do_comment and do_mime is
* not required. As presently all are set true by default.
* But when, methods to take user input will be developed,
* it will be of use
*/
// Check if we can use Relations
if ($do_relation) {
// Find which tables are related with the current one and write it in
// an array
$res_rel = PMA_getForeigners($db, $table);
$have_rel = !empty($res_rel);
} else {
$have_rel = false;
} // end if
//column count and table heading
$this->colTitles[0] = __('Column');
$this->tablewidths[0] = 90;
$this->colTitles[1] = __('Type');
$this->tablewidths[1] = 80;
$this->colTitles[2] = __('Null');
$this->tablewidths[2] = 40;
$this->colTitles[3] = __('Default');
$this->tablewidths[3] = 120;
for ($columns_cnt = 0; $columns_cnt < 4; $columns_cnt++) {
$this->colAlign[$columns_cnt] = 'L';
$this->display_column[$columns_cnt] = true;
}
if ($do_relation && $have_rel) {
$this->colTitles[$columns_cnt] = __('Links to');
$this->display_column[$columns_cnt] = true;
$this->colAlign[$columns_cnt] = 'L';
$this->tablewidths[$columns_cnt] = 120;
$columns_cnt++;
}
if ($do_comments /*&& $cfgRelation['commwork']*/) {
$this->colTitles[$columns_cnt] = __('Comments');
$this->display_column[$columns_cnt] = true;
$this->colAlign[$columns_cnt] = 'L';
$this->tablewidths[$columns_cnt] = 120;
$columns_cnt++;
}
if ($do_mime && $cfgRelation['mimework']) {
$this->colTitles[$columns_cnt] = __('MIME');
$this->display_column[$columns_cnt] = true;
$this->colAlign[$columns_cnt] = 'L';
$this->tablewidths[$columns_cnt] = 120;
$columns_cnt++;
}
// Starting to fill table with required info
$this->setY($this->tMargin);
$this->AddPage();
$this->SetFont(PDF::PMA_PDF_FONT, '', 9);
// Now let's start to write the table structure
if ($do_comments) {
$comments = PMA_getComments($db, $table);
}
if ($do_mime && $cfgRelation['mimework']) {
$mime_map = PMA_getMIME($db, $table, true);
}
$columns = $GLOBALS['dbi']->getColumns($db, $table);
/**
* Get the unique keys in the table.
* Presently, this information is not used. We will have to find out
* way of displaying it.
*/
$unique_keys = array();
$keys = $GLOBALS['dbi']->getTableIndexes($db, $table);
foreach ($keys as $key) {
if ($key['Non_unique'] == 0) {
$unique_keys[] = $key['Column_name'];
}
}
// 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;
}
$row = 0;
$tmpheight = array();
$maxpage = $this->page;
$data = array();
// fun begin
foreach ($columns as $column) {
$extracted_columnspec
= Util::extractColumnSpec($column['Type']);
$type = $extracted_columnspec['print_type'];
if (empty($type)) {
$type = ' ';
}
if (!isset($column['Default'])) {
if ($column['Null'] != 'NO') {
$column['Default'] = 'NULL';
}
}
$data [] = $column['Field'];
$data [] = $type;
$data [] = ($column['Null'] == '' || $column['Null'] == 'NO')
? 'No'
: 'Yes';
$data [] = isset($column['Default']) ? $column['Default'] : '';
$field_name = $column['Field'];
if ($do_relation && $have_rel) {
$data [] = isset($res_rel[$field_name])
? $res_rel[$field_name]['foreign_table']
. ' (' . $res_rel[$field_name]['foreign_field']
. ')'
: '';
}
if ($do_comments) {
$data [] = isset($comments[$field_name])
? $comments[$field_name]
: '';
}
if ($do_mime) {
$data [] = isset($mime_map[$field_name])
? $mime_map[$field_name]['mimetype']
: '';
}
$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],
$this->FontSizePt,
$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;
}
}
// 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++;
}
// 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;
}
/**
* MySQL report
*
* @param string $query Query to execute
*
* @return void
*/
public 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 = $GLOBALS['dbi']->query(
$query,
null,
DatabaseInterface::QUERY_UNBUFFERED
);
$this->numFields = $GLOBALS['dbi']->numFields($this->results);
$this->fields = $GLOBALS['dbi']->getFieldsMeta($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();
$titleWidth = array();
for ($i = 0; $i < $this->numFields; $i++) {
$col_as = $this->fields[$i]->name;
$db = $this->currentDb;
$table = $this->currentTable;
if (!empty($this->aliases[$db]['tables'][$table]['columns'][$col_as])) {
$col_as = $this->aliases[$db]['tables'][$table]['columns'][$col_as];
}
$stringWidth = $this->getstringwidth($col_as) + 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] = $col_as;
$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 = $GLOBALS['dbi']->fetchRow($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);
$GLOBALS['dbi']->freeResult($this->results);
// Pass 2
$this->results = $GLOBALS['dbi']->query(
$query,
null,
DatabaseInterface::QUERY_UNBUFFERED
);
$this->setY($this->tMargin);
$this->AddPage();
$this->SetFont(PDF::PMA_PDF_FONT, '', 9);
$this->morepagestable($this->FontSizePt);
$GLOBALS['dbi']->freeResult($this->results);
} // end of mysqlReport function
} // end of PMA_Export_PDF class

View File

@ -0,0 +1,257 @@
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;
}
/**
* Handles the export for the [Name] format
*
* @package PhpMyAdmin-Export
*/
class Export[Name] extends PMA\libraries\plugins\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()
{
$exportPluginProperties = new PMA\libraries\properties\plugins\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 PMA\libraries\properties\options\groups\OptionsPropertyRootGroup(
"Format Specific Options"
);
// general options main group
$generalOptions = new PMA\libraries\properties\options\groups\OptionsPropertyMainGroup(
"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 PMA\libraries\properties\options\items\RadioPropertyItem(
"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;
}
/**
* 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
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBHeader ($db, $db_alias = '')
{
// 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
* @param string $db_alias Aliases of db
*
* @return bool Whether it succeeded
*/
public function exportDBCreate($db, $db_alias = '')
{
// 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
* @param array $aliases Aliases of db/table/columns
*
* @return bool Whether it succeeded
*/
public function exportData(
$db, $table, $crlf, $error_url, $sql_query, $aliases = array()
) {
// implementation;
return true;
}
// optional - implement other methods defined in PMA\libraries\plugins\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 PMA\libraries\plugins\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;
}
}
?>

View File

@ -0,0 +1,283 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Holds the PMA\libraries\plugins\export\TableProperty class
*
* @package PhpMyAdmin-Export
* @subpackage CodeGen
*/
namespace PMA\libraries\plugins\export;
/**
* PMA\libraries\plugins\export\TableProperty class
*
* @package PhpMyAdmin-Export
* @subpackage CodeGen
*/
class TableProperty
{
/**
* Name
*
* @var string
*/
public $name;
/**
* Type
*
* @var string
*/
public $type;
/**
* Whether 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
*/
public 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
*/
public function getPureType()
{
$pos = mb_strpos($this->type, "(");
if ($pos > 0) {
return mb_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
*/
public 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
*/
public function isUnique()
{
return $this->key == "PRI" || $this->key == "UNI" ? "true" : "false";
}
/**
* Gets the .NET primitive type
*
* @return string type
*/
public function getDotNetPrimitiveType()
{
if (mb_strpos($this->type, "int") === 0) {
return "int";
}
if (mb_strpos($this->type, "longtext") === 0) {
return "string";
}
if (mb_strpos($this->type, "long") === 0) {
return "long";
}
if (mb_strpos($this->type, "char") === 0) {
return "string";
}
if (mb_strpos($this->type, "varchar") === 0) {
return "string";
}
if (mb_strpos($this->type, "text") === 0) {
return "string";
}
if (mb_strpos($this->type, "tinyint") === 0) {
return "bool";
}
if (mb_strpos($this->type, "datetime") === 0) {
return "DateTime";
}
return "unknown";
}
/**
* Gets the .NET object type
*
* @return string type
*/
public function getDotNetObjectType()
{
if (mb_strpos($this->type, "int") === 0) {
return "Int32";
}
if (mb_strpos($this->type, "longtext") === 0) {
return "String";
}
if (mb_strpos($this->type, "long") === 0) {
return "Long";
}
if (mb_strpos($this->type, "char") === 0) {
return "String";
}
if (mb_strpos($this->type, "varchar") === 0) {
return "String";
}
if (mb_strpos($this->type, "text") === 0) {
return "String";
}
if (mb_strpos($this->type, "tinyint") === 0) {
return "Boolean";
}
if (mb_strpos($this->type, "datetime") === 0) {
return "DateTime";
}
return "Unknown";
}
/**
* Gets the index name
*
* @return string containing the name of the index
*/
public function getIndexName()
{
if (mb_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
*/
public function isPK()
{
return $this->key == "PRI";
}
/**
* Formats a string for C#
*
* @param string $text string to be formatted
*
* @return string formatted text
*/
public 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
*/
public 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
*/
public 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;
}
}