Merge pull request #121 from lem9/test-for-missing-redirection

Fix for bug 3594237
This commit is contained in:
Michal Čihař 2012-12-19 03:50:31 -08:00
commit ad6a9d1a1b
8 changed files with 295 additions and 203 deletions

View File

@ -22,6 +22,8 @@
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('tbl_structure.js', function() {
$("a.change_column_anchor.ajax").die('click');
$("button.change_columns_anchor.ajax, input.change_columns_anchor.ajax").die('click');
$("a.drop_column_anchor.ajax").die('click');
$("a.add_primary_key_anchor.ajax").die('click');
$('a.drop_primary_key_index_anchor.ajax').die('click');
@ -31,6 +33,48 @@ AJAX.registerTeardown('tbl_structure.js', function() {
});
AJAX.registerOnload('tbl_structure.js', function() {
/**
* Attach Event Handler for 'Change Column'
*
* (see $GLOBALS['cfg']['AjaxEnable'])
*/
$("a.change_column_anchor.ajax").live('click', function(event) {
event.preventDefault();
$('#page_content').hide();
$.get($(this).attr('href'), {'ajax_request': true}, function(data) {
if (data.success) {
$('<div id="change_column_dialog"></div>')
.html(data.message)
.insertBefore('#page_content');
PMA_verifyColumnsProperties();
} else {
PMA_ajaxShowMessage(PMA_messages['strErrorProcessingRequest'] + " : " + data.error, false);
}
});
});
/**
* Attach Event Handler for 'Change multiple columns'
*
* (see $GLOBALS['cfg']['AjaxEnable'])
*/
$("button.change_columns_anchor.ajax, input.change_columns_anchor.ajax").live('click', function(event) {
event.preventDefault();
$('#page_content').hide();
var $form = $(this).closest('form');
var params = $form.serialize() + "&ajax_request=true&submit_mult=change";
$.post($form.prop("action"), params, function (data) {
if (data.success) {
$('<div id="change_column_dialog"></div>')
.html(data.message)
.insertBefore('#page_content');
PMA_verifyColumnsProperties();
} else {
PMA_ajaxShowMessage(PMA_messages['strErrorProcessingRequest'] + " : " + data.error, false);
}
});
});
/**
* Attach Event Handler for 'Drop Column'
*
@ -356,6 +400,7 @@ function reloadFieldForm(message) {
PMA_ajaxShowMessage(message);
}, 500);
});
$('#page_content').show();
}
/**

View File

@ -2321,7 +2321,7 @@ class PMA_Util
* Generate a button or image tag
*
* @param string $button_name name of button element
* @param string $button_class class of button element
* @param string $button_class class of button or image element
* @param string $image_name name of image element
* @param string $text text to display
* @param string $image image to display
@ -2348,6 +2348,7 @@ class PMA_Util
/* IE (before version 9) has trouble with <button> */
if (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER < 9) {
return '<input type="image" name="' . $image_name
. '" class="' . $button_class
. '" value="' . htmlspecialchars($value)
. '" title="' . htmlspecialchars($text)
. '" src="' . $GLOBALS['pmaThemeImage']. $image . '" />'

View File

@ -125,7 +125,7 @@ if (! empty($submit_mult)
$mult_btn = __('Yes');
break;
case 'change':
include './tbl_alter.php';
PMA_displayHtmlForColumnChange($db, $table, $selected, $action);
// execution stops here but PMA_Response correctly finishes
// the rendering
exit;

View File

@ -31,11 +31,13 @@ class Node_Column extends Node
parent::__construct($name, $type, $is_group);
$this->icon = PMA_Util::getImage('pause.png', '');
$this->links = array(
'text' => 'tbl_alter.php?server=' . $GLOBALS['server']
'text' => 'tbl_structure.php?server=' . $GLOBALS['server']
. '&amp;db=%3$s&amp;table=%2$s&amp;field=%1$s'
. '&amp;change_column=1'
. '&amp;token=' . $GLOBALS['token'],
'icon' => 'tbl_alter.php?server=' . $GLOBALS['server']
'icon' => 'tbl_structure.php?server=' . $GLOBALS['server']
. '&amp;db=%3$s&amp;table=%2$s&amp;field=%1$s'
. '&amp;change_column=1'
. '&amp;token=' . $GLOBALS['token']
);
}

View File

@ -1316,8 +1316,11 @@ function PMA_getHtmlForDropColumn($tbl_is_view, $db_is_information_schema,
if (! $tbl_is_view && ! $db_is_information_schema) {
$html_output .= '<td class="edit center">'
. '<a href="tbl_alter.php?' . $url_query . '&amp;field='
. $field_encoded . '">'
. '<a class="change_column_anchor'
. ($GLOBALS['cfg']['AjaxEnable'] ? ' ajax' : '')
. '" href="tbl_structure.php?'
. $url_query . '&amp;field=' . $field_encoded
. '&amp;change_column=1">'
. $titles['Change'] . '</a>' . '</td>';
$html_output .= '<td class="drop center">'
. '<a class="drop_column_anchor'
@ -1374,8 +1377,8 @@ function PMA_getHtmlForCheckAllTableColumn($pmaThemeImage, $text_dir,
if (! $tbl_is_view && ! $db_is_information_schema) {
$html_output .= PMA_Util::getButtonOrImage(
'submit_mult', 'mult_submit', 'submit_mult_change',
__('Change'), 'b_edit.png', 'change'
'submit_mult', 'mult_submit change_columns_anchor ajax',
'submit_mult_change', __('Change'), 'b_edit.png', 'change'
);
$html_output .= PMA_Util::getButtonOrImage(
'submit_mult', 'mult_submit', 'submit_mult_drop',
@ -2241,4 +2244,211 @@ function PMA_getHtmlForDisplayTableStats($showtable, $table_info_num_rows,
return $html_output;
}
/**
* Displays HTML for changing one or more columns
*
* @param string $db database name
* @param string $table table name
* @param array $selected the selected columns
* @param string $action target script to call
*
* @return boolean $regenerate true if error occurred
*
*/
function PMA_displayHtmlForColumnChange($db, $table, $selected, $action)
{
// $selected comes from multi_submits.inc.php
if (empty($selected)) {
$selected[] = $_REQUEST['field'];
$selected_cnt = 1;
} else { // from a multiple submit
$selected_cnt = count($selected);
}
/**
* @todo optimize in case of multiple fields to modify
*/
for ($i = 0; $i < $selected_cnt; $i++) {
$fields_meta[] = PMA_DBI_get_columns($db, $table, $selected[$i], true);
}
$num_fields = count($fields_meta);
// set these globals because tbl_properties.inc.php verifies them
// @todo: refactor tbl_properties.inc.php so that it uses function params
$GLOBALS['action'] = 'tbl_alter.php';
$GLOBALS['num_fields'] = $num_fields;
// Get more complete field information.
// For now, this is done to obtain MySQL 4.1.2+ new TIMESTAMP options
// and to know when there is an empty DEFAULT value.
// Later, if the analyser returns more information, it
// could be executed to replace the info given by SHOW FULL COLUMNS FROM.
/**
* @todo put this code into a require()
* or maybe make it part of PMA_DBI_get_columns();
*/
// We also need this to correctly learn if a TIMESTAMP is NOT NULL, since
// SHOW FULL COLUMNS says NULL and SHOW CREATE TABLE says NOT NULL (tested
// in MySQL 4.0.25).
$show_create_table = PMA_DBI_fetch_value(
'SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.' . PMA_Util::backquote($table),
0, 1
);
$analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
unset($show_create_table);
/**
* Form for changing properties.
*/
include 'libraries/tbl_properties.inc.php';
}
/**
* Update the table's structure based on $_REQUEST
*
* @param string $db database name
* @param string $table table name
*
* @return boolean $regenerate true if error occurred
*
*/
function PMA_updateColumns($db, $table)
{
$regenerate = false;
$field_cnt = count($_REQUEST['field_orig']);
$key_fields = array();
$changes = array();
for ($i = 0; $i < $field_cnt; $i++) {
$changes[] = 'CHANGE ' . PMA_Table::generateAlter(
$_REQUEST['field_orig'][$i],
$_REQUEST['field_name'][$i],
$_REQUEST['field_type'][$i],
$_REQUEST['field_length'][$i],
$_REQUEST['field_attribute'][$i],
isset($_REQUEST['field_collation'][$i])
? $_REQUEST['field_collation'][$i]
: '',
isset($_REQUEST['field_null'][$i])
? $_REQUEST['field_null'][$i]
: 'NOT NULL',
$_REQUEST['field_default_type'][$i],
$_REQUEST['field_default_value'][$i],
isset($_REQUEST['field_extra'][$i])
? $_REQUEST['field_extra'][$i]
: false,
isset($_REQUEST['field_comments'][$i])
? $_REQUEST['field_comments'][$i]
: '',
$key_fields,
$i,
isset($_REQUEST['field_move_to'][$i])
? $_REQUEST['field_move_to'][$i]
: ''
);
} // end for
// Builds the primary keys statements and updates the table
$key_query = '';
/**
* this is a little bit more complex
*
* @todo if someone selects A_I when altering a column we need to check:
* - no other column with A_I
* - the column has an index, if not create one
*
if (count($key_fields)) {
$fields = array();
foreach ($key_fields as $each_field) {
if (isset($_REQUEST['field_name'][$each_field]) && strlen($_REQUEST['field_name'][$each_field])) {
$fields[] = PMA_Util::backquote($_REQUEST['field_name'][$each_field]);
}
} // end for
$key_query = ', ADD KEY (' . implode(', ', $fields) . ') ';
}
*/
// To allow replication, we first select the db to use and then run queries
// on this db.
if (! PMA_DBI_select_db($db)) {
PMA_Util::mysqlDie(
PMA_DBI_getError(),
'USE ' . PMA_Util::backquote($db) . ';',
'',
$err_url
);
}
$sql_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ';
$sql_query .= implode(', ', $changes) . $key_query;
$sql_query .= ';';
$result = PMA_DBI_try_query($sql_query);
if ($result !== false) {
$message = PMA_Message::success(
__('Table %1$s has been altered successfully')
);
$message->addParam($table);
$btnDrop = 'Fake';
/**
* If comments were sent, enable relation stuff
*/
include_once 'libraries/transformations.lib.php';
// update field names in relation
if (isset($_REQUEST['field_orig']) && is_array($_REQUEST['field_orig'])) {
foreach ($_REQUEST['field_orig'] as $fieldindex => $fieldcontent) {
if ($_REQUEST['field_name'][$fieldindex] != $fieldcontent) {
PMA_REL_renameField(
$db, $table, $fieldcontent,
$_REQUEST['field_name'][$fieldindex]
);
}
}
}
// update mime types
if (isset($_REQUEST['field_mimetype'])
&& is_array($_REQUEST['field_mimetype'])
&& $GLOBALS['cfg']['BrowseMIME']
) {
foreach ($_REQUEST['field_mimetype'] as $fieldindex => $mimetype) {
if (isset($_REQUEST['field_name'][$fieldindex])
&& strlen($_REQUEST['field_name'][$fieldindex])
) {
PMA_setMIME(
$db, $table, $_REQUEST['field_name'][$fieldindex],
$mimetype,
$_REQUEST['field_transformation'][$fieldindex],
$_REQUEST['field_transformation_options'][$fieldindex]
);
}
}
}
$response = PMA_Response::getInstance();
if ($response->isAjax()) {
$response->isSuccess($message->isSuccess());
$response->addJSON('message', $message);
$response->addJSON(
'sql_query',
PMA_Util::getMessage(null, $sql_query)
);
}
} else {
PMA_Util::mysqlDie('', '', '', $err_url, false);
// An error happened while inserting/updating a table definition.
// to prevent total loss of that data, we embed the form once again.
// The variable $regenerate will be used to restore data in libraries/tbl_properties.inc.php
// @todo: test this code, now that it's inside a function
if (isset($_REQUEST['orig_field'])) {
$_REQUEST['field'] = $_REQUEST['orig_field'];
}
$regenerate = true;
}
return $regenerate;
}
?>

View File

@ -40,7 +40,7 @@ $html = '';
$length_values_input_size = 8;
$_form_params = array(
'db' => $db,
'db' => $db
);
if ($action == 'tbl_create.php') {
@ -137,7 +137,10 @@ $header_cells[] = __('Comments');
if (isset($fields_meta)) {
// for moving, load all available column names
$move_columns_sql_query = 'SELECT * FROM ' . PMA_Util::backquote($table);
$move_columns_sql_query = 'SELECT * FROM '
. PMA_Util::backquote($db)
. '.'
. PMA_Util::backquote($table);
$move_columns_sql_result = PMA_DBI_try_query($move_columns_sql_query);
$move_columns = PMA_DBI_get_fields_meta($move_columns_sql_result);
unset($move_columns_sql_query, $move_columns_sql_result);
@ -145,7 +148,7 @@ if (isset($fields_meta)) {
$header_cells[] = __('Move column');
}
if ($cfgRelation['mimework'] && $cfg['BrowseMIME']) {
if ($cfgRelation['mimework'] && $GLOBALS['cfg']['BrowseMIME']) {
$mime_map = PMA_getMIME($db, $table);
$available_mime = PMA_getAvailableMIMEtypes();
@ -648,7 +651,7 @@ for ($i = 0; $i < $num_fields; $i++) {
// column MIME-types
if ($cfgRelation['mimework']
&& $cfg['BrowseMIME']
&& $GLOBALS['cfg']['BrowseMIME']
&& $cfgRelation['commwork']
) {
$content_cells[$i][$ci] = '<select id="field_' . $i . '_'

View File

@ -125,195 +125,4 @@ if (isset($_REQUEST['move_columns'])
}
exit;
}
/**
* Modifications have been submitted -> updates the table
*/
$abort = false;
if (isset($_REQUEST['do_save_data'])) {
$field_cnt = count($_REQUEST['field_orig']);
$key_fields = array();
$changes = array();
for ($i = 0; $i < $field_cnt; $i++) {
$changes[] = 'CHANGE ' . PMA_Table::generateAlter(
$_REQUEST['field_orig'][$i],
$_REQUEST['field_name'][$i],
$_REQUEST['field_type'][$i],
$_REQUEST['field_length'][$i],
$_REQUEST['field_attribute'][$i],
isset($_REQUEST['field_collation'][$i])
? $_REQUEST['field_collation'][$i]
: '',
isset($_REQUEST['field_null'][$i])
? $_REQUEST['field_null'][$i]
: 'NOT NULL',
$_REQUEST['field_default_type'][$i],
$_REQUEST['field_default_value'][$i],
isset($_REQUEST['field_extra'][$i])
? $_REQUEST['field_extra'][$i]
: false,
isset($_REQUEST['field_comments'][$i])
? $_REQUEST['field_comments'][$i]
: '',
$key_fields,
$i,
isset($_REQUEST['field_move_to'][$i])
? $_REQUEST['field_move_to'][$i]
: ''
);
} // end for
// Builds the primary keys statements and updates the table
$key_query = '';
/**
* this is a little bit more complex
*
* @todo if someone selects A_I when altering a column we need to check:
* - no other column with A_I
* - the column has an index, if not create one
*
if (count($key_fields)) {
$fields = array();
foreach ($key_fields as $each_field) {
if (isset($_REQUEST['field_name'][$each_field]) && strlen($_REQUEST['field_name'][$each_field])) {
$fields[] = PMA_Util::backquote($_REQUEST['field_name'][$each_field]);
}
} // end for
$key_query = ', ADD KEY (' . implode(', ', $fields) . ') ';
}
*/
// To allow replication, we first select the db to use and then run queries
// on this db.
if (! PMA_DBI_select_db($db)) {
PMA_Util::mysqlDie(
PMA_DBI_getError(),
'USE ' . PMA_Util::backquote($db) . ';',
'',
$err_url
);
}
$sql_query = 'ALTER TABLE ' . PMA_Util::backquote($table) . ' ';
$sql_query .= implode(', ', $changes) . $key_query;
$sql_query .= ';';
$result = PMA_DBI_try_query($sql_query);
if ($result !== false) {
$message = PMA_Message::success(
__('Table %1$s has been altered successfully')
);
$message->addParam($table);
$btnDrop = 'Fake';
/**
* If comments were sent, enable relation stuff
*/
include_once 'libraries/transformations.lib.php';
// update field names in relation
if (isset($_REQUEST['field_orig']) && is_array($_REQUEST['field_orig'])) {
foreach ($_REQUEST['field_orig'] as $fieldindex => $fieldcontent) {
if ($_REQUEST['field_name'][$fieldindex] != $fieldcontent) {
PMA_REL_renameField(
$db, $table, $fieldcontent,
$_REQUEST['field_name'][$fieldindex]
);
}
}
}
// update mime types
if (isset($_REQUEST['field_mimetype'])
&& is_array($_REQUEST['field_mimetype'])
&& $cfg['BrowseMIME']
) {
foreach ($_REQUEST['field_mimetype'] as $fieldindex => $mimetype) {
if (isset($_REQUEST['field_name'][$fieldindex])
&& strlen($_REQUEST['field_name'][$fieldindex])
) {
PMA_setMIME(
$db, $table, $_REQUEST['field_name'][$fieldindex],
$mimetype,
$_REQUEST['field_transformation'][$fieldindex],
$_REQUEST['field_transformation_options'][$fieldindex]
);
}
}
}
$response = PMA_Response::getInstance();
if ($response->isAjax()) {
$response->isSuccess($message->isSuccess());
$response->addJSON('message', $message);
$response->addJSON(
'sql_query',
PMA_Util::getMessage(null, $sql_query)
);
exit;
}
$active_page = 'tbl_structure.php';
include 'tbl_structure.php';
} else {
PMA_Util::mysqlDie('', '', '', $err_url, false);
// An error happened while inserting/updating a table definition.
// to prevent total loss of that data, we embed the form once again.
// The variable $regenerate will be used to restore data in libraries/tbl_properties.inc.php
if (isset($_REQUEST['orig_field'])) {
$_REQUEST['field'] = $_REQUEST['orig_field'];
}
$regenerate = true;
}
}
/**
* No modifications yet required -> displays the table fields
*
* $selected comes from multi_submits.inc.php
*/
if ($abort == false) {
if (! isset($selected)) {
PMA_Util::checkParameters(array('field'));
$selected[] = $_REQUEST['field'];
$selected_cnt = 1;
} else { // from a multiple submit
$selected_cnt = count($selected);
}
/**
* @todo optimize in case of multiple fields to modify
*/
for ($i = 0; $i < $selected_cnt; $i++) {
$fields_meta[] = PMA_DBI_get_columns($db, $table, $selected[$i], true);
}
$num_fields = count($fields_meta);
$action = 'tbl_alter.php';
// Get more complete field information.
// For now, this is done to obtain MySQL 4.1.2+ new TIMESTAMP options
// and to know when there is an empty DEFAULT value.
// Later, if the analyser returns more information, it
// could be executed to replace the info given by SHOW FULL COLUMNS FROM.
/**
* @todo put this code into a require()
* or maybe make it part of PMA_DBI_get_columns();
*/
// We also need this to correctly learn if a TIMESTAMP is NOT NULL, since
// SHOW FULL COLUMNS says NULL and SHOW CREATE TABLE says NOT NULL (tested
// in MySQL 4.0.25).
$show_create_table = PMA_DBI_fetch_value(
'SHOW CREATE TABLE ' . PMA_Util::backquote($db) . '.' . PMA_Util::backquote($table),
0, 1
);
$analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
unset($show_create_table);
/**
* Form for changing properties.
*/
include 'libraries/tbl_properties.inc.php';
}
?>

View File

@ -24,6 +24,28 @@ $scripts = $header->getScripts();
$scripts->addFile('tbl_structure.js');
$scripts->addFile('indexes.js');
/**
* A click on Change has been made for one column
*/
if (isset($_REQUEST['change_column'])) {
PMA_displayHtmlForColumnChange($db, $table, null, 'tbl_structure.php');
exit;
}
/**
* Modifications have been submitted -> updates the table
*/
if (isset($_REQUEST['do_save_data'])) {
$regenerate = PMA_updateColumns($db, $table);
if ($regenerate) {
// @todo: find in which situation this happens, then
// do something appropriate
} else {
// continue to show the table's structure
unset($_REQUEST['selected']);
unset($_REQUEST['true_selected']);
}
}
/**
* handle multiple field commands if required
*