diff --git a/ChangeLog b/ChangeLog index 4aa479788b..586ac0906e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,6 +30,9 @@ phpMyAdmin - ChangeLog - issue #12473 Code can throw unhandled exception - issue #12550 Do not try to keep alive session even after expiry - issue #12512 Fixed rendering BBCode links in setup +- issue #12518 Fixed copy of table with generated columns +- issue #12221 Fixed export of table with generated columns +- issue #12320 Copying a user does not copy usergroup - issue #12272 Adding a new row with default enum goes to no selection when you want to add more then 2 rows 4.6.4 (2016-08-16) diff --git a/doc/setup.rst b/doc/setup.rst index 66eb0469e4..474a93e866 100644 --- a/doc/setup.rst +++ b/doc/setup.rst @@ -756,6 +756,7 @@ are always ways to make your installation more secure: * Serve phpMyAdmin on HTTPS only. Preferably, you should use HSTS as well, so that you're protected from protocol downgrade attacks. +* Remove the ``test`` directory from phpMyAdmin, unless you are developing and need test suite. * Remove the ``setup`` directory from phpMyAdmin, you will probably not use it after the initial setup. * Properly choose an authentication method - :ref:`cookie` diff --git a/js/functions.js b/js/functions.js index 9fa445f314..a6587bbad1 100644 --- a/js/functions.js +++ b/js/functions.js @@ -906,7 +906,7 @@ AJAX.registerOnload('functions.js', function () { var remaining = PMA_commonParams.get('LoginCookieValidity') - _idleSecondsCounter; if (remaining > 5) { // max value for setInterval() function - var interval = min(remaining * 1000, Math.pow(2, 31) - 1); + var interval = Math.min(remaining * 1000, Math.pow(2, 31) - 1); updateTimeout = window.setTimeout(UpdateIdleTime, interval); } else if (remaining > 0) { // We're close to session expiry diff --git a/libraries/Table.php b/libraries/Table.php index ccc9df8731..d3f8032c60 100644 --- a/libraries/Table.php +++ b/libraries/Table.php @@ -1017,10 +1017,17 @@ class Table $GLOBALS['dbi']->query($sql_set_mode); $GLOBALS['sql_query'] .= "\n\n" . $sql_set_mode . ';'; - $sql_insert_data = 'INSERT INTO ' . $target - . ' SELECT * FROM ' . $source; - $GLOBALS['dbi']->query($sql_insert_data); - $GLOBALS['sql_query'] .= "\n\n" . $sql_insert_data . ';'; + $_old_table = new Table($source_table, $source_db); + $nonGeneratedCols = $_old_table->getNonGeneratedColumns(true); + if (count($nonGeneratedCols) > 0) { + $sql_insert_data = 'INSERT INTO ' . $target . '(' + . implode(', ', $nonGeneratedCols) + . ') SELECT ' . implode(', ', $nonGeneratedCols) + . ' FROM ' . $source; + + $GLOBALS['dbi']->query($sql_insert_data); + $GLOBALS['sql_query'] .= "\n\n" . $sql_insert_data . ';'; + } } PMA_getRelationsParam(); @@ -1484,6 +1491,40 @@ class Table } } + /** + * Get non-generated columns in table + * + * @param bool $backquoted whether to quote name with backticks `` + * + * @return array + */ + public function getNonGeneratedColumns($backquoted = true) + { + $columns_meta_query = 'SHOW COLUMNS FROM ' . $this->getFullName(true); + $ret = array(); + + $columns_meta_query_result = $this->_dbi->fetchResult( + $columns_meta_query + ); + + if ($columns_meta_query_result + && $columns_meta_query_result !== false + ) { + foreach ($columns_meta_query_result as $column) { + $value = $column['Field']; + if ($backquoted === true) { + $value = Util::backquote($value); + } + + if (strpos($column['Extra'], 'GENERATED') === false) { + array_push($ret, $value); + } + } + } + + return $ret; + } + /** * Return UI preferences for this table from phpMyAdmin database. * diff --git a/libraries/export.lib.php b/libraries/export.lib.php index 20567d9698..e432d1ceb8 100644 --- a/libraries/export.lib.php +++ b/libraries/export.lib.php @@ -682,8 +682,13 @@ function PMA_exportDatabase( && in_array($table, $table_data) && ! ($is_view) ) { - $local_query = 'SELECT * FROM ' . PMA\libraries\Util::backquote($db) + $tableObj = new PMA\libraries\Table($table, $db); + $nonGeneratedCols = $tableObj->getNonGeneratedColumns(true); + + $local_query = 'SELECT ' . implode(', ', $nonGeneratedCols) + . ' FROM ' . PMA\libraries\Util::backquote($db) . '.' . PMA\libraries\Util::backquote($table); + if (! $export_plugin->exportData( $db, $table, $crlf, $err_url, $local_query, $aliases )) { @@ -862,7 +867,12 @@ function PMA_exportTable( $local_query = $sql_query . $add_query; $GLOBALS['dbi']->selectDb($db); } else { - $local_query = 'SELECT * FROM ' . PMA\libraries\Util::backquote($db) + // Data is exported only for Non-generated columns + $tableObj = new PMA\libraries\Table($table, $db); + $nonGeneratedCols = $tableObj->getNonGeneratedColumns(true); + + $local_query = 'SELECT ' . implode(', ', $nonGeneratedCols) + . ' FROM ' . PMA\libraries\Util::backquote($db) . '.' . PMA\libraries\Util::backquote($table) . $add_query; } if (! $export_plugin->exportData( diff --git a/libraries/server_privileges.lib.php b/libraries/server_privileges.lib.php index 059595e619..932d7a3d13 100644 --- a/libraries/server_privileges.lib.php +++ b/libraries/server_privileges.lib.php @@ -2951,6 +2951,33 @@ function PMA_getUserGroupCount() return $user_group_count; } +/** + * Returns name of user group that user is part of + * + * @param string $username User name + * + * @return mixed usergroup if found or null if not found + */ +function PMA_getUserGroupForUser($username) +{ + $cfgRelation = PMA_getRelationsParam(); + $user_table = Util::backquote($cfgRelation['db']) + . '.' . Util::backquote($cfgRelation['users']); + $sql_query = 'SELECT `usergroup` FROM ' . $user_table + . ' WHERE `username` = \'' . $username . '\'' + . ' LIMIT 1'; + + $usergroup = $GLOBALS['dbi']->fetchValue( + $sql_query, 0, 0, $GLOBALS['controllink'] + ); + + if ($usergroup === false) { + return null; + } + + return $usergroup; +} + /** * This function return the extra data array for the ajax behavior * @@ -3129,8 +3156,15 @@ function PMA_getChangeLoginInformationHtmlForm($username, $hostname) . '' . "\n" . '' . "\n" - . '