diff --git a/composer.json b/composer.json
index 2423a2565a..d5c178e0ee 100644
--- a/composer.json
+++ b/composer.json
@@ -65,7 +65,7 @@
"samyoul/u2f-php-server": "<1.1"
},
"suggest": {
- "ext-openssl": "Cookie encryption",
+ "ext-openssl": "For encryption performance",
"ext-curl": "Updates checking",
"ext-opcache": "Better performance",
"ext-zlib": "For gz import and export",
@@ -76,7 +76,8 @@
"tecnickcom/tcpdf": "For PDF support",
"pragmarx/google2fa": "For 2FA authentication",
"bacon/bacon-qr-code": "For 2FA authentication",
- "samyoul/u2f-php-server": "For FIDO U2F authentication"
+ "samyoul/u2f-php-server": "For FIDO U2F authentication",
+ "paragonie/sodium_compat": "For modern encryption support"
},
"require-dev": {
"phpunit/phpunit": "^4.8.36 || ^5.7",
@@ -87,7 +88,9 @@
"pragmarx/google2fa": "^3.0",
"bacon/bacon-qr-code": "^1.0",
"samyoul/u2f-php-server": "^1.1",
- "phpmyadmin/coding-standard": "^0.3"
+ "phpmyadmin/coding-standard": "^0.3",
+ "paragonie/random_compat": ">=2",
+ "paragonie/sodium_compat": "^1.17"
},
"extra": {
"branch-alias": {
diff --git a/config.sample.inc.php b/config.sample.inc.php
index 5eede6dd90..48dfdfdefe 100644
--- a/config.sample.inc.php
+++ b/config.sample.inc.php
@@ -148,6 +148,13 @@ $cfg['SaveDir'] = '';
*/
//$cfg['SendErrorReports'] = 'always';
+/**
+ * 'URLQueryEncryption' defines whether phpMyAdmin will encrypt sensitive data from the URL query string.
+ * 'URLQueryEncryptionSecretKey' is a 32 bytes long secret key used to encrypt/decrypt the URL query string.
+ */
+//$cfg['URLQueryEncryption'] = true;
+//$cfg['URLQueryEncryptionSecretKey'] = '';
+
/**
* You can find more configuration options in the documentation
* in the doc/ folder or at
';
@@ -226,7 +226,7 @@ class ServerBinlogController extends Controller
$this_url_params = $url_params;
$this_url_params['pos'] = $pos + $GLOBALS['cfg']['MaxRows'];
$html .= ' - ';
diff --git a/libraries/classes/Controllers/Table/TableStructureController.php b/libraries/classes/Controllers/Table/TableStructureController.php
index 5ace136ab6..80dccdb8e5 100644
--- a/libraries/classes/Controllers/Table/TableStructureController.php
+++ b/libraries/classes/Controllers/Table/TableStructureController.php
@@ -1241,13 +1241,6 @@ class TableStructureController extends TableController
'DistinctValues' => Util::getIcon('b_browse', __('Distinct values')),
);
- $edit_view_url = '';
- if ($this->_tbl_is_view && ! $this->_db_is_system_schema) {
- $edit_view_url = Url::getCommon(
- array('db' => $this->db, 'table' => $this->table)
- );
- }
-
/**
* Displays Space usage and row statistics
*/
@@ -1275,11 +1268,11 @@ class TableStructureController extends TableController
'tbl_is_view' => $this->_tbl_is_view,
'mime_map' => $mime_map,
'url_query' => $this->_url_query,
+ 'url_params' => $url_params,
'titles' => $titles,
'tbl_storage_engine' => $this->_tbl_storage_engine,
'primary' => $primary_index,
'columns_with_unique_index' => $columns_with_unique_index,
- 'edit_view_url' => $edit_view_url,
'columns_list' => $columns_list,
'table_stats' => isset($tablestats) ? $tablestats : null,
'fields' => $fields,
diff --git a/libraries/classes/Core.php b/libraries/classes/Core.php
index bf5edde41a..621544edf5 100644
--- a/libraries/classes/Core.php
+++ b/libraries/classes/Core.php
@@ -1317,4 +1317,36 @@ class Core
$hmac = hash_hmac('sha256', $sqlQuery, $_SESSION[' HMAC_secret '] . $cfg['blowfish_secret']);
return hash_equals($hmac, $signature);
}
+
+ /**
+ * @return void
+ */
+ public static function populateRequestWithEncryptedQueryParams()
+ {
+ if (
+ (! isset($_GET['eq']) || ! is_string($_GET['eq']))
+ && (! isset($_POST['eq']) || ! is_string($_POST['eq']))
+ ) {
+ unset($_GET['eq'], $_POST['eq'], $_REQUEST['eq']);
+ return;
+ }
+
+ $isFromPost = isset($_POST['eq']);
+ $decryptedQuery = Url::decryptQuery($isFromPost ? $_POST['eq'] : $_GET['eq']);
+ unset($_GET['eq'], $_POST['eq'], $_REQUEST['eq']);
+ if ($decryptedQuery === null) {
+ return;
+ }
+
+ $urlQueryParams = (array) json_decode($decryptedQuery);
+ foreach ($urlQueryParams as $urlQueryParamKey => $urlQueryParamValue) {
+ if ($isFromPost) {
+ $_POST[$urlQueryParamKey] = $urlQueryParamValue;
+ } else {
+ $_GET[$urlQueryParamKey] = $urlQueryParamValue;
+ }
+
+ $_REQUEST[$urlQueryParamKey] = $urlQueryParamValue;
+ }
+ }
}
diff --git a/libraries/classes/Crypto/Crypto.php b/libraries/classes/Crypto/Crypto.php
new file mode 100644
index 0000000000..6449f7dca5
--- /dev/null
+++ b/libraries/classes/Crypto/Crypto.php
@@ -0,0 +1,155 @@
+hasRandomBytesSupport = ! $forceFallback && is_callable('random_bytes');
+ $this->hasSodiumSupport = ! $forceFallback
+ && $this->hasRandomBytesSupport
+ && is_callable('sodium_crypto_secretbox')
+ && is_callable('sodium_crypto_secretbox_open')
+ && defined('SODIUM_CRYPTO_SECRETBOX_NONCEBYTES')
+ && defined('SODIUM_CRYPTO_SECRETBOX_KEYBYTES');
+ }
+
+ /**
+ * @param string $plaintext
+ *
+ * @return string
+ */
+ public function encrypt($plaintext)
+ {
+ if ($this->hasSodiumSupport) {
+ return $this->encryptWithSodium($plaintext);
+ }
+
+ return $this->encryptWithPhpseclib($plaintext);
+ }
+
+ /**
+ * @param string $ciphertext
+ *
+ * @return string
+ */
+ public function decrypt($ciphertext)
+ {
+ if ($this->hasSodiumSupport) {
+ return $this->decryptWithSodium($ciphertext);
+ }
+
+ return $this->decryptWithPhpseclib($ciphertext);
+ }
+
+ /**
+ * @return string
+ */
+ private function getEncryptionKey()
+ {
+ global $PMA_Config;
+
+ $keyLength = $this->hasSodiumSupport ? SODIUM_CRYPTO_SECRETBOX_KEYBYTES : 32;
+
+ $key = $PMA_Config->get('URLQueryEncryptionSecretKey');
+ if (is_string($key) && mb_strlen($key, '8bit') === $keyLength) {
+ return $key;
+ }
+
+ $key = isset($_SESSION['URLQueryEncryptionSecretKey']) ? $_SESSION['URLQueryEncryptionSecretKey'] : null;
+ if (is_string($key) && mb_strlen($key, '8bit') === $keyLength) {
+ return $key;
+ }
+
+ $key = $this->hasRandomBytesSupport ? random_bytes($keyLength) : Random::string($keyLength);
+ $_SESSION['URLQueryEncryptionSecretKey'] = $key;
+
+ return $key;
+ }
+
+ /**
+ * @param string $plaintext
+ *
+ * @return string
+ */
+ private function encryptWithPhpseclib($plaintext)
+ {
+ $key = $this->getEncryptionKey();
+ $cipher = new AES(AES::MODE_CBC);
+ $iv = $this->hasRandomBytesSupport ? random_bytes(16) : Random::string(16);
+ $cipher->setIV($iv);
+ $cipher->setKey($key);
+ $ciphertext = $cipher->encrypt($plaintext);
+ $hmac = hash_hmac('sha256', $iv . $ciphertext, $key, true);
+
+ return $hmac . $iv . $ciphertext;
+ }
+
+ /**
+ * @param string $encrypted
+ *
+ * @return string|null
+ */
+ private function decryptWithPhpseclib($encrypted)
+ {
+ $key = $this->getEncryptionKey();
+ $hmac = mb_substr($encrypted, 0, 32, '8bit');
+ $iv = mb_substr($encrypted, 32, 16, '8bit');
+ $ciphertext = mb_substr($encrypted, 48, null, '8bit');
+ $calculatedHmac = hash_hmac('sha256', $iv . $ciphertext, $key, true);
+ if (! hash_equals($hmac, $calculatedHmac)) {
+ return null;
+ }
+
+ $cipher = new AES(AES::MODE_CBC);
+ $cipher->setIV($iv);
+ $cipher->setKey($key);
+
+ return $cipher->decrypt($ciphertext);
+ }
+
+ /**
+ * @param string $plaintext
+ *
+ * @return string
+ */
+ private function encryptWithSodium($plaintext)
+ {
+ $key = $this->getEncryptionKey();
+ $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
+ $ciphertext = sodium_crypto_secretbox($plaintext, $nonce, $key);
+
+ return $nonce . $ciphertext;
+ }
+
+ /**
+ * @param string $encrypted
+ *
+ * @return string|null
+ */
+ private function decryptWithSodium($encrypted)
+ {
+ $key = $this->getEncryptionKey();
+ $nonce = mb_substr($encrypted, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
+ $ciphertext = mb_substr($encrypted, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
+ $decrypted = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);
+ if ($decrypted === false) {
+ return null;
+ }
+
+ return $decrypted;
+ }
+}
diff --git a/libraries/classes/DatabaseInterface.php b/libraries/classes/DatabaseInterface.php
index 47e1946c89..7ab5d754fb 100644
--- a/libraries/classes/DatabaseInterface.php
+++ b/libraries/classes/DatabaseInterface.php
@@ -1563,17 +1563,22 @@ class DatabaseInterface
*/
public function initRelationParamsCache()
{
- if (strlen($GLOBALS['db'])) {
- $cfgRelation = $this->relation->getRelationsParam();
- if (empty($cfgRelation['db'])) {
- $this->relation->fixPmaTables($GLOBALS['db'], false);
- }
- }
- $cfgRelation = $this->relation->getRelationsParam();
- if (empty($cfgRelation['db']) && isset($GLOBALS['dblist'])) {
- if ($GLOBALS['dblist']->databases->exists('phpmyadmin')) {
- $this->relation->fixPmaTables('phpmyadmin', false);
- }
+ $storageDbName = $GLOBALS['cfg']['Server']['pmadb'] ?? '';
+ // Use "phpmyadmin" as a default database name to check to keep the behavior consistent
+ $storageDbName = $storageDbName !== null
+ && is_string($storageDbName)
+ && $storageDbName !== '' ? $storageDbName : 'phpmyadmin';
+
+ // This will make users not having explicitly listed databases
+ // have config values filled by the default phpMyAdmin storage table name values
+ $this->relation->fixPmaTables($storageDbName, false);
+
+ // This global will be changed if fixPmaTables did find one valid table
+ $storageDbName = $GLOBALS['cfg']['Server']['pmadb'] ?? '';
+
+ // Empty means that until now no pmadb was found eligible
+ if (empty($storageDbName)) {
+ $this->relation->fixPmaTables($GLOBALS['db'], false);
}
}
diff --git a/libraries/classes/Dbi/DbiMysqli.php b/libraries/classes/Dbi/DbiMysqli.php
index afd596ccd7..d0905eb00c 100644
--- a/libraries/classes/Dbi/DbiMysqli.php
+++ b/libraries/classes/Dbi/DbiMysqli.php
@@ -149,16 +149,29 @@ class DbiMysqli implements DbiExtension
$host = $server['host'];
}
- $return_value = mysqli_real_connect(
- $link,
- $host,
- $user,
- $password,
- '',
- $server['port'],
- $server['socket'],
- $client_flags
- );
+ if ($server['hide_connection_errors']) {
+ $return_value = @mysqli_real_connect(
+ $link,
+ $host,
+ $user,
+ $password,
+ '',
+ $server['port'],
+ $server['socket'],
+ $client_flags
+ );
+ } else {
+ $return_value = mysqli_real_connect(
+ $link,
+ $host,
+ $user,
+ $password,
+ '',
+ $server['port'],
+ $server['socket'],
+ $client_flags
+ );
+ }
if ($return_value === false || is_null($return_value)) {
/*
@@ -180,7 +193,20 @@ class DbiMysqli implements DbiExtension
);
$server['ssl'] = true;
return self::connect($user, $password, $server);
+ } elseif ($error_number === 1045 && $server['hide_connection_errors']) {
+ trigger_error(
+ sprintf(
+ __(
+ 'Error 1045: Access denied for user. Additional error information'
+ . ' may be available, but is being hidden by the %s configuration directive.'
+ ),
+ '[code][doc@cfg_Servers_hide_connection_errors]'
+ . '$cfg[\'Servers\'][$i][\'hide_connection_errors\'][/doc][/code]'
+ ),
+ E_USER_ERROR
+ );
}
+
return false;
}
diff --git a/libraries/classes/Display/Results.php b/libraries/classes/Display/Results.php
index 6809c227c9..e371df95c4 100644
--- a/libraries/classes/Display/Results.php
+++ b/libraries/classes/Display/Results.php
@@ -1736,9 +1736,8 @@ class Results
$tmp_image = '';
- $tmp_url = 'sql.php' . Url::getCommon($url_params_full_text);
- return Util::linkOrButton($tmp_url, $tmp_image);
+ return Util::linkOrButton('sql.php', $url_params_full_text, $tmp_image);
} // end of the '_getFullOrPartialTextButtonOrLink()' function
@@ -1869,13 +1868,11 @@ class Results
'session_max_rows' => $session_max_rows,
'is_browse_distinct' => $this->__get('is_browse_distinct'),
);
- $single_order_url = 'sql.php' . Url::getCommon($_single_url_params);
- $multi_order_url = 'sql.php' . Url::getCommon($_multi_url_params);
// Displays the sorting URL
// enable sort order swapping for image
$order_link = $this->_getSortOrderLink(
- $order_img, $fields_meta, $single_order_url, $multi_order_url
+ $order_img, $fields_meta, $_single_url_params, $_multi_url_params
);
$sorted_header_html .= $this->_getDraggableClassForSortableColumns(
@@ -2143,10 +2140,10 @@ class Results
/**
* Get sort order link
*
- * @param string $order_img the sort order image
- * @param array $fields_meta set of field properties
- * @param string $order_url the url for sort
- * @param string $multi_order_url the url for sort
+ * @param string $order_img the sort order image
+ * @param array $fields_meta set of field properties
+ * @param array $order_url_params the url params for sort
+ * @param array $multi_order_url_params the url params for sort
*
* @return string the sort order link
*
@@ -2155,7 +2152,7 @@ class Results
* @see _getTableHeaders()
*/
private function _getSortOrderLink(
- $order_img, $fields_meta, $order_url, $multi_order_url
+ $order_img, $fields_meta, $order_url_params, $multi_order_url_params
) {
$order_link_params = array(
'class' => 'sortlink'
@@ -2163,10 +2160,12 @@ class Results
$order_link_content = htmlspecialchars($fields_meta->name);
$inner_link_content = $order_link_content . $order_img
- . '';
+ . '';
return Util::linkOrButton(
- $order_url, $inner_link_content, $order_link_params
+ 'sql.php', $order_url_params, $inner_link_content, $order_link_params
);
} // end of the '_getSortOrderLink()' function
@@ -2608,7 +2607,7 @@ class Results
// 1. Prepares the row
// In print view these variable needs to be initialized
- $del_url = $del_str = $edit_anchor_class
+ $del_url = $del_str = $edit_anchor_class = $editCopyUrlParams = $delUrlParams
= $edit_str = $js_conf = $copy_url = $copy_str = $edit_url = null;
// 1.2 Defines the URLs for the modify/delete link(s)
@@ -2643,7 +2642,7 @@ class Results
if ($displayParts['edit_lnk'] == self::UPDATE_ROW) {
list($edit_url, $copy_url, $edit_str, $copy_str,
- $edit_anchor_class)
+ $edit_anchor_class, $editCopyUrlParams)
= $this->_getModifiedLinks(
$where_clause,
$clause_is_unique, $url_sql_query
@@ -2652,7 +2651,7 @@ class Results
} // end if (1.2.1)
// 1.2.2 Delete/Kill link(s)
- list($del_url, $del_str, $js_conf)
+ list($del_url, $del_str, $js_conf, $delUrlParams)
= $this->_getDeleteAndKillLinks(
$where_clause, $clause_is_unique,
$url_sql_query, $displayParts['del_lnk'],
@@ -2668,7 +2667,7 @@ class Results
self::POSITION_LEFT, $del_url, $displayParts, $row_no,
$where_clause, $where_clause_html, $condition_array,
$edit_url, $copy_url, $edit_anchor_class,
- $edit_str, $copy_str, $del_str, $js_conf
+ $edit_str, $copy_str, $del_str, $js_conf, $editCopyUrlParams, $delUrlParams
);
} elseif ($GLOBALS['cfg']['RowActionLinks'] == self::POSITION_NONE) {
@@ -2677,7 +2676,7 @@ class Results
self::POSITION_NONE, $del_url, $displayParts, $row_no,
$where_clause, $where_clause_html, $condition_array,
$edit_url, $copy_url, $edit_anchor_class,
- $edit_str, $copy_str, $del_str, $js_conf
+ $edit_str, $copy_str, $del_str, $js_conf, $editCopyUrlParams, $delUrlParams
);
} // end if (1.3)
@@ -2711,7 +2710,7 @@ class Results
self::POSITION_RIGHT, $del_url, $displayParts, $row_no,
$where_clause, $where_clause_html, $condition_array,
$edit_url, $copy_url, $edit_anchor_class,
- $edit_str, $copy_str, $del_str, $js_conf
+ $edit_str, $copy_str, $del_str, $js_conf, $editCopyUrlParams, $delUrlParams
);
}
@@ -3327,15 +3326,9 @@ class Results
'goto' => 'sql.php',
);
- $edit_url = 'tbl_change.php'
- . Url::getCommon(
- $_url_params + array('default_action' => 'update')
- );
+ $edit_url = 'tbl_change.php';
- $copy_url = 'tbl_change.php'
- . Url::getCommon(
- $_url_params + array('default_action' => 'insert')
- );
+ $copy_url = 'tbl_change.php';
$edit_str = $this->_getActionLinkContent(
'b_edit', __('Edit')
@@ -3350,7 +3343,7 @@ class Results
$edit_anchor_class .= ' nonunique';
}
- return array($edit_url, $copy_url, $edit_str, $copy_str, $edit_anchor_class);
+ return array($edit_url, $copy_url, $edit_str, $copy_str, $edit_anchor_class, $_url_params);
} // end of the '_getModifiedLinks()' function
@@ -3401,7 +3394,7 @@ class Results
'message_to_show' => __('The row has been deleted.'),
'goto' => $lnk_goto,
);
- $del_url = 'sql.php' . Url::getCommon($_url_params);
+ $del_url = 'sql.php';
$js_conf = 'DELETE FROM ' . Sanitize::jsFormat($this->__get('table'))
. ' WHERE ' . Sanitize::jsFormat($where_clause, false)
@@ -3428,16 +3421,16 @@ class Results
'goto' => $lnk_goto,
);
- $del_url = 'sql.php' . Url::getCommon($_url_params);
+ $del_url = 'sql.php';
$js_conf = $kill;
$del_str = Util::getIcon(
'b_drop', __('Kill')
);
} else {
- $del_url = $del_str = $js_conf = null;
+ $del_url = $del_str = $js_conf = $_url_params = null;
}
- return array($del_url, $del_str, $js_conf);
+ return array($del_url, $del_str, $js_conf, $_url_params);
} // end of the '_getDeleteAndKillLinks()' function
@@ -3505,6 +3498,8 @@ class Results
* @param string $copy_str the label for copy row
* @param string $del_str the label for delete row
* @param string $js_conf text for the JS confirmation
+ * @param array $editCopyUrlParams URL parameters
+ * @param array $delUrlParams URL parameters
*
* @return string html content
*
@@ -3515,7 +3510,7 @@ class Results
private function _getPlacedLinks(
$dir, $del_url, array $displayParts, $row_no, $where_clause, $where_clause_html,
array $condition_array, $edit_url, $copy_url,
- $edit_anchor_class, $edit_str, $copy_str, $del_str, $js_conf
+ $edit_anchor_class, $edit_str, $copy_str, $del_str, $js_conf, $editCopyUrlParams, $delUrlParams
) {
if (! isset($js_conf)) {
@@ -3526,7 +3521,7 @@ class Results
$dir, $del_url, $displayParts,
$row_no, $where_clause, $where_clause_html, $condition_array,
$edit_url, $copy_url, $edit_anchor_class,
- $edit_str, $copy_str, $del_str, $js_conf
+ $edit_str, $copy_str, $del_str, $js_conf, $editCopyUrlParams, $delUrlParams
);
} // end of the '_getPlacedLinks()' function
@@ -4804,8 +4799,8 @@ class Results
/**
* Generates HTML to display the Create view in span tag
*
- * @param array $analyzed_sql_results analyzed sql results
- * @param string $url_query String with URL Parameters
+ * @param array $analyzed_sql_results analyzed sql results
+ * @param array $url_query URL Parameters
*
* @return string
*
@@ -4813,14 +4808,15 @@ class Results
*
* @see _getResultsOperations()
*/
- private function _getLinkForCreateView(array $analyzed_sql_results, $url_query)
+ private function _getLinkForCreateView(array $analyzed_sql_results, $urlParams)
{
$results_operations_html = '';
if (empty($analyzed_sql_results['procedure'])) {
$results_operations_html .= ''
. Util::linkOrButton(
- 'view_create.php' . $url_query,
+ 'view_create.php',
+ $urlParams,
Util::getIcon(
'b_view_add', __('Create view'), true
),
@@ -4867,6 +4863,7 @@ class Results
{
$html = Util::linkOrButton(
'#',
+ null,
Util::getIcon(
'b_insrow', __('Copy to clipboard'), true
),
@@ -4887,6 +4884,7 @@ class Results
{
$html = Util::linkOrButton(
'#',
+ null,
Util::getIcon(
'b_print', __('Print'), true
),
@@ -4927,7 +4925,6 @@ class Results
'printview' => '1',
'sql_query' => $this->__get('sql_query'),
);
- $url_query = Url::getCommon($_url_params);
if (!$header_shown) {
$results_operations_html .= $header;
@@ -4937,7 +4934,7 @@ class Results
// show only view and not other options
if ($only_view) {
$results_operations_html .= $this->_getLinkForCreateView(
- $analyzed_sql_results, $url_query
+ $analyzed_sql_results, $_url_params
);
if ($header_shown) {
@@ -4992,7 +4989,8 @@ class Results
}
$results_operations_html .= Util::linkOrButton(
- 'tbl_export.php' . Url::getCommon($_url_params),
+ 'tbl_export.php',
+ $_url_params,
Util::getIcon(
'b_tblexport', __('Export'), true
)
@@ -5001,7 +4999,8 @@ class Results
// prepare chart
$results_operations_html .= Util::linkOrButton(
- 'tbl_chart.php' . Url::getCommon($_url_params),
+ 'tbl_chart.php',
+ $_url_params,
Util::getIcon(
'b_chart', __('Display chart'), true
)
@@ -5021,8 +5020,8 @@ class Results
if ($geometry_found) {
$results_operations_html
.= Util::linkOrButton(
- 'tbl_gis_visualization.php'
- . Url::getCommon($_url_params),
+ 'tbl_gis_visualization.php',
+ $_url_params,
Util::getIcon(
'b_globe',
__('Visualize GIS data'),
@@ -5047,7 +5046,7 @@ class Results
}
$results_operations_html .= $this->_getLinkForCreateView(
- $analyzed_sql_results, $url_query
+ $analyzed_sql_results, $_url_params
);
if ($header_shown) {
@@ -5367,7 +5366,7 @@ class Results
$tag_params['class'] = 'ajax';
}
$result .= Util::linkOrButton(
- 'sql.php' . Url::getCommon($_url_params),
+ 'sql.php', $_url_params,
$displayedData, $tag_params
);
}
@@ -5443,6 +5442,7 @@ class Results
* Prepares an Edit link
*
* @param string $edit_url edit url
+ * @param array $urlParams URL parameters
* @param string $class css classes for td element
* @param string $edit_str text for the edit link
* @param string $where_clause where clause
@@ -5455,7 +5455,7 @@ class Results
* @see _getTableBody(), _getCheckboxAndLinks()
*/
private function _getEditLink(
- $edit_url, $class, $edit_str, $where_clause, $where_clause_html
+ $edit_url, $urlParams, $class, $edit_str, $where_clause, $where_clause_html
) {
$ret = '';
@@ -5463,7 +5463,7 @@ class Results
$ret .= '
Edit',
@@ -444,7 +451,7 @@ class ResultsTest extends PmaTestCase
. '
Edit'
. '
Copy',
'`customer`.`id` = 1',
@@ -507,7 +520,7 @@ class ResultsTest extends PmaTestCase
. '
Copy'
. '
Delete',
'DELETE FROM `Data`.`customer` WHERE `customer`.`id` = 1',
@@ -569,10 +584,8 @@ class ResultsTest extends PmaTestCase
'
Edit',
@@ -657,6 +661,21 @@ class ResultsTest extends PmaTestCase
'
Delete',
'DELETE FROM `data`.`new` WHERE `new`.`id` = 1',
+ [
+ 'db' => 'data',
+ 'table' => 'new',
+ 'where_clause' => '`new`.`id` = 1',
+ 'clause_is_unique' => true,
+ 'sql_query' => 'SELECT * FROM `new`',
+ 'goto' => 'sql.php',
+ ],
+ [
+ 'db' => 'data',
+ 'table' => 'new',
+ 'sql_query' => 'DELETE FROM `data`.`new` WHERE `new`.`id` = 1',
+ 'message_to_show' => 'The row has been deleted.',
+ 'goto' => 'tbl_sql.php',
+ ],
'
Edit'
. '
Copy'
. '
Edit',
@@ -729,13 +737,26 @@ class ResultsTest extends PmaTestCase
'
Delete',
'DELETE FROM `data`.`new` WHERE `new`.`id` = 1',
+ [
+ 'db' => 'data',
+ 'table' => 'new',
+ 'where_clause' => '`new`.`id` = 1',
+ 'clause_is_unique' => true,
+ 'sql_query' => 'SELECT * FROM `new`',
+ 'goto' => 'sql.php',
+ ],
+ [
+ 'db' => 'data',
+ 'table' => 'new',
+ 'sql_query' => 'DELETE FROM `data`.`new` WHERE `new`.`id` = 1',
+ 'message_to_show' => 'The row has been deleted.',
+ 'goto' => 'tbl_sql.php',
+ ],
'
Copy'
. '
Edit'
. '
Edit',
@@ -799,6 +811,21 @@ class ResultsTest extends PmaTestCase
'
Delete',
'DELETE FROM `data`.`new` WHERE `new`.`id` = 1',
+ [
+ 'db' => 'data',
+ 'table' => 'new',
+ 'where_clause' => '`new`.`id` = 1',
+ 'clause_is_unique' => true,
+ 'sql_query' => 'SELECT * FROM `new`',
+ 'goto' => 'sql.php',
+ ],
+ [
+ 'db' => 'data',
+ 'table' => 'new',
+ 'sql_query' => 'DELETE FROM `data`.`new` WHERE `new`.`id` = 1',
+ 'message_to_show' => 'The row has been deleted.',
+ 'goto' => 'tbl_sql.php',
+ ],
'
Delete',
null,
+ [],
+ [],
'