rfe #812 store export definitions for reuse

Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
This commit is contained in:
Madhura Jayaratne 2015-07-01 01:57:38 +05:30
parent 89b75b3a4e
commit 545db4a443
19 changed files with 487 additions and 14 deletions

View File

@ -63,6 +63,7 @@ $cfg['Servers'][$i]['AllowNoPassword'] = false;
// $cfg['Servers'][$i]['savedsearches'] = 'pma__savedsearches';
// $cfg['Servers'][$i]['central_columns'] = 'pma__central_columns';
// $cfg['Servers'][$i]['designer_settings'] = 'pma__designer_settings';
// $cfg['Servers'][$i]['exporttemplates'] = 'pma__exporttemplates';
/* Contrib / Swekey authentication */
// $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey-pma.conf';

View File

@ -812,6 +812,20 @@ Server connection settings
* put the table name in :config:option:`$cfg['Servers'][$i]['savedsearches']` (e.g.
``pma__savedsearches``)
.. _exporttemplates:
.. config:option:: $cfg['Servers'][$i]['exporttemplates']
:type: string
:default: ``''``
Since release 4.5.0 you can save and load export templates.
To allow the usage of this functionality:
* set up :config:option:`$cfg['Servers'][$i]['pmadb']` and the phpMyAdmin configuration storage
* put the table name in :config:option:`$cfg['Servers'][$i]['exporttemplates']` (e.g.
``pma__exporttemplates``)
.. _tracking:
.. config:option:: $cfg['Servers'][$i]['tracking']

View File

@ -49,4 +49,5 @@ foreach ($hosts as $host) {
$cfg['Servers'][$i]['savedsearches'] = 'pma__savedsearches';
$cfg['Servers'][$i]['central_columns'] = 'pma__central_columns';
$cfg['Servers'][$i]['designer_settings'] = 'pma__designer_settings';
$cfg['Servers'][$i]['exporttemplates'] = 'pma__exporttemplates';
}

View File

@ -26,6 +26,167 @@ function enable_dump_some_rows_sub_options()
$("input[type='text'][name='limit_from']").prop('disabled', '');
}
/**
* Return template data as a json object
*
* @returns template data
*/
function getTemplateData()
{
var $form = $('form[name="dump"]');
var blacklist = ['token', 'server', 'db', 'table', 'single_table',
'export_type', 'export_method', 'sql_query'];
var obj = {};
var arr = $form.serializeArray();
$.each(arr, function () {
if ($.inArray(this.name, blacklist) < 0) {
if (obj[this.name] !== undefined) {
if (! obj[this.name].push) {
obj[this.name] = [obj[this.name]];
}
obj[this.name].push(this.value || '');
} else {
obj[this.name] = this.value || '';
}
}
});
return obj;
}
/**
* Create a template with selected options
*
* @param name name of the template
*/
function createTemplate(name)
{
var templateData = getTemplateData();
var params = {
ajax_request : true,
token : PMA_commonParams.get('token'),
server : PMA_commonParams.get('server'),
db : PMA_commonParams.get('db'),
table : PMA_commonParams.get('table'),
templateAction : 'create',
templateName : name,
templateData : JSON.stringify(templateData)
};
var $msgbox = PMA_ajaxShowMessage();
$.post('tbl_export.php', params, function (response) {
if (response.success === true) {
$('#templateName').val('');
$('#template').html(response.data);
PMA_ajaxRemoveMessage($msgbox);
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
}
/**
* Loads a template
*
* @param id ID of the template to load
*/
function loadTemplate(id)
{
var params = {
ajax_request : true,
token : PMA_commonParams.get('token'),
server : PMA_commonParams.get('server'),
db : PMA_commonParams.get('db'),
table : PMA_commonParams.get('table'),
templateAction : 'load',
templateId : id,
};
var $msgbox = PMA_ajaxShowMessage();
$.post('tbl_export.php', params, function (response) {
if (response.success === true) {
var $form = $('form[name="dump"]');
var options = $.parseJSON(response.data);
$.each(options, function (key, value) {
var $element = $form.find('[name="' + key + '"]');
if ($element.length) {
if (($element.is('input') && $element.attr('type') == 'checkbox') ||
($element.is('input') && $element.attr('type') == 'radio') ||
($element.is('select') && $element.attr('multiple') == 'multiple')) {
if (! value.push) {
value = [value];
}
}
$element.val(value);
$element.trigger('change');
}
});
PMA_ajaxRemoveMessage($msgbox);
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
}
/**
* Updates an existing template with current options
*
* @param id ID of the template to update
*/
function updateTemplate(id)
{
var templateData = getTemplateData();
var params = {
ajax_request : true,
token : PMA_commonParams.get('token'),
server : PMA_commonParams.get('server'),
db : PMA_commonParams.get('db'),
table : PMA_commonParams.get('table'),
templateAction : 'update',
templateId : id,
templateData : JSON.stringify(templateData)
};
var $msgbox = PMA_ajaxShowMessage();
$.post('tbl_export.php', params, function (response) {
if (response.success === true) {
PMA_ajaxRemoveMessage($msgbox);
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
}
/**
* Delete a template
*
* @param id ID of the template to delete
*/
function deleteTemplate(id)
{
var params = {
ajax_request : true,
token : PMA_commonParams.get('token'),
server : PMA_commonParams.get('server'),
db : PMA_commonParams.get('db'),
table : PMA_commonParams.get('table'),
templateAction : 'delete',
templateId : id,
};
var $msgbox = PMA_ajaxShowMessage();
$.post('tbl_export.php', params, function (response) {
if (response.success === true) {
$('#template option[value="' + id + '"]').remove();
PMA_ajaxRemoveMessage($msgbox);
} else {
PMA_ajaxShowMessage(response.error, false);
}
});
}
/**
* Unbind all event handlers before tearing down a page
*/
@ -45,9 +206,53 @@ AJAX.registerTeardown('export.js', function () {
$('input[name="table_data[]"]').off('change');
$('#table_structure_all').off('change');
$('#table_data_all').off('change');
$('input[name="createTemplate"]').off('click');
$('input[name="loadTemplate"]').off('click');
$('input[name="updateTemplate"]').off('click');
$('input[name="deleteTemplate"]').off('click');
});
AJAX.registerOnload('export.js', function () {
/**
* Export template handling code
*/
// create a new template
$('input[name="createTemplate"]').on('click', function (e) {
e.preventDefault();
var name = $('input[name="templateName"]').val();
if (name.length) {
createTemplate(name);
}
});
// load an existing template
$('input[name="loadTemplate"]').on('click', function (e) {
e.preventDefault();
var id = $('select[name="template"]').val();
if (id.length) {
loadTemplate(id);
}
});
// udpate an existing template with new criteria
$('input[name="updateTemplate"]').on('click', function (e) {
e.preventDefault();
var id = $('select[name="template"]').val();
if (id.length) {
updateTemplate(id);
}
});
// delete an existing template
$('input[name="deleteTemplate"]').on('click', function (e) {
e.preventDefault();
var id = $('select[name="template"]').val();
if (id.length) {
deleteTemplate(id);
}
});
/**
* Toggles the hiding and showing of each plugin's options
* according to the currently selected plugin from the dropdown list

View File

@ -349,6 +349,11 @@ class PMA_DisplayResults
'config_data' => $json_highlighting_data
);
}
if (! empty($cfgRelation['exporttemplates'])) {
$relDb[$cfgRelation['exporttemplates']] = array(
'template_data' => $json_highlighting_data
);
}
}
}

View File

@ -490,6 +490,15 @@ $cfg['Servers'][$i]['central_columns'] = '';
*/
$cfg['Servers'][$i]['designer_settings'] = '';
/**
* table to store export templates
* - leave blank to disable saved searches feature
* SUGGESTED: 'pma__exporttemplates'
*
* @global string $cfg['Servers'][$i]['exporttemplates']
*/
$cfg['Servers'][$i]['exporttemplates'] = '';
/**
* Maximum number of records saved in $cfg['Servers'][$i]['table_uiprefs'] table.
*

View File

@ -652,6 +652,11 @@ $strConfigServers_savedsearches_desc = __(
'Leave blank for no QBE saved searches support, suggested: '
. '[kbd]pma__savedsearches[/kbd].'
);
$strConfigServers_savedsearches_name = __('Export templates table');
$strConfigServers_savedsearches_desc = __(
'Leave blank for no export template support, suggested: '
. '[kbd]pma__exporttemplates[/kbd].'
);
$strConfigServers_central_columns_name = __('Central columns table');
$strConfigServers_central_columns_desc = __(
'Leave blank for no central columns support, suggested: '

View File

@ -84,6 +84,7 @@ $forms['Servers']['Server_pmadb'] = array('Servers' => array(1 => array(
'savedsearches' => 'pma__savedsearches',
'central_columns' => 'pma__central_columns',
'designer_settings' => 'pma__designer_settings',
'exporttemplates' => 'pma__exporttemplates',
'MaxTableUiprefs' => 100)));
$forms['Servers']['Server_tracking'] = array('Servers' => array(1 => array(
'tracking_version_auto_create',

View File

@ -39,7 +39,10 @@ if (empty($export_list)) {
exit;
}
$html = '<form method="post" action="export.php" '
$html = PMA_getHtmlForExportOptionHeader($export_type, $db, $table);
$html .= PMA_getHtmlForExportTemplateLoading($db, $table);
$html .= '<form method="post" action="export.php" '
. ' name="dump" class="disableAjax">';
//output Hidden Inputs

View File

@ -184,6 +184,92 @@ function PMA_getHtmlForExportOptionHeader($export_type, $db, $table)
return $html;
}
/**
* Returns Html for saving and loading export templates
*
* @param string $db database
* @param string $table table
*/
function PMA_getHtmlForExportTemplateLoading($db, $table)
{
$html = '<div class="exportoptions" id="exporttemplates">';
$html .= '<h3>' . __('Export templates:') . '</h3>';
$html .= '<div class="floatleft">';
$html .= '<form method="post" action="tbl_export.php" id="newTemplateForm"'
. ' class="ajax">';
$html .= '<h4>' . __('New template:') . '</h4>';
$html .= '<input type="text" name="templateName" id="templateName" '
. 'required="required" placeholder="' . __('Template name') . '" />';
$html .= '<input type="submit" name="createTemplate" id="createTemplate" '
. 'value="' . __('Create') . '" />';
$html .= '</form>';
$html .= '</div>';
$html .= '<div class="floatleft" style="margin-left: 50px;">';
$html .= '<form method="post" action="tbl_export.php"'
. ' id="existingTemplatesForm" class="ajax">';
$html .= '<h4>' . __('Existing templates:') . '</h4>';
$html .= '<label for="template">' . __('Template:') . '</label>';
$html .= '<select name="template" id="template">';
$html .= PMA_getOptionsForExportTemplates($db, $table);
$html .= '</select>';
$html .= '<input type="submit" name="loadTemplate" '
. 'id="loadTemplate" value="' . __('Load') . '" />';
$html .= '<input type="submit" name="updateTemplate" '
. 'id="updateTemplate" value="' . __('Update') . '" />';
$html .= '<input type="submit" name="deleteTemplate" '
. 'id="deleteTemplate" value="' . __('Delete') . '" />';
$html .= '</form>';
$html .= '</div>';
$html .= '<div class="clearfloat"></div>';
$html .= '</div>';
return $html;
}
/**
* Returns HTML for the options in teplate dropdown
*
* @param string $db database
* @param string $table table
*
* @return string HTML for the options in teplate dropdown
*/
function PMA_getOptionsForExportTemplates($db, $table)
{
$ret = '';
// Get the relation settings
$cfgRelation = PMA_getRelationsParam();
$query = "SELECT `id`, `template_name` FROM "
. PMA_Util::backquote($cfgRelation['db']) . '.'
. PMA_Util::backquote($cfgRelation['exporttemplates'])
. " WHERE `username` = "
. "'" . PMA_Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . "'"
. " AND `db_name` "
. (! empty($db)
? "= '" . PMA_Util::sqlAddSlashes($db) . "'"
: "IS NULL")
. " AND `table_name` "
. (! empty($table)
? "= '" . PMA_Util::sqlAddSlashes($table) . "'"
: "IS NULL")
. " ORDER BY `template_name`;";
$result = PMA_queryAsControlUser($query);
if ($result) {
while ($row = $GLOBALS['dbi']->fetchAssoc($result, $GLOBALS['controllink'])) {
$ret .= '<option value="' . htmlspecialchars($row['id']) . '">'
. htmlspecialchars($row['template_name']) . '</option>';
}
}
return $ret;
}
/**
* Prints Html For Export Options Method
*
@ -774,8 +860,7 @@ function PMA_getHtmlForExportOptions(
$num_tables, $export_list, $unlim_num_rows
) {
global $cfg;
$html = PMA_getHtmlForExportOptionHeader($export_type, $db, $table);
$html .= PMA_getHtmlForExportOptionsMethod();
$html = PMA_getHtmlForExportOptionsMethod();
$html .= PMA_getHtmlForExportOptionsFormatDropdown($export_list);
$html .= PMA_getHtmlForExportOptionsSelection($export_type, $multi_values);

View File

@ -1028,6 +1028,7 @@ function PMA_getMetadataTypesToExport()
'pdf_pages',
'savedsearches',
'central_columns',
'exporttemplates',
);
}
?>

View File

@ -1024,6 +1024,7 @@ class ExportSql extends ExportPlugin
'column_info' => 'db_name',
'table_uiprefs' => 'db_name',
'tracking' => 'db_name',
'exporttemplates' => 'db_name',
);
} else {
$types = array(
@ -1033,6 +1034,7 @@ class ExportSql extends ExportPlugin
//'table_coords' => 'db_name',
'savedsearches' => 'db_name',
'central_columns' => 'db_name',
'exporttemplates' => 'db_name',
);
}
@ -1075,6 +1077,9 @@ class ExportSql extends ExportPlugin
} elseif ($type == 'savedsearches') {
$sql_query = "SELECT `username`, `db_name`, `search_name`,"
. " `search_data` FROM";
} elseif ($type == 'exporttemplates') {
$sql_query = "SELECT `username`, `db_name`, `table_name`,"
. " `template_name`, `template_data` FROM";
} else {
$sql_query = "SELECT * FROM ";
}

View File

@ -325,6 +325,17 @@ function PMA_getRelationsParamDiagnostic($cfgRelation)
'designer_settingswork',
$messages
);
$retval .= PMA_getDiagMessageForParameter(
'exporttemplates',
isset($cfgRelation['exporttemplates']),
$messages,
'exporttemplates'
);
$retval .= PMA_getDiagMessageForFeature(
__('Saving export templates'),
'exporttemplateswork',
$messages
);
$retval .= '</table>' . "\n";
if (! $cfgRelation['allworks']) {
@ -452,6 +463,7 @@ function PMA_checkRelationsParam()
$cfgRelation['savedsearcheswork'] = false;
$cfgRelation['central_columnswork'] = false;
$cfgRelation['designer_settingswork'] = false;
$cfgRelation['exporttemplateswork'] = false;
$cfgRelation['user'] = null;
$cfgRelation['db'] = null;
@ -527,6 +539,8 @@ function PMA_checkRelationsParam()
$cfgRelation['central_columns'] = $curr_table[0];
} elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['designer_settings']) {
$cfgRelation['designer_settings'] = $curr_table[0];
} elseif ($curr_table[0] == $GLOBALS['cfg']['Server']['exporttemplates']) {
$cfgRelation['exporttemplates'] = $curr_table[0];
}
} // end while
$GLOBALS['dbi']->freeResult($tab_rs);
@ -597,6 +611,10 @@ function PMA_checkRelationsParam()
$cfgRelation['designer_settingswork'] = true;
}
if (isset($cfgRelation['exporttemplates'])) {
$cfgRelation['exporttemplateswork'] = true;
}
if ($cfgRelation['relwork'] && $cfgRelation['displaywork']
&& $cfgRelation['pdfwork'] && $cfgRelation['commwork']
&& $cfgRelation['mimework'] && $cfgRelation['historywork']
@ -606,6 +624,7 @@ function PMA_checkRelationsParam()
&& $cfgRelation['menuswork'] && $cfgRelation['navwork']
&& $cfgRelation['savedsearcheswork'] && $cfgRelation['favoritework']
&& $cfgRelation['designer_settingswork']
&& $cfgRelation['exporttemplateswork']
) {
$cfgRelation['allworks'] = true;
}
@ -1821,7 +1840,8 @@ function PMA_fixPMATables($db, $create = true)
'pma__navigationhiding' => 'navigationhiding',
'pma__savedsearches' => 'savedsearches',
'pma__central_columns' => 'central_columns',
'pma__designer_settings' => 'designer_settings'
'pma__designer_settings' => 'designer_settings',
'pma__exporttemplates' => 'exporttemplates',
);
$existingTables = $GLOBALS['dbi']->getTables($db, $GLOBALS['controllink']);

View File

@ -124,6 +124,14 @@ function PMA_relationsCleanupTable($db, $table)
. ' AND item_type = \'table\'))';
PMA_queryAsControlUser($remove_query);
}
if ($cfgRelation['exporttemplateswork']) {
$remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db'])
. '.' . PMA_Util::backquote($cfgRelation['exporttemplates'])
. ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\''
. ' AND table_name = \'' . PMA_Util::sqlAddSlashes($table) . '\'';
PMA_queryAsControlUser($remove_query);
}
}
/**
@ -211,6 +219,13 @@ function PMA_relationsCleanupDatabase($db)
. ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\'';
PMA_queryAsControlUser($remove_query);
}
if ($cfgRelation['exporttemplateswork']) {
$remove_query = 'DELETE FROM ' . PMA_Util::backquote($cfgRelation['db'])
. '.' . PMA_Util::backquote($cfgRelation['exporttemplates'])
. ' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\'';
PMA_queryAsControlUser($remove_query);
}
}
/**

View File

@ -335,3 +335,22 @@ CREATE TABLE IF NOT EXISTS `pma__designer_settings` (
)
COMMENT='Settings related to Designer'
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
-- --------------------------------------------------------
--
-- Table structure for table `pma__exporttemplates`
--
CREATE TABLE IF NOT EXISTS `pma__exporttemplates` (
`id` int(5) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(64) COLLATE utf8_bin NOT NULL,
`db_name` varchar(64) COLLATE utf8_bin DEFAULT NULL,
`table_name` varchar(64) COLLATE utf8_bin DEFAULT NULL,
`template_name` varchar(64) COLLATE utf8_bin NOT NULL,
`template_data` text COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `u_user_db_table_template` (`username`,`db_name`,`table_name`,`template_name`)
)
COMMENT='Saved export templates'
DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;

View File

@ -287,3 +287,22 @@ CREATE TABLE IF NOT EXISTS `pma__designer_settings` (
)
COMMENT='Settings related to Designer'
COLLATE utf8_bin;
-- --------------------------------------------------------
--
-- Table structure for table `pma__exporttemplates`
--
CREATE TABLE IF NOT EXISTS `pma__exporttemplates` (
`id` int(5) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(64) COLLATE utf8_bin NOT NULL,
`db_name` varchar(64) COLLATE utf8_bin DEFAULT NULL,
`table_name` varchar(64) COLLATE utf8_bin DEFAULT NULL,
`template_name` varchar(64) COLLATE utf8_bin NOT NULL,
`template_data` text COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `u_user_db_table_template` (`username`,`db_name`,`table_name`,`template_name`)
)
COMMENT='Saved export templates'
COLLATE utf8_bin;

View File

@ -11,6 +11,7 @@
*/
require_once 'libraries/common.inc.php';
require_once 'libraries/config/page_settings.class.php';
require_once 'libraries/display_export.lib.php';
PMA_PageSettings::showGroup('Export');
@ -19,6 +20,79 @@ $header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('export.js');
// Get the relation settings
$cfgRelation = PMA_getRelationsParam();
// handling export template actions
if (isset($_REQUEST['templateAction']) && $cfgRelation['exporttemplateswork']) {
if (isset($_REQUEST['templateId'])) {
$templateId = $_REQUEST['templateId'];
$id = PMA_Util::sqlAddSlashes($templateId);
}
$templateTable = PMA_Util::backquote($cfgRelation['db']) . '.'
. PMA_Util::backquote($cfgRelation['exporttemplates']);
$user = PMA_Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']);
if ('create' == $_REQUEST['templateAction']) {
$query = "INSERT INTO " . $templateTable . "("
. " `username`, `db_name`, `table_name`,"
. " `template_name`, `template_data`"
. ") VALUES ("
. "'" . $user . "', "
. (! empty($GLOBALS['db'])
? "'" . PMA_Util::sqlAddSlashes($GLOBALS['db']) . "'"
: 'NULL'
) . ","
. (! empty($GLOBALS['table'])
? "'" . PMA_Util::sqlAddSlashes($GLOBALS['table']) . "'"
: 'NULL'
) . ","
. "'" . PMA_Util::sqlAddSlashes($_REQUEST['templateName']) . "', "
. "'" . PMA_Util::sqlAddSlashes($_REQUEST['templateData']) . "');";
} elseif ('load' == $_REQUEST['templateAction']) {
$query = "SELECT `template_data` FROM " . $templateTable
. " WHERE `id` = " . $id . " AND `username` = '" . $user . "'";
} elseif ('update' == $_REQUEST['templateAction']) {
$query = "UPDATE " . $templateTable . " SET `template_data` = "
. "'" . PMA_Util::sqlAddSlashes($_REQUEST['templateData']) . "'"
. " WHERE `id` = " . $id . " AND `username` = '" . $user . "'";
} elseif ('delete' == $_REQUEST['templateAction']) {
$query = "DELETE FROM " . $templateTable
. " WHERE `id` = " . $id . " AND `username` = '" . $user . "'";
}
$result = PMA_queryAsControlUser($query, false);
$response = PMA_Response::getInstance();
if (! $result) {
$error = $GLOBALS['dbi']->getError($GLOBALS['controllink']);
$response->isSuccess(false);
$response->addJSON('message', $error);
exit;
}
$response->isSuccess(true);
if ('create' == $_REQUEST['templateAction']) {
$response->addJSON(
'data',
PMA_getOptionsForExportTemplates($GLOBALS['db'], $GLOBALS['table'])
);
} elseif ('load' == $_REQUEST['templateAction']) {
$data = null;
while ($row = $GLOBALS['dbi']->fetchAssoc($result, $GLOBALS['controllink'])) {
$data = $row['template_data'];
}
$response->addJSON('data', $data);
}
$GLOBALS['dbi']->freeResult($result);
exit;
}
/**
* Gets tables information and displays top links
*/

View File

@ -180,16 +180,6 @@ class PMA_DisplayExport_Test extends PHPUnit_Framework_TestCase
$unlim_num_rows_str
);
//validate 1: PMA_getHtmlForExportOptionHeader
$this->assertContains(
'<div class="exportoptions" id="header">',
$html
);
$this->assertContains(
__('Exporting databases from the current server'),
$html
);
//validate 2: PMA_getHtmlForExportOptionsMethod
$this->assertContains(
$cfg['Export']['method'],

View File

@ -55,6 +55,7 @@ class PMA_Relation_Cleanup_Test extends PHPUnit_Framework_TestCase
$GLOBALS['cfg']['Server']['savedsearches'] = 'savedsearches';
$GLOBALS['cfg']['Server']['central_columns'] = 'central_columns';
$GLOBALS['cfg']['Server']['designer_settings'] = 'designer_settings';
$GLOBALS['cfg']['Server']['exporttemplates'] = 'pma__exporttemplates';
$this->redefineRelation();
}