diff --git a/ChangeLog b/ChangeLog index cd57c48228..97cdec7fba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,7 @@ phpMyAdmin - ChangeLog - issue #13193 Improved documentation on user settings - issue #13092 Gracefully handle early fatal errors in AJAX requests - issue #13327 Fixed Incorrect NavigationTreeEnableExpansion default value in the documentation +- issue #13008 Fixed export of database with a lot of tables 4.7.1 (2017-05-25) - issue #13132 Always execute tracking queries as controluser diff --git a/ajax.php b/ajax.php new file mode 100644 index 0000000000..da69d976c7 --- /dev/null +++ b/ajax.php @@ -0,0 +1,34 @@ +addJSON('databases', $GLOBALS['dblist']->databases); + break; + case 'list-tables': + Util::checkParameters(array('db')); + $response->addJSON('tables', $GLOBALS['dbi']->getTables($_REQUEST['db'])); + break; + case 'list-columns': + Util::checkParameters(array('db', 'table')); + $response->addJSON('columns', $GLOBALS['dbi']->getColumnNames($_REQUEST['db'], $_REQUEST['table'])); + break; + + default: + PMA_fatalError(__('Bad type!')); +} diff --git a/js/export.js b/js/export.js index e4d51d41c8..2803800c25 100644 --- a/js/export.js +++ b/js/export.js @@ -225,8 +225,10 @@ AJAX.registerTeardown('export.js', function () { $("input[type='radio'][name='quick_or_custom']").unbind('change'); $("input[type='radio'][name='allrows']").unbind('change'); $('#btn_alias_config').off('click'); - $('#db_alias_select').off('change'); - $('.table_alias_select').off('change'); + $('.alias_remove').off('click'); + $('#db_alias_button').off('click'); + $('#table_alias_button').off('click'); + $('#column_alias_button').off('click'); $('input[name="table_select[]"]').off('change'); $('input[name="table_structure[]"]').off('change'); $('input[name="table_data[]"]').off('change'); @@ -764,23 +766,10 @@ function aliasSelectHandler(event) { function createAliasModal(event) { event.preventDefault(); var dlgButtons = {}; - dlgButtons[PMA_messages.strResetAll] = function() { - $(this).find('input[type="text"]').val(''); - }; - dlgButtons[PMA_messages.strReset] = function() { - $(this).find('input[type="text"]:visible').val(''); - }; dlgButtons[PMA_messages.strSaveAndClose] = function() { $(this).dialog("close"); - // do not fillup form submission with empty values - $.each($(this).find('input[type="text"]'), function (i, e) { - if ($(e).val().trim().length == 0) { - $(e).prop('disabled', true); - } - }); $('#alias_modal').parent().appendTo($('form[name="dump"]')); }; - $('#alias_modal').find('input[type="text"]').prop('disabled', false); $('#alias_modal').dialog({ width: Math.min($(window).width() - 100, 700), maxHeight: $(window).height(), @@ -789,24 +778,79 @@ function createAliasModal(event) { buttons: dlgButtons, create: function() { $(this).css('maxHeight', $(window).height() - 150); - $('.alias-dialog .ui-dialog-titlebar-close').remove(); + var db = PMA_commonParams.get('db'); + if (db) { + var option = $(''); + option.text(db); + option.attr('value', db); + $('#db_alias_select').append(option).val(db).change(); + } else { + var params = { + ajax_request : true, + token : PMA_commonParams.get('token'), + server : PMA_commonParams.get('server'), + type: 'list-databases' + }; + $.post('ajax.php', params, function (response) { + if (response.success === true) { + $.each(response.databases, function (idx, value) { + var option = $(''); + option.text(value); + option.attr('value', value); + $('#db_alias_select').append(option); + }); + } else { + PMA_ajaxShowMessage(response.error, false); + } + }); + } }, close: function() { var isEmpty = true; $(this).find('input[type="text"]').each(function() { - // trim input fields on close - $(this).val($(this).val().trim()); - // check if non empty field present + // trim empty input fields on close if ($(this).val()) { isEmpty = false; + } else { + $(this).parents('tr').remove(); } }); + // Toggle checkbox based on aliases $('input#btn_alias_config').prop('checked', !isEmpty); }, position: { my: "center top", at: "center top", of: window } }); - // Call change event of .table_alias_select - $('.table_alias_select:visible').trigger('change'); +} + +function aliasToggleRow(elm) { + var inputs = elm.parents('tr').find('input,button'); + if (elm.val()) { + inputs.attr('disabled', false); + } else { + inputs.attr('disabled', true); + } +} + +function addAlias(type, name, field, value) { + if (value === '') { + return; + } + + var row = $('#alias_data tfoot tr').clone(); + row.find('th').text(type); + row.find('td:first').text(name); + row.find('input').attr('name', field); + row.find('input').val(value); + row.find('.alias_remove').on('click', function () { + $(this).parents('tr').remove(); + }); + + var matching = $('#alias_data [name="' + $.escapeSelector(field) + '"]'); + if (matching.length > 0) { + matching.parents('tr').remove(); + } + + $('#alias_data tbody').append(row); } AJAX.registerOnload('export.js', function () { @@ -846,18 +890,100 @@ AJAX.registerOnload('export.js', function () { // Open Alias Modal Dialog on click $('#btn_alias_config').on('click', createAliasModal); - - // Database alias select on change event - $('#db_alias_select').on( - 'change', - {sel: 'span', type: '_tables'}, - aliasSelectHandler - ); - - // Table alias select on change event - $('.table_alias_select').on( - 'change', - {sel: 'table', type: '_cols'}, - aliasSelectHandler - ); + $('.alias_remove').on('click', function () { + $(this).parents('tr').remove(); + }); + $('#db_alias_select').on('change', function () { + aliasToggleRow($(this)); + var db = $(this).val(); + var table = PMA_commonParams.get('table'); + if (table) { + var option = $(''); + option.text(table); + option.attr('value', table); + $('#table_alias_select').append(option).val(table).change(); + } else { + var params = { + ajax_request : true, + token : PMA_commonParams.get('token'), + server : PMA_commonParams.get('server'), + db : $(this).val(), + type: 'list-tables' + }; + $.post('ajax.php', params, function (response) { + if (response.success === true) { + $.each(response.tables, function (idx, value) { + var option = $(''); + option.text(value); + option.attr('value', value); + $('#table_alias_select').append(option); + }); + } else { + PMA_ajaxShowMessage(response.error, false); + } + }); + } + }); + $('#table_alias_select').on('change', function () { + aliasToggleRow($(this)); + var params = { + ajax_request : true, + token : PMA_commonParams.get('token'), + server : PMA_commonParams.get('server'), + db : $('#db_alias_select').val(), + table: $(this).val(), + type: 'list-columns' + }; + $.post('ajax.php', params, function (response) { + if (response.success === true) { + $.each(response.columns, function (idx, value) { + var option = $(''); + option.text(value); + option.attr('value', value); + $('#column_alias_select').append(option); + }); + } else { + PMA_ajaxShowMessage(response.error, false); + } + }); + }); + $('#column_alias_select').on('change', function () { + aliasToggleRow($(this)); + }); + $('#db_alias_button').on('click', function (e) { + e.preventDefault(); + var db = $('#db_alias_select').val(); + addAlias( + PMA_messages.strAliasDatabase, + db, + 'aliases[' + db + '][alias]', + $('#db_alias_name').val() + ); + $('#db_alias_name').val(''); + }); + $('#table_alias_button').on('click', function (e) { + e.preventDefault(); + var db = $('#db_alias_select').val(); + var table = $('#table_alias_select').val(); + addAlias( + PMA_messages.strAliasTable, + db + '.' + table, + 'aliases[' + db + '][tables][' + table + '][alias]', + $('#table_alias_name').val() + ); + $('#table_alias_name').val(''); + }); + $('#column_alias_button').on('click', function (e) { + e.preventDefault(); + var db = $('#db_alias_select').val(); + var table = $('#table_alias_select').val(); + var column = $('#column_alias_select').val(); + addAlias( + PMA_messages.strAliasColumn, + db + '.' + table + '.' + column, + 'aliases[' + db + '][tables][' + table + '][colums][' + column + ']', + $('#column_alias_name').val() + ); + $('#column_alias_name').val(''); + }); }); diff --git a/js/messages.php b/js/messages.php index bd807543b1..a7f4c8547b 100644 --- a/js/messages.php +++ b/js/messages.php @@ -295,6 +295,10 @@ $js_messages['strProfilingResults'] = __('Profiling results'); $js_messages['strTable'] = _pgettext('Display format', 'Table'); $js_messages['strChart'] = __('Chart'); +$js_messages['strAliasDatabase'] = _pgettext('Alias', 'Database'); +$js_messages['strAliasTable'] = _pgettext('Alias', 'Table'); +$js_messages['strAliasColumn'] = _pgettext('Alias', 'Column'); + /* l10n: A collection of available filters */ $js_messages['strFiltersForLogTable'] = __('Log table filter options'); /* l10n: Filter as in "Start Filtering" */ diff --git a/libraries/display_export.lib.php b/libraries/display_export.lib.php index bc80a65078..36f2d77b15 100644 --- a/libraries/display_export.lib.php +++ b/libraries/display_export.lib.php @@ -11,6 +11,7 @@ use PMA\libraries\Message; use PMA\libraries\plugins\ExportPlugin; use PMA\libraries\Response; use PMA\libraries\Table; +use PMA\libraries\Template; use PMA\libraries\URL; /** @@ -877,25 +878,76 @@ function PMA_getHtmlForExportOptions( $html .= PMA_getHtmlForExportOptionsQuickExport(); } - $html .= PMA_getHtmlForAliasModalDialog($db, $table); + $html .= PMA_getHtmlForAliasModalDialog(); $html .= PMA_getHtmlForExportOptionsOutput($export_type); $html .= PMA_getHtmlForExportOptionsFormat($export_list); return $html; } /** - * Prints Html For Alias Modal Dialog - * - * @param String $db Selected DB - * @param String $table Selected Table + * Generate Html For currently defined aliases * * @return string */ -function PMA_getHtmlForAliasModalDialog($db = '', $table = '') +function PMA_getHtmlForCurrentAlias() { + $result = ''; + + $template = Template::get('export/alias_item'); if (isset($_SESSION['tmpval']['aliases'])) { - $aliases = $_SESSION['tmpval']['aliases']; + foreach ($_SESSION['tmpval']['aliases'] as $db => $db_data) { + if (isset($db_data['alias'])) { + $result .= $template->render(array( + 'type' => _pgettext('Alias', 'Database'), + 'name' => $db, + 'field' => 'aliases[' . $db . '][alias]', + 'value' => $db_data['alias'], + )); + } + if (! isset($db_data['tables'])) { + continue; + } + foreach ($db_data['tables'] as $table => $table_data) { + if (isset($table_data['alias'])) { + $result .= $template->render(array( + 'type' => _pgettext('Alias', 'Table'), + 'name' => $db . '.' . $table, + 'field' => 'aliases[' . $db . '][tables][' . $table . '][alias]', + 'value' => $table_data['alias'], + )); + } + if (! isset($table_data['columns'])) { + continue; + } + foreach ($table_data['columns'] as $column => $column_name) { + $result .= $template->render(array( + 'type' => _pgettext('Alias', 'Column'), + 'name' => $db . '.' . $table . '.'. $column, + 'field' => 'aliases[' . $db . '][tables][' . $table . '][colums][' . $column . ']', + 'value' => $column_name, + )); + } + } + } } + + // Empty row for javascript manipulations + $result .= '' . $template->render(array( + 'type' => '', 'name' => '', 'field' => 'aliases_new', 'value' => '' + )) . ''; + + return $result . '
' + . __('Defined aliases') + . '
'; +} + +/** + * Generate Html For Alias Modal Dialog + * + * @return string + */ +function PMA_getHtmlForAliasModalDialog() +{ // In case of server export, the following list of // databases are not shown in the list. $dbs_not_allowed = array( @@ -906,114 +958,10 @@ function PMA_getHtmlForAliasModalDialog($db = '', $table = '') // Fetch Columns info // Server export does not have db set. $title = __('Rename exported databases/tables/columns'); - if (empty($db)) { - $databases = $GLOBALS['dbi']->getColumnsFull( - null, null, null, $GLOBALS['userlink'] - ); - foreach ($dbs_not_allowed as $db) { - unset($databases[$db]); - } - // Database export does not have table set. - } elseif (empty($table)) { - $tables = $GLOBALS['dbi']->getColumnsFull( - $db, null, null, $GLOBALS['userlink'] - ); - $databases = array($db => $tables); - // Table export - } else { - $columns = $GLOBALS['dbi']->getColumnsFull( - $db, $table, null, $GLOBALS['userlink'] - ); - $databases = array( - $db => array( - $table => $columns - ) - ); - } $html = '
'; - $db_html = ''; - $db_html .= ''; - $table_html .= ''; - $table_html .= ''; - $table_html .= ''; - $col_html .= ''; - $col_html .= '' - . ''; - foreach ($columns as $column => $col_def) { - $val = ''; - if (!empty($aliases[$db]['tables'][$table]['columns'][$column])) { - $val = htmlspecialchars( - $aliases[$db]['tables'][$table]['columns'][$column] - ); - } - $column = htmlspecialchars($column); - $name_attr = 'aliases[' . $db . '][tables][' . $table - . '][columns][' . $column . ']'; - $id_attr = substr(md5($name_attr), 0, 12); - $col_html .= ''; - $col_html .= ''; - $col_html .= ''; - $col_html .= ''; - } - $col_html .= '
' . __('Old column name') . '' . __('New column name') . '
'; - } - $table_html .= ''; - $table_html .= $table_input_html . '
' . $col_html . '
'; - } - $db_html .= ''; - $html .= $db_html; - $html .= $db_input_html . '
'; - $html .= $table_html; + $html .= PMA_getHtmlForCurrentAlias(); + $html .= Template::get('export/alias_add')->render(); $html .= '
'; return $html; diff --git a/templates/export/alias_add.phtml b/templates/export/alias_add.phtml new file mode 100644 index 0000000000..3f29fa9467 --- /dev/null +++ b/templates/export/alias_add.phtml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + +
+ + + + + + + +
diff --git a/templates/export/alias_item.phtml b/templates/export/alias_item.phtml new file mode 100644 index 0000000000..e0da9cce58 --- /dev/null +++ b/templates/export/alias_item.phtml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/test/libraries/PMA_display_export_test.php b/test/libraries/PMA_display_export_test.php index c3c2d7ca84..bad7ca286d 100644 --- a/test/libraries/PMA_display_export_test.php +++ b/test/libraries/PMA_display_export_test.php @@ -235,10 +235,6 @@ class PMA_DisplayExport_Test extends PHPUnit_Framework_TestCase 'New table name', $html ); - $this->assertContains( - 'test_column', - $html - ); //validate 6: PMA_getHtmlForExportOptionsOutput $this->assertContains( @@ -297,35 +293,7 @@ class PMA_DisplayExport_Test extends PHPUnit_Framework_TestCase . 'Rename exported databases/tables/columns">', $html ); - $this->assertContains( - 'test\'_db', - $html - ); - $this->assertContains( - 'test_<b>table', - $html - ); - $this->assertContains( - 'col<2', - $html - ); - $this->assertContains( - 'co"l1', - $html - ); - $this->assertContains( - '
', - $html - ); - $name_attr = 'aliases[test\'_db][tables][test_<b>table][alias]'; - $id_attr = mb_substr(md5($name_attr), 0, 12); - - $this->assertContains( - '', - $html - ); + $this->assertContains('