diff --git a/ChangeLog b/ChangeLog index 336c41e147..d49b1e6431 100644 --- a/ChangeLog +++ b/ChangeLog @@ -37,12 +37,14 @@ phpMyAdmin - ChangeLog + [setup] rfe #1452 Use type="password" for server passwords + rfe #1451 HTML5 input tag enhancements - bug #1193 Text field too small when editing a row longer than $cfg['LimitChars'] ++ Privileges tab for table level 4.0.7.0 (not yet released) - bug #3993 Sorting in database overview with statistics doesn't work - bug Handle the situation where PHP_SELF is not set +- bug #4080 Overwrite existing file not obeyed -4.0.6.0 (not yet released) +4.0.6.0 (2013-09-05) - bug #4036 Call to undefined function mb_detect_encoding (clarify the doc) - bug Missing hints when changing a column's structure - bug #4048 Cannot select foreign value in Search diff --git a/browse_foreigners.php b/browse_foreigners.php index 946c1ce2f2..81a19e9a0e 100644 --- a/browse_foreigners.php +++ b/browse_foreigners.php @@ -8,6 +8,7 @@ require_once 'libraries/common.inc.php'; require_once 'libraries/transformations.lib.php'; +require_once 'libraries/browse_foreigners.lib.php'; /** * Sets globals from $_REQUEST @@ -36,311 +37,29 @@ $header->setBodyId('body_browse_foreigners'); $cfgRelation = PMA_getRelationsParam(); $foreigners = ($cfgRelation['relwork'] ? PMA_getForeigners($db, $table) : false); - -$override_total = true; - -if (! isset($_REQUEST['pos'])) { - $pos = 0; -} else { - $pos = $_REQUEST['pos']; -} - -$foreign_limit = 'LIMIT ' . $pos . ', ' . $GLOBALS['cfg']['MaxRows'] . ' '; -if (isset($foreign_navig) && $foreign_navig == __('Show all')) { - unset($foreign_limit); -} +$foreign_limit = PMA_getForeignLimit( + isset($foreign_navig) ? $foreign_navig : null +); $foreignData = PMA_getForeignData( - $foreigners, $field, $override_total, + $foreigners, $_REQUEST['field'], true, isset($_REQUEST['foreign_filter']) ? $_REQUEST['foreign_filter'] - : '', $foreign_limit -); - -$gotopage = ''; -$showall = ''; - -if (is_array($foreignData['disp_row'])) { - - if ($cfg['ShowAll'] - && ($foreignData['the_total'] > $GLOBALS['cfg']['MaxRows']) - ) { - $showall = ''; - } - - $session_max_rows = $GLOBALS['cfg']['MaxRows']; - $pageNow = @floor($pos / $session_max_rows) + 1; - $nbTotalPage = @ceil($foreignData['the_total'] / $session_max_rows); - - if ($foreignData['the_total'] > $GLOBALS['cfg']['MaxRows']) { - $gotopage = PMA_Util::pageselector( - 'pos', - $session_max_rows, - $pageNow, - $nbTotalPage, - 200, - 5, - 5, - 20, - 10, - __('Page number:') - ); - } -} - -// When coming from Table/Zoom search -if (isset($_REQUEST['fromsearch'])) { - // In table or zoom search, input fields are named "criteriaValues" - $element_name = " var field = 'criteriaValues';\n"; -} else { - // In insert/edit, input fields are named "fields" - $element_name = " var field = 'fields';\n"; -} - -if (isset($_REQUEST['rownumber'])) { - $element_name .= " var element_name = field + '[multi_edit][" - . htmlspecialchars($_REQUEST['rownumber']) . "][' + fieldmd5 + ']';\n" - . " var null_name = field_null + '[multi_edit][" - . htmlspecialchars($_REQUEST['rownumber']) . "][' + fieldmd5 + ']';\n"; -} else { - $element_name .= "var element_name = field + '[]'"; -} -$error = PMA_jsFormat( - __( - 'The target browser window could not be updated. ' - . 'Maybe you have closed the parent window, or ' - . 'your browser\'s security settings are ' - . 'configured to block cross-window updates.' - ) + : '', + isset($foreign_limit) ? $foreign_limit : null ); -if (! isset($_REQUEST['fieldkey']) || ! is_numeric($_REQUEST['fieldkey'])) { - $fieldkey = 0; -} else { - $fieldkey = $_REQUEST['fieldkey']; -} - -$code = <<getScripts()->addCode($code); // HTML output -$output = '
' - . '
' - . PMA_URL_getHiddenInputs($db, $table) - . '' - . ''; +$html = PMA_getHtmlForRelationalFieldSelection( + $db, $table, $_REQUEST['field'], $foreignData, + isset($fieldkey) ? $fieldkey : null, + isset($data) ? $data : null +); -if (isset($_REQUEST['rownumber'])) { - $output .= ''; -} -$output .= '' - . '' - . '' - . '' - . '' - . '' . $gotopage . '' - . '' . $showall . '' - . '
' - . '
'; - -$output .= ''; - -if (is_array($foreignData['disp_row'])) { - $header = ' - - - - - - '; - - $output .= '' . $header . '' . "\n" - . '' . $header . '' . "\n" - . '' . "\n"; - - $values = array(); - $keys = array(); - foreach ($foreignData['disp_row'] as $relrow) { - if ($foreignData['foreign_display'] != false) { - $values[] = $relrow[$foreignData['foreign_display']]; - } else { - $values[] = ''; - } - - $keys[] = $relrow[$foreignData['foreign_field']]; - } - - asort($keys); - - $hcount = 0; - $odd_row = true; - $val_ordered_current_row = 0; - $val_ordered_current_equals_data = false; - $key_ordered_current_equals_data = false; - foreach ($keys as $key_ordered_current_row => $value) { - $hcount++; - - if ($cfg['RepeatCells'] > 0 && $hcount > $cfg['RepeatCells']) { - $output .= $header; - $hcount = 0; - $odd_row = true; - } - - $key_ordered_current_key = $keys[$key_ordered_current_row]; - $key_ordered_current_val = $values[$key_ordered_current_row]; - - $val_ordered_current_key = $keys[$val_ordered_current_row]; - $val_ordered_current_val = $values[$val_ordered_current_row]; - - $val_ordered_current_row++; - - if ($GLOBALS['PMA_String']->strlen($val_ordered_current_val) <= $cfg['LimitChars']) { - $val_ordered_current_val = htmlspecialchars( - $val_ordered_current_val - ); - $val_ordered_current_val_title = ''; - } else { - $val_ordered_current_val_title = htmlspecialchars( - $val_ordered_current_val - ); - $val_ordered_current_val = htmlspecialchars( - $GLOBALS['PMA_String']->substr($val_ordered_current_val, 0, $cfg['LimitChars']) - . '...' - ); - } - if ($GLOBALS['PMA_String']->strlen($key_ordered_current_val) <= $cfg['LimitChars']) { - $key_ordered_current_val = htmlspecialchars( - $key_ordered_current_val - ); - $key_ordered_current_val_title = ''; - } else { - $key_ordered_current_val_title = htmlspecialchars( - $key_ordered_current_val - ); - $key_ordered_current_val = htmlspecialchars( - $GLOBALS['PMA_String']->substr( - $key_ordered_current_val, 0, $cfg['LimitChars'] - ) . '...' - ); - } - - if (! empty($data)) { - $val_ordered_current_equals_data = $val_ordered_current_key == $data; - $key_ordered_current_equals_data = $key_ordered_current_key == $data; - } - - $output .= ''; - $odd_row = ! $odd_row; - - $output .= ''; - - $output .= ''; - - $output .= ''; - - $output .= ''; - - $output .= ''; - $output .= ''; - } // end while -} - -$output .= '' - . '
' . __('Keyname') . '' . __('Description') . '' . __('Description') . '' . __('Keyname') . '
' - . ($key_ordered_current_equals_data ? '' : '') - . '' - . htmlspecialchars($key_ordered_current_key) - . '' . ($key_ordered_current_equals_data ? '' : '') - . '' - . ($key_ordered_current_equals_data ? '' : '') - . '' - . $key_ordered_current_val . '' - . ($key_ordered_current_equals_data ? '' : '') - . '' - . '' - . ($val_ordered_current_equals_data ? '' : '') - . '' - . $val_ordered_current_val . '' - . ($val_ordered_current_equals_data ? '' : '') - . '' - . ($val_ordered_current_equals_data ? '' : '') - . '' - . htmlspecialchars($val_ordered_current_key) - . '' . ($val_ordered_current_equals_data ? '' : '') - . '
'; - -$response->addHtml($output); +$response->addHtml($html); ?> diff --git a/db_datadict.php b/db_datadict.php index 6a17a57af8..f08a5c4779 100644 --- a/db_datadict.php +++ b/db_datadict.php @@ -207,10 +207,11 @@ foreach ($tables as $table) { } $column_name = $row['Field']; + $tmp_column = $analyzed_sql[0]['create_table_fields'][$column_name]; if (PMA_MYSQL_INT_VERSION < 50025 - && ! empty($analyzed_sql[0]['create_table_fields'][$column_name]['type']) - && $analyzed_sql[0]['create_table_fields'][$column_name]['type'] == 'TIMESTAMP' - && $analyzed_sql[0]['create_table_fields'][$column_name]['timestamp_not_null'] + && ! empty($tmp_column['type']) + && $tmp_column['type'] == 'TIMESTAMP' + && $tmp_column['timestamp_not_null'] ) { // here, we have a TIMESTAMP that SHOW FULL COLUMNS reports as // having the NULL attribute, but SHOW CREATE TABLE says the diff --git a/doc/config.rst b/doc/config.rst index ca642f228a..c2bac3e002 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -1198,6 +1198,12 @@ Generic settings :default: false Whether to force using https while accessing phpMyAdmin. + + .. note:: + + In some setups (like separate SSL proxy or loadballancer) you might + have to set :config:option:`$cfg['PmaAbsoluteUri']` for correct + redirection. .. config:option:: $cfg['ExecTimeLimit'] diff --git a/examples/create_tables.sql b/examples/create_tables.sql index ca23e71c06..0ac5654dc4 100644 --- a/examples/create_tables.sql +++ b/examples/create_tables.sql @@ -262,43 +262,9 @@ CREATE TABLE IF NOT EXISTS `pma__users` ( CREATE TABLE IF NOT EXISTS `pma__usergroups` ( `usergroup` varchar(64) NOT NULL, - `server_databases` enum('Y','N') NOT NULL DEFAULT 'N', - `server_sql` enum('Y','N') NOT NULL DEFAULT 'N', - `server_status` enum('Y','N') NOT NULL DEFAULT 'N', - `server_rights` enum('Y','N') NOT NULL DEFAULT 'N', - `server_export` enum('Y','N') NOT NULL DEFAULT 'N', - `server_import` enum('Y','N') NOT NULL DEFAULT 'N', - `server_settings` enum('Y','N') NOT NULL DEFAULT 'N', - `server_binlog` enum('Y','N') NOT NULL DEFAULT 'N', - `server_replication` enum('Y','N') NOT NULL DEFAULT 'N', - `server_vars` enum('Y','N') NOT NULL DEFAULT 'N', - `server_charset` enum('Y','N') NOT NULL DEFAULT 'N', - `server_plugins` enum('Y','N') NOT NULL DEFAULT 'N', - `server_engine` enum('Y','N') NOT NULL DEFAULT 'N', - `db_structure` enum('Y','N') NOT NULL DEFAULT 'N', - `db_sql` enum('Y','N') NOT NULL DEFAULT 'N', - `db_search` enum('Y','N') NOT NULL DEFAULT 'N', - `db_qbe` enum('Y','N') NOT NULL DEFAULT 'N', - `db_export` enum('Y','N') NOT NULL DEFAULT 'N', - `db_import` enum('Y','N') NOT NULL DEFAULT 'N', - `db_operation` enum('Y','N') NOT NULL DEFAULT 'N', - `db_privileges` enum('Y','N') NOT NULL DEFAULT 'N', - `db_routines` enum('Y','N') NOT NULL DEFAULT 'N', - `db_events` enum('Y','N') NOT NULL DEFAULT 'N', - `db_triggers` enum('Y','N') NOT NULL DEFAULT 'N', - `db_tracking` enum('Y','N') NOT NULL DEFAULT 'N', - `db_designer` enum('Y','N') NOT NULL DEFAULT 'N', - `table_browse` enum('Y','N') NOT NULL DEFAULT 'N', - `table_structure` enum('Y','N') NOT NULL DEFAULT 'N', - `table_sql` enum('Y','N') NOT NULL DEFAULT 'N', - `table_search` enum('Y','N') NOT NULL DEFAULT 'N', - `table_insert` enum('Y','N') NOT NULL DEFAULT 'N', - `table_export` enum('Y','N') NOT NULL DEFAULT 'N', - `table_import` enum('Y','N') NOT NULL DEFAULT 'N', - `table_operation` enum('Y','N') NOT NULL DEFAULT 'N', - `table_tracking` enum('Y','N') NOT NULL DEFAULT 'N', - `table_triggers` enum('Y','N') NOT NULL DEFAULT 'N', - PRIMARY KEY (`usergroup`) + `tab` varchar(64) NOT NULL, + `allowed` enum('Y','N') NOT NULL DEFAULT 'N', + PRIMARY KEY (`usergroup`,`tab`,`allowed`) ) COMMENT='User groups with configured menu items' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin; diff --git a/examples/create_tables_drizzle.sql b/examples/create_tables_drizzle.sql index 4bbb9c34d5..698a15949d 100644 --- a/examples/create_tables_drizzle.sql +++ b/examples/create_tables_drizzle.sql @@ -248,43 +248,9 @@ CREATE TABLE IF NOT EXISTS `pma__users` ( CREATE TABLE IF NOT EXISTS `pma__usergroups` ( `usergroup` varchar(64) NOT NULL, - `server_databases` enum('Y','N') NOT NULL DEFAULT 'N', - `server_sql` enum('Y','N') NOT NULL DEFAULT 'N', - `server_status` enum('Y','N') NOT NULL DEFAULT 'N', - `server_rights` enum('Y','N') NOT NULL DEFAULT 'N', - `server_export` enum('Y','N') NOT NULL DEFAULT 'N', - `server_import` enum('Y','N') NOT NULL DEFAULT 'N', - `server_settings` enum('Y','N') NOT NULL DEFAULT 'N', - `server_binlog` enum('Y','N') NOT NULL DEFAULT 'N', - `server_replication` enum('Y','N') NOT NULL DEFAULT 'N', - `server_vars` enum('Y','N') NOT NULL DEFAULT 'N', - `server_charset` enum('Y','N') NOT NULL DEFAULT 'N', - `server_plugins` enum('Y','N') NOT NULL DEFAULT 'N', - `server_engine` enum('Y','N') NOT NULL DEFAULT 'N', - `db_structure` enum('Y','N') NOT NULL DEFAULT 'N', - `db_sql` enum('Y','N') NOT NULL DEFAULT 'N', - `db_search` enum('Y','N') NOT NULL DEFAULT 'N', - `db_qbe` enum('Y','N') NOT NULL DEFAULT 'N', - `db_export` enum('Y','N') NOT NULL DEFAULT 'N', - `db_import` enum('Y','N') NOT NULL DEFAULT 'N', - `db_operation` enum('Y','N') NOT NULL DEFAULT 'N', - `db_privileges` enum('Y','N') NOT NULL DEFAULT 'N', - `db_routines` enum('Y','N') NOT NULL DEFAULT 'N', - `db_events` enum('Y','N') NOT NULL DEFAULT 'N', - `db_triggers` enum('Y','N') NOT NULL DEFAULT 'N', - `db_tracking` enum('Y','N') NOT NULL DEFAULT 'N', - `db_designer` enum('Y','N') NOT NULL DEFAULT 'N', - `table_browse` enum('Y','N') NOT NULL DEFAULT 'N', - `table_structure` enum('Y','N') NOT NULL DEFAULT 'N', - `table_sql` enum('Y','N') NOT NULL DEFAULT 'N', - `table_search` enum('Y','N') NOT NULL DEFAULT 'N', - `table_insert` enum('Y','N') NOT NULL DEFAULT 'N', - `table_export` enum('Y','N') NOT NULL DEFAULT 'N', - `table_import` enum('Y','N') NOT NULL DEFAULT 'N', - `table_operation` enum('Y','N') NOT NULL DEFAULT 'N', - `table_tracking` enum('Y','N') NOT NULL DEFAULT 'N', - `table_triggers` enum('Y','N') NOT NULL DEFAULT 'N', - PRIMARY KEY (`usergroup`) + `tab` varchar(64) NOT NULL, + `allowed` enum('Y','N') NOT NULL DEFAULT 'N', + PRIMARY KEY (`usergroup`,`tab`,`allowed`) ) COMMENT='User groups with configured menu items' COLLATE utf8_bin; diff --git a/export.php b/export.php index 944b383002..bfd1a9c177 100644 --- a/export.php +++ b/export.php @@ -6,18 +6,17 @@ * @package PhpMyAdmin */ -/** - * If we are sending the export file (as opposed to just displaying it - * as text), we have to bypass the usual PMA_Response mechanism - */ -if ($_POST['output_format'] == 'sendit') { - define('PMA_BYPASS_GET_INSTANCE', 1); -} - /** * Get the variables sent or posted to this script and a core script */ if (!defined('TESTSUITE')) { + /** + * If we are sending the export file (as opposed to just displaying it + * as text), we have to bypass the usual PMA_Response mechanism + */ + if ($_POST['output_format'] == 'sendit') { + define('PMA_BYPASS_GET_INSTANCE', 1); + } require_once 'libraries/common.inc.php'; require_once 'libraries/zip.lib.php'; require_once 'libraries/plugin_interface.lib.php'; @@ -504,7 +503,7 @@ if (!defined('TESTSUITE')) { . preg_replace('@[/\\\\]@', '_', $filename); unset($message); if (file_exists($save_filename) - && ((! $quick_export && empty($onserverover)) + && ((! $quick_export && empty($_REQUEST['onserverover'])) || ($quick_export && $_REQUEST['quick_export_onserverover'] != 'saveitover')) ) { diff --git a/index.php b/index.php index 64a808df61..50cabc4fd0 100644 --- a/index.php +++ b/index.php @@ -134,10 +134,8 @@ if ($server > 0 || count($cfg['Servers']) > 1 */ if ($cfg['ServerDefault'] == 0 || (! $cfg['NavigationDisplayServers'] - && (count($cfg['Servers']) > 1 - || ($server == 0 && count($cfg['Servers']) == 1) - ) - ) + && (count($cfg['Servers']) > 1 + || ($server == 0 && count($cfg['Servers']) == 1))) ) { echo '
  • '; include_once 'libraries/select_server.lib.php'; @@ -257,7 +255,9 @@ if ($server > 0 && $GLOBALS['cfg']['ShowServerInfo']) { 'li_server_type' ); PMA_printListItem( - __('Server version:') . ' ' . PMA_MYSQL_STR_VERSION . ' - ' . PMA_MYSQL_VERSION_COMMENT, + __('Server version:') + . ' ' + . PMA_MYSQL_STR_VERSION . ' - ' . PMA_MYSQL_VERSION_COMMENT, 'li_server_version' ); PMA_printListItem( @@ -272,12 +272,12 @@ if ($server > 0 && $GLOBALS['cfg']['ShowServerInfo']) { echo '
  • '; echo ' ' . __('Server charset:') . ' ' . ' ' - . ' ' . $mysql_charsets_descriptions[$mysql_charset_map['utf-8']] . "\n" - . ' (' . $mysql_charset_map['utf-8'] . ')' . "\n" - . ' ' . "\n" - . '
  • ' . "\n"; - echo ' '; - echo ' '; + . ' ' . $mysql_charsets_descriptions[$mysql_charset_map['utf-8']] + . ' (' . $mysql_charset_map['utf-8'] . ')' + . ' ' + . ' ' + . ' ' + . ' '; } if ($GLOBALS['cfg']['ShowServerInfo'] || $GLOBALS['cfg']['ShowPhpInfo']) { @@ -290,7 +290,10 @@ if ($GLOBALS['cfg']['ShowServerInfo'] || $GLOBALS['cfg']['ShowPhpInfo']) { if ($server > 0) { $client_version_str = $GLOBALS['dbi']->getClientInfo(); if (preg_match('#\d+\.\d+\.\d+#', $client_version_str) - && in_array($GLOBALS['cfg']['Server']['extension'], array('mysql', 'mysqli')) + && in_array( + $GLOBALS['cfg']['Server']['extension'], + array('mysql', 'mysqli') + ) ) { $client_version_str = 'libmysql - ' . $client_version_str; } @@ -500,7 +503,8 @@ if ($server > 0) { ) { $msg = PMA_Message::notice(__('The phpMyAdmin configuration storage is not completely configured, some extended features have been deactivated. To find out why click %shere%s.')); $msg->addParam( - '', + '', false ); $msg->addParam('', false); @@ -587,7 +591,9 @@ if (file_exists('libraries/language_stats.inc.php')) { && $GLOBALS['language_stats'][$lang] < $cfg['TranslationWarningThreshold'] ) { trigger_error( - 'You are using an incomplete translation, please help to make it better by [a@http://www.phpmyadmin.net/home_page/improve.php#translate@_blank]contributing[/a].', + 'You are using an incomplete translation, please help to make it ' + . 'better by [a@http://www.phpmyadmin.net/home_page/improve.php' + . '#translate@_blank]contributing[/a].', E_USER_NOTICE ); } diff --git a/js/navigation.js b/js/navigation.js index bdb2b2cd7d..f1c78c689a 100644 --- a/js/navigation.js +++ b/js/navigation.js @@ -376,17 +376,19 @@ function PMA_showCurrentNavigation() var $dbItem = highlightLoadedItem( $('#pma_navigation_tree > div'), db, 'database', false, false ); - // open the table in the tree and select it - var $expander = $dbItem.children('div:first').children('a.expander'); - // if not loaded or loaded but collapsed - if (! $expander.hasClass('loaded') - || $expander.find('img').is('.ic_b_plus') - ) { - expandTreeNode($expander, function() { + if ($dbItem) { + // open the table in the tree and select it + var $expander = $dbItem.children('div:first').children('a.expander'); + // if not loaded or loaded but collapsed + if (! $expander.hasClass('loaded') + || $expander.find('img').is('.ic_b_plus') + ) { + expandTreeNode($expander, function() { + loadAndHighlightTableOrView($dbItem, table); + }); + } else { loadAndHighlightTableOrView($dbItem, table); - }); - } else { - loadAndHighlightTableOrView($dbItem, table); + } } } else if (db) { // if we are at the database level // open in the tree and select the database diff --git a/js/rte.js b/js/rte.js index 1acb9ab894..37f5d7e457 100644 --- a/js/rte.js +++ b/js/rte.js @@ -143,7 +143,8 @@ RTE.COMMON = { lineNumbers: true, matchBrackets: true, indentUnit: 4, - mode: "text/x-mysql" + mode: "text/x-mysql", + lineWrapping: true }; CodeMirror.fromTextArea($elm[0], opts); } else { @@ -331,7 +332,8 @@ RTE.COMMON = { lineNumbers: true, matchBrackets: true, indentUnit: 4, - mode: "text/x-mysql" + mode: "text/x-mysql", + lineWrapping: true }; if (typeof CodeMirror != 'undefined') { that.syntaxHiglighter = CodeMirror.fromTextArea($elm[0], opts); diff --git a/js/server_privileges.js b/js/server_privileges.js index ebfbc971c5..9128310fe8 100644 --- a/js/server_privileges.js +++ b/js/server_privileges.js @@ -575,7 +575,8 @@ AJAX.registerOnload('server_privileges.js', function () { lineNumbers: true, matchBrackets: true, indentUnit: 4, - mode: "text/x-mysql" + mode: "text/x-mysql", + lineWrapping: true } ); } @@ -593,7 +594,8 @@ AJAX.registerOnload('server_privileges.js', function () { lineNumbers: true, matchBrackets: true, indentUnit: 4, - mode: "text/x-mysql" + mode: "text/x-mysql", + lineWrapping: true } ); } @@ -629,7 +631,8 @@ AJAX.registerOnload('server_privileges.js', function () { lineNumbers: true, matchBrackets: true, indentUnit: 4, - mode: "text/x-mysql" + mode: "text/x-mysql", + lineWrapping: true } ); } diff --git a/js/server_status_monitor.js b/js/server_status_monitor.js index 2e41ac3ee9..bfdf7b6adc 100644 --- a/js/server_status_monitor.js +++ b/js/server_status_monitor.js @@ -94,7 +94,8 @@ AJAX.registerOnload('server_status_monitor.js', function () { lineNumbers: true, matchBrackets: true, indentUnit: 4, - mode: "text/x-mysql" + mode: "text/x-mysql", + lineWrapping: true } ); } diff --git a/libraries/Menu.class.php b/libraries/Menu.class.php index 5bdcaf39eb..3894b557ab 100644 --- a/libraries/Menu.class.php +++ b/libraries/Menu.class.php @@ -140,19 +140,16 @@ class PMA_Menu $userTable = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . "." . PMA_Util::backquote($GLOBALS['cfg']['Server']['users']); - $sql_query = "SELECT * FROM " . $groupTable - . " WHERE `usergroup` = (SELECT usergroup FROM " + $sql_query = "SELECT `tab` FROM " . $groupTable + . " WHERE `allowed` = 'N' AND `usergroup` = (SELECT usergroup FROM " . $userTable . " WHERE `username` = '" . PMA_Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . "')"; $result = PMA_queryAsControlUser($sql_query, false); if ($result) { - $row = $GLOBALS['dbi']->fetchAssoc($result); - foreach ($allowedTabs as $key => $tab) { - $colName = $level . '_' . $key; - if (isset($row[$colName]) && $row[$colName] == 'N') { - unset($allowedTabs[$key]); - } + while ($row = $GLOBALS['dbi']->fetchAssoc($result)) { + $tabName = substr($row['tab'], strpos($row['tab'], '_') + 1); + unset($allowedTabs[$tabName]); } } } @@ -292,6 +289,7 @@ class PMA_Menu { $db_is_information_schema = $GLOBALS['dbi']->isSystemSchema($this->_db); $tbl_is_view = PMA_Table::isView($this->_db, $this->_table); + $is_superuser = $GLOBALS['dbi']->isSuperuser(); $tabs = array(); @@ -328,14 +326,26 @@ class PMA_Menu $tabs['export']['text'] = __('Export'); /** - * Don't display "Import" and "Operations" - * for views and information_schema + * Don't display "Import" for views and information_schema */ if (! $tbl_is_view && ! $db_is_information_schema) { $tabs['import']['icon'] = 'b_tblimport.png'; $tabs['import']['link'] = 'tbl_import.php'; $tabs['import']['text'] = __('Import'); - + } + if ($is_superuser && ! PMA_DRIZZLE && ! $db_is_information_schema) { + $tabs['privileges']['link'] = 'server_privileges.php'; + $tabs['privileges']['args']['checkprivsdb'] = $this->_db; + $tabs['privileges']['args']['checkprivstable'] = $this->_table; + // stay on table view + $tabs['privileges']['args']['viewing_mode'] = 'table'; + $tabs['privileges']['text'] = __('Privileges'); + $tabs['privileges']['icon'] = 's_rights.png'; + } + /** + * Don't display "Operations" for views and information_schema + */ + if (! $tbl_is_view && ! $db_is_information_schema) { $tabs['operation']['icon'] = 'b_tblops.png'; $tabs['operation']['link'] = 'tbl_operations.php'; $tabs['operation']['text'] = __('Operations'); @@ -425,7 +435,7 @@ class PMA_Menu if ($is_superuser && ! PMA_DRIZZLE) { $tabs['privileges']['link'] = 'server_privileges.php'; - $tabs['privileges']['args']['checkprivs'] = $this->_db; + $tabs['privileges']['args']['checkprivsdb'] = $this->_db; // stay on database view $tabs['privileges']['args']['viewing_mode'] = 'db'; $tabs['privileges']['text'] = __('Privileges'); @@ -521,6 +531,7 @@ class PMA_Menu basename($GLOBALS['PMA_PHP_SELF']), array('server_privileges.php', 'server_user_groups.php') ); + $tabs['rights']['args']['viewing_mode'] = 'server'; } $tabs['export']['icon'] = 'b_export.png'; diff --git a/libraries/Util.class.php b/libraries/Util.class.php index b97f6f0edc..907478d1a4 100644 --- a/libraries/Util.class.php +++ b/libraries/Util.class.php @@ -4114,6 +4114,7 @@ class PMA_Util 'insert' => __('Insert'), 'export' => __('Export'), 'import' => __('Import'), + 'privileges' => __('Privileges'), 'operation' => __('Operations'), 'tracking' => __('Tracking'), 'triggers' => __('Triggers'), diff --git a/libraries/browse_foreigners.lib.php b/libraries/browse_foreigners.lib.php new file mode 100644 index 0000000000..f1825ae638 --- /dev/null +++ b/libraries/browse_foreigners.lib.php @@ -0,0 +1,415 @@ +' + . '
    ' + . PMA_URL_getHiddenInputs($db, $table) + . '' + . ''; + + if (isset($_REQUEST['rownumber'])) { + $output .= ''; + } + $output .= '' + . '' + . '' + . '' + . '' + . '' . $gotopage . '' + . '' . $showall . '' + . '
    ' + . ''; + + $output .= ''; + + if (is_array($foreignData['disp_row'])) { + $header = ' + + + + + + '; + + $output .= '' . $header . '' . "\n" + . '' . $header . '' . "\n" + . '' . "\n"; + + $values = array(); + $keys = array(); + foreach ($foreignData['disp_row'] as $relrow) { + if ($foreignData['foreign_display'] != false) { + $values[] = $relrow[$foreignData['foreign_display']]; + } else { + $values[] = ''; + } + + $keys[] = $relrow[$foreignData['foreign_field']]; + } + + asort($keys); + + $hcount = 0; + $odd_row = true; + $val_ordered_current_row = 0; + $val_ordered_current_equals_data = false; + $key_ordered_current_equals_data = false; + foreach ($keys as $key_ordered_current_row => $value) { + $hcount++; + + if ($GLOBALS['cfg']['RepeatCells'] > 0 + && $hcount > $GLOBALS['cfg']['RepeatCells'] + ) { + $output .= $header; + $hcount = 0; + $odd_row = true; + } + + $key_ordered_current_key = $keys[$key_ordered_current_row]; + $key_ordered_current_val = $values[$key_ordered_current_row]; + + $val_ordered_current_key = $keys[$val_ordered_current_row]; + $val_ordered_current_val = $values[$val_ordered_current_row]; + + $val_ordered_current_row++; + + $pmaString = $GLOBALS['PMA_String']; + $limitChars = $GLOBALS['cfg']['LimitChars']; + if ($pmaString->strlen($val_ordered_current_val) <= $limitChars) { + $val_ordered_current_val = htmlspecialchars( + $val_ordered_current_val + ); + $val_ordered_current_val_title = ''; + } else { + $val_ordered_current_val_title = htmlspecialchars( + $val_ordered_current_val + ); + $val_ordered_current_val = htmlspecialchars( + $pmaString->substr( + $val_ordered_current_val, 0, $limitChars + ) + . '...' + ); + } + if ($pmaString->strlen($key_ordered_current_val) <= $limitChars) { + $key_ordered_current_val = htmlspecialchars( + $key_ordered_current_val + ); + $key_ordered_current_val_title = ''; + } else { + $key_ordered_current_val_title = htmlspecialchars( + $key_ordered_current_val + ); + $key_ordered_current_val = htmlspecialchars( + $pmaString->substr( + $key_ordered_current_val, 0, $limitChars + ) . '...' + ); + } + + if (! empty($data)) { + $val_ordered_current_equals_data + = $val_ordered_current_key == $data; + $key_ordered_current_equals_data + = $key_ordered_current_key == $data; + } + + $output .= ''; + $odd_row = ! $odd_row; + + $output .= PMA_getHtmlForColumnElement( + 'class="nowrap"', $key_ordered_current_equals_data, + $key_ordered_current_key, $key_ordered_current_val, + $key_ordered_current_val_title, $field + ); + + $output .= PMA_getHtmlForColumnElement( + '', $key_ordered_current_equals_data, $key_ordered_current_key, + $key_ordered_current_val, $key_ordered_current_val_title, $field + ); + + $output .= ''; + + $output .= PMA_getHtmlForColumnElement( + '', $val_ordered_current_equals_data, $key_ordered_current_key, + $val_ordered_current_val, $val_ordered_current_val_title, $field + ); + + $output .= PMA_getHtmlForColumnElement( + 'class="nowrap"', $val_ordered_current_equals_data, + $key_ordered_current_key, $val_ordered_current_val, + $val_ordered_current_val_title, $field + ); + $output .= ''; + } // end while + } + $output .= '' + . '
    ' . __('Keyname') . '' . __('Description') . '' . __('Description') . '' . __('Keyname') . '
    ' + . '
    '; + + return $output; +} + +/** + * Function to get html for each column element + * + * @param string $cssClass class="nowrap" or '' + * @param bool $currentEqualsData whether current equals data + * @param string $currentKey current key + * @param string $currentVal current value + * @param string $currentTitle current title + * @param string $field field + * + * @return string + */ +function PMA_getHtmlForColumnElement($cssClass, $currentEqualsData, $currentKey, + $currentVal, $currentTitle, $field +) { + $output = '' + . ($currentEqualsData ? '' : '') + . ''; + if ($cssClass !== '') { + $output .= htmlspecialchars($currentKey); + } else { + $output .= $currentVal; + } + + $output .= '' . ($currentEqualsData ? '' : '') . ''; + + return $output; +} + +/** + * Function to get javascript code to handle display selection for relational + * field values + * + * @return string + */ +function PMA_getJsScriptToHandleSelectRelationalFields() +{ + $element_name = PMA_getElementName(); + $fieldkey = PMA_getFieldKey(); + $error = PMA_getJsError(); + $code = << $GLOBALS['cfg']['MaxRows']) + ) { + $showall = ''; + } + } + + return $showall; +} + +/** + * Function to get html for the goto page option + * + * @param array $foreignData foreign data + * + * @return string + */ +function PMA_getHtmlForGotoPage($foreignData) +{ + $gotopage = ''; + isset($_REQUEST['pos']) ? $pos = $_REQUEST['pos'] : $pos = 0; + if (is_array($foreignData['disp_row'])) { + $session_max_rows = $GLOBALS['cfg']['MaxRows']; + $pageNow = @floor($pos / $session_max_rows) + 1; + $nbTotalPage = @ceil($foreignData['the_total'] / $session_max_rows); + + if ($foreignData['the_total'] > $GLOBALS['cfg']['MaxRows']) { + $gotopage = PMA_Util::pageselector( + 'pos', + $session_max_rows, + $pageNow, + $nbTotalPage, + 200, + 5, + 5, + 20, + 10, + __('Page number:') + ); + } + } + return $gotopage; +} + +/** + * Function to get foreign limit + * + * @param string $foreign_navig foreign navigation + * + * @return string + */ +function PMA_getForeignLimit($foreign_navig) +{ + if (isset($foreign_navig) && $foreign_navig == __('Show all')) { + return null; + } + isset($_REQUEST['pos']) ? $pos = $_REQUEST['pos'] : $pos = 0; + return 'LIMIT ' . $pos . ', ' . $GLOBALS['cfg']['MaxRows'] . ' '; +} +?> diff --git a/libraries/build_html_for_db.lib.php b/libraries/build_html_for_db.lib.php index 466e4506cc..0fcee3101b 100644 --- a/libraries/build_html_for_db.lib.php +++ b/libraries/build_html_for_db.lib.php @@ -165,7 +165,7 @@ function PMA_buildHtmlForDb( . 'PMA_commonActions.setDb(\'' . PMA_jsFormat($current['SCHEMA_NAME']) . '\');' . '" href="server_privileges.php?' . $url_query - . '&checkprivs=' . urlencode($current['SCHEMA_NAME']) + . '&checkprivsdb=' . urlencode($current['SCHEMA_NAME']) . '" title="' . sprintf( __('Check privileges for database "%s".'), diff --git a/libraries/config.default.php b/libraries/config.default.php index f7d4465974..8bfa21a80c 100644 --- a/libraries/config.default.php +++ b/libraries/config.default.php @@ -150,35 +150,35 @@ $cfg['Servers'][$i]['ssl'] = false; * * @global string $cfg['Servers'][$i]['ssl_key'] */ -$cfg['Servers'][$i]['ssl_key'] = NULL; +$cfg['Servers'][$i]['ssl_key'] = null; /** * Path to the cert file when using SSL for connecting to the MySQL server * * @global string $cfg['Servers'][$i]['ssl_cert'] */ -$cfg['Servers'][$i]['ssl_cert'] = NULL; +$cfg['Servers'][$i]['ssl_cert'] = null; /** * Path to the CA file when using SSL for connecting to the MySQL server * * @global string $cfg['Servers'][$i]['ssl_ca'] */ -$cfg['Servers'][$i]['ssl_ca'] = NULL; +$cfg['Servers'][$i]['ssl_ca'] = null; /** * Directory containing trusted SSL CA certificates in PEM format * * @global string $cfg['Servers'][$i]['ssl_ca_path'] */ -$cfg['Servers'][$i]['ssl_ca_path'] = NULL; +$cfg['Servers'][$i]['ssl_ca_path'] = null; /** * List of allowable ciphers for SSL connections to the MySQL server * * @global string $cfg['Servers'][$i]['ssl_ciphers'] */ -$cfg['Servers'][$i]['ssl_ciphers'] = NULL; +$cfg['Servers'][$i]['ssl_ciphers'] = null; /** * How to connect to MySQL server ('tcp' or 'socket') diff --git a/libraries/config/ConfigFile.class.php b/libraries/config/ConfigFile.class.php index d1ce2d3a59..825dcd8675 100644 --- a/libraries/config/ConfigFile.class.php +++ b/libraries/config/ConfigFile.class.php @@ -128,7 +128,7 @@ class ConfigFile * Sets names of config options which will be placed in config file even if * they are set to their default values (use only full paths) * - * @param array $keys + * @param array $keys the names of the config options * * @return void */ @@ -173,7 +173,8 @@ class ConfigFile * {@link updateWithGlobalConfig()} or reading * by {@link getConfig()} or {@link getConfigArray()} * - * @param array $mapping + * @param array $mapping Contains the mapping of "Server/config options" + * to "Server/1/config options" * * @return void */ @@ -195,7 +196,7 @@ class ConfigFile /** * Sets configuration data (overrides old data) * - * @param array $cfg + * @param array $cfg Configuration options * * @return void */ diff --git a/libraries/create_addfield.lib.php b/libraries/create_addfield.lib.php index 566fdda3fd..c2abd68739 100644 --- a/libraries/create_addfield.lib.php +++ b/libraries/create_addfield.lib.php @@ -51,13 +51,13 @@ function PMA_getIndexedColumns() * Initiate the column creation statement according to the table creation or * add columns to a existing table * - * @param int $field_cnt number of columns - * @param int $field_primary primary index field - * @param boolean $is_create_tbl true if requirement is to get the statement - * for table creation + * @param int $field_cnt number of columns + * @param int &$field_primary primary index field + * @param boolean $is_create_tbl true if requirement is to get the statement + * for table creation * - * @return array $definitions An array of initial sql statements - * according to the request + * @return array $definitions An array of initial sql statements + * according to the request */ function PMA_buildColumnCreationStatement( $field_cnt, &$field_primary, $is_create_tbl = true diff --git a/libraries/insert_edit.lib.php b/libraries/insert_edit.lib.php index 8e97f480d0..2fdf31f995 100644 --- a/libraries/insert_edit.lib.php +++ b/libraries/insert_edit.lib.php @@ -2181,6 +2181,7 @@ function PMA_transformEditedValues($db, $table, * @param array $multi_edit_colummns multiple edit column array * @param array $multi_edit_columns_name multiple edit columns name array * @param array $multi_edit_funcs multiple edit functions array + * @param array $multi_edit_salt multiple edit array with encryption salt * @param array $gis_from_text_functions array that contains gis from text functions * @param string $current_value current value in the column * @param array $gis_from_wkb_functions initialy $val is $multi_edit_colummns[$key] diff --git a/libraries/navigation/NavigationHeader.class.php b/libraries/navigation/NavigationHeader.class.php index 7c9e8c3a7f..9faf605d7d 100644 --- a/libraries/navigation/NavigationHeader.class.php +++ b/libraries/navigation/NavigationHeader.class.php @@ -85,7 +85,8 @@ class PMA_NavigationHeader // prevent XSS, see PMASA-2013-9 // if link has protocol, allow only http and https if (preg_match('/^[a-z]+:/i', $logo_link) - && ! preg_match('/^https?:/i', $logo_link)) { + && ! preg_match('/^https?:/i', $logo_link) + ) { $logo_link = 'index.php'; } $retval .= ' fetchRow($result)) { @@ -1730,9 +1786,11 @@ function PMA_getListOfPrivilegesAndComparedPrivileges() /** * Get the HTML for user form and check the privileges for a particular database. * + * @param string $db database name + * * @return string $html_output */ -function PMA_getHtmlForSpecificDbPrivileges() +function PMA_getHtmlForSpecificDbPrivileges($db) { // check the privileges for a particular database. $html_output = '
    ' @@ -1743,8 +1801,8 @@ function PMA_getHtmlForSpecificDbPrivileges() . sprintf( __('Users having access to "%s"'), '' - . htmlspecialchars($_REQUEST['checkprivs']) + . PMA_URL_getCommon($db) . '">' + . htmlspecialchars($db) . '' ) . "\n" @@ -1765,27 +1823,35 @@ function PMA_getHtmlForSpecificDbPrivileges() list($list_of_privileges, $list_of_compared_privileges) = PMA_getListOfPrivilegesAndComparedPrivileges(); - $sql_query = '(SELECT ' . $list_of_privileges . ', `Db`' + $sql_query = '(SELECT ' . $list_of_privileges . ', `Db`, \'d\' AS `Type`' .' FROM `mysql`.`db`' - .' WHERE \'' . PMA_Util::sqlAddSlashes($_REQUEST['checkprivs']) + .' WHERE \'' . PMA_Util::sqlAddSlashes($db) . "'" .' LIKE `Db`' .' AND NOT (' . $list_of_compared_privileges. ')) ' .'UNION ' - .'(SELECT ' . $list_of_privileges . ', \'*\' AS `Db`' + .'(SELECT ' . $list_of_privileges . ', \'*\' AS `Db`, \'g\' AS `Type`' .' FROM `mysql`.`user` ' .' WHERE NOT (' . $list_of_compared_privileges . ')) ' .' ORDER BY `User` ASC,' .' `Host` ASC,' .' `Db` ASC;'; $res = $GLOBALS['dbi']->query($sql_query); - $row = $GLOBALS['dbi']->fetchAssoc($res); - if ($row) { - $found = true; + + $privMap = array(); + while ($row = $GLOBALS['dbi']->fetchAssoc($res)) { + $user = $row['User']; + $host = $row['Host']; + if (! isset($privMap[$user])) { + $privMap[$user] = array(); + } + if (! isset($privMap[$user][$host])) { + $privMap[$user][$host] = array(); + } + $privMap[$user][$host][] = $row; } - $html_output .= PMA_getHtmlTableBodyForSpecificDbPrivs( - $found, $row, $odd_row, $res - ); + + $html_output .= PMA_getHtmlTableBodyForSpecificDbOrTablePrivs($privMap, $db); $html_output .= '' . '' . '
    ' . "\n"; @@ -1807,11 +1873,11 @@ function PMA_getHtmlForSpecificDbPrivileges() . PMA_URL_getCommon( array( 'adduser' => 1, - 'dbname' => $_REQUEST['checkprivs'], + 'dbname' => $db, ) ) .'" rel="' - . PMA_URL_getCommon(array('checkprivs' => $_REQUEST['checkprivs'])) + . PMA_URL_getCommon(array('checkprivsdb' => $db)) . '" class="ajax" name="db_specific">' . "\n" . PMA_Util::getIcon('b_usradd.png') . ' ' . __('Add user') . '' . "\n"; @@ -1822,113 +1888,266 @@ function PMA_getHtmlForSpecificDbPrivileges() } /** - * Get HTML snippet for table body of specific database privileges + * Get the HTML for user form and check the privileges for a particular table. * - * @param boolean $found whether user found or not - * @param array $row array of rows from mysql, - * db table with list of privileges - * @param boolean $odd_row whether odd or not - * @param string $res ran sql query + * @param string $db database name + * @param string $table table name * * @return string $html_output */ -function PMA_getHtmlTableBodyForSpecificDbPrivs($found, $row, $odd_row, - $res -) { - $html_output = '' . "\n"; - if ($found) { - while (true) { - // prepare the current user - $current_privileges = array(); - $current_user = $row['User']; - $current_host = $row['Host']; - while ($row - && $current_user == $row['User'] - && $current_host == $row['Host'] - ) { - $current_privileges[] = $row; - $row = $GLOBALS['dbi']->fetchAssoc($res); - } - $html_output .= '' . "\n" - . ' 1) { - $html_output .= ' rowspan="' . count($current_privileges) . '"'; - } - $html_output .= '>' - . (empty($current_user) - ? '' . __('Any') . '' - : htmlspecialchars($current_user)) . "\n" - . '' . "\n"; +function PMA_getHtmlForSpecificTablePrivileges($db, $table) +{ + // check the privileges for a particular table. + $html_output = '
    '; + $html_output .= '
    '; + $html_output .= '' + . PMA_Util::getIcon('b_usrcheck.png') + . sprintf( + __('Users having access to "%s"'), + '' + . htmlspecialchars($db) . '.' . htmlspecialchars($table) + . '' + ) + . ''; - $html_output .= ' 1) { - $html_output .= ' rowspan="' . count($current_privileges) . '"'; - } - $html_output .= '>' - . htmlspecialchars($current_host) . '' . "\n"; - for ($i = 0; $i < count($current_privileges); $i++) { - $current = $current_privileges[$i]; - $html_output .= '' . "\n" - . ' '; - if (! isset($current['Db']) || $current['Db'] == '*') { - $html_output .= __('global'); - } elseif ( - $current['Db'] == PMA_Util::escapeMysqlWildcards( - $_REQUEST['checkprivs'] - ) - ) { - $html_output .= __('database-specific'); + $html_output .= ''; + $html_output .= '' + . '' + . '' + . '' + . '' + . '' + . '' + . '' + . ''; + + list($list_of_privileges, $list_of_compared_privileges) + = PMA_getListOfPrivilegesAndComparedPrivileges(); + $sql_query + = "(" + . " SELECT " . $list_of_privileges . ", '*' AS `Db`, 'g' AS `Type`" + . " FROM `mysql`.`user`" + . " WHERE NOT (" . $list_of_compared_privileges . ")" + . ")" + . " UNION " + . "(" + . " SELECT " . $list_of_privileges . ", `Db`, 'd' AS `Type`" + . " FROM `mysql`.`db`" + . " WHERE '" . PMA_Util::sqlAddSlashes($db) . "' LIKE `Db`" + . " AND NOT (" . $list_of_compared_privileges. ")" + . ")" + . " ORDER BY `User` ASC, `Host` ASC, `Db` ASC;"; + $res = $GLOBALS['dbi']->query($sql_query); + + $privMap = array(); + while ($row = $GLOBALS['dbi']->fetchAssoc($res)) { + $user = $row['User']; + $host = $row['Host']; + if (! isset($privMap[$user])) { + $privMap[$user] = array(); + } + if (! isset($privMap[$user][$host])) { + $privMap[$user][$host] = array(); + } + $privMap[$user][$host][] = $row; + } + + $sql_query = "SELECT `User`, `Host`, `Db`," + . " 't' AS `Type`, `Table_name`, `Table_priv`" + . " FROM `mysql`.`tables_priv`" + . " WHERE '" . PMA_Util::sqlAddSlashes($db) . "' LIKE `Db`" + . " AND '" . PMA_Util::sqlAddSlashes($table) . "' LIKE `Table_name`" + . " AND NOT (`Table_priv` = '' AND Column_priv = '')" + . " ORDER BY `User` ASC, `Host` ASC, `Db` ASC, `Table_priv` ASC;"; + $res = $GLOBALS['dbi']->query($sql_query); + + while ($row = $GLOBALS['dbi']->fetchAssoc($res)) { + $user = $row['User']; + $host = $row['Host']; + if (! isset($privMap[$user])) { + $privMap[$user] = array(); + } + if (! isset($privMap[$user][$host])) { + $privMap[$user][$host] = array(); + } + $privMap[$user][$host][] = $row; + } + + $html_output .= PMA_getHtmlTableBodyForSpecificDbOrTablePrivs( + $privMap, $db, $table + ); + $html_output .= '
    ' . __('User') . '' . __('Host') . '' . __('Type') . '' . __('Privileges') . '' . __('Grant') . '' . __('Action') . '
    '; + $html_output .= '
    '; + $html_output .= '
    '; + + // Offer to create a new user for the current database + $html_output .= '
    ' + . '' . _pgettext('Create new user', 'New') . ''; + $html_output .= '' + . PMA_Util::getIcon('b_usradd.png') . __('Add user') . ''; + + $html_output .= '
    '; + return $html_output; +} + +/** + * Get HTML snippet for table body of specific database or table privileges + * + * @param boolean $privMap priviledge map + * @param boolean $db database + * @param boolean $table table + * + * @return string $html_output + */ +function PMA_getHtmlTableBodyForSpecificDbOrTablePrivs($privMap, $db, $table = null) +{ + $html_output = ''; + $odd_row = true; + if (! empty($privMap)) { + foreach ($privMap as $current_user => $val) { + foreach ($val as $current_host => $current_privileges) { + $html_output .= ''; + + // user + $html_output .= ' 1) { + $html_output .= ' rowspan="' . count($current_privileges) . '"'; + } + $html_output .= '>'; + if (empty($current_user)) { + $html_output .= '' + . __('Any') . ''; } else { - $html_output .= __('wildcard'). ': ' - . '' . htmlspecialchars($current['Db']) . ''; + $html_output .= htmlspecialchars($current_user); } - $html_output .= "\n" - . '' . "\n"; + $html_output .= ''; - $html_output .='' . "\n" - . '' . "\n" - . '' - . join( - ',' . "\n" . ' ', - PMA_extractPrivInfo($current, true) - ) - . "\n" - . '' . "\n" - . '' . "\n"; - - $html_output .= '' . "\n" - . '' . ($current['Grant_priv'] == 'Y' ? __('Yes') : __('No')) - . "\n" - . '' . "\n" - . '' . "\n"; - $html_output .= PMA_getUserEditLink( - $current_user, $current_host, - (isset($current['Db']) && $current['Db'] != '*') - ? $current['Db'] : '' - ); - $html_output .= '' . "\n" - . ' ' . "\n"; - if (($i + 1) < count($current_privileges)) { - $html_output .= '' - . "\n"; + // host + $html_output .= ' 1) { + $html_output .= ' rowspan="' . count($current_privileges) . '"'; } + $html_output .= '>'; + $html_output .= htmlspecialchars($current_host); + $html_output .= ''; + + for ($i = 0; $i < count($current_privileges); $i++) { + $current = $current_privileges[$i]; + + // type + $html_output .= ''; + if ($current['Type'] == 'g') { + $html_output .= __('global'); + } elseif ($current['Type'] == 'd') { + if ($current['Db'] == PMA_Util::escapeMysqlWildcards($db)) { + $html_output .= __('database-specific'); + } else { + $html_output .= __('wildcard'). ': ' + . '' + . htmlspecialchars($current['Db']) + . ''; + } + } elseif ($current['Type'] == 't') { + $html_output .= __('table-specific'); + } + $html_output .= ''; + + // privileges + $html_output .= ''; + if (isset($current['Table_name'])) { + $privList = explode(',', $current['Table_priv']); + $privs = array(); + $grantsArr = PMA_getTableGrantsArray(); + foreach ($grantsArr as $grant) { + $privs[$grant[0]] = 'N'; + foreach ($privList as $priv) { + if ($grant[0] == $priv) { + $privs[$grant[0]] = 'Y'; + } + } + } + $html_output .= '' + . join( + ',', + PMA_extractPrivInfo($privs, true, true) + ) + . ''; + } else { + $html_output .= '' + . join( + ',', + PMA_extractPrivInfo($current, true, false) + ) + . ''; + } + $html_output .= ''; + + // grant + $html_output .= ''; + $containsGrant = false; + if (isset($current['Table_name'])) { + $privList = explode(',', $current['Table_priv']); + foreach ($privList as $priv) { + if ($priv == 'Grant') { + $containsGrant = true; + } + } + } else { + $containsGrant = $current['Grant_priv'] == 'Y'; + } + $html_output .= ($containsGrant ? __('Yes') : __('No')); + $html_output .= ''; + + // action + $html_output .= ''; + $specific_db = (isset($current['Db']) && $current['Db'] != '*') + ? $current['Db'] : ''; + $specific_table = (isset($current['Table_name']) + && $current['Table_name'] != '*') + ? $current['Table_name'] : ''; + $html_output .= PMA_getUserEditLink( + $current_user, + $current_host, + $specific_db, + $specific_table + ); + $html_output .= ''; + + $html_output .= ''; + if (($i + 1) < count($current_privileges)) { + $html_output .= ''; + } + } + $odd_row = ! $odd_row; } - if (empty($row)) { - break; - } - $odd_row = ! $odd_row; } } else { - $html_output .= '' . "\n" - . '' . "\n" - . ' ' . __('No user found.') . "\n" - . '' . "\n" - . '' . "\n"; + $html_output .= '' + . '' + . __('No user found.') + . '' + . ''; } - $html_output .= '' . "\n"; + $html_output .= ''; return $html_output; } @@ -3033,11 +3252,11 @@ function PMA_updatePrivileges($username, $hostname, $tablename, $dbname) // See https://sourceforge.net/p/phpmyadmin/bugs/3270/ $sql_query0 = ''; } - if (isset($sql_query1) && ! $GLOBALS['dbi']->tryQuery($sql_query1)) { + if (! empty($sql_query1) && ! $GLOBALS['dbi']->tryQuery($sql_query1)) { // this one may fail, too... $sql_query1 = ''; } - if (isset($sql_query2)) { + if (! empty($sql_query2)) { $GLOBALS['dbi']->query($sql_query2); } else { $sql_query2 = ''; @@ -3426,7 +3645,7 @@ function PMA_getHtmlHeaderForDisplayUserProperties( . __('Edit Privileges:') . ' ' . __('User'); - if (isset($dbname)) { + if (! empty($dbname)) { $html_output .= ' '; - - $usersTable = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) - . "." . PMA_Util::backquote($GLOBALS['cfg']['Server']['users']); - $sql_query = "SELECT `username` FROM " . $usersTable - . " WHERE `usergroup`='" . PMA_Util::sqlAddSlashes($userGroup) . "'"; - $result = PMA_queryAsControlUser($sql_query, false); - if ($result) { - if ($GLOBALS['dbi']->numRows($result) == 0) { - $html_output .= '

    ' - . __('No users were found belonging to this user group.') - . '

    '; - } else { - $html_output .= '' - . '' - . ''; - $i = 0; - while ($row = $GLOBALS['dbi']->fetchRow($result)) { - $i++; - $html_output .= '' - . '' - . '' - . ''; - } - $html_output .= '' - . '
    #' . __('User') . '
    ' . $i . ' ' . htmlspecialchars($row[0]) . '
    '; - } - } - $GLOBALS['dbi']->freeResult($result); - return $html_output; -} - -/** - * Returns HTML for the 'user groups' table - * - * @return string HTML for the 'user groups' table - */ -function PMA_getHtmlForUserGroupsTable() -{ - $tabs = PMA_Util::getMenuTabList(); - - $html_output = '

    ' . __('User groups') . '

    '; - $groupTable = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) - . "." . PMA_Util::backquote($GLOBALS['cfg']['Server']['usergroups']); - $sql_query = "SELECT * FROM " . $groupTable . " ORDER BY `usergroup` ASC"; - $result = PMA_queryAsControlUser($sql_query, false); - - if ($result && $GLOBALS['dbi']->numRows($result)) { - $html_output .= '
    '; - $html_output .= PMA_URL_getHiddenInputs(); - $html_output .= ''; - $html_output .= ''; - $html_output .= ''; - $html_output .= ''; - $html_output .= ''; - $html_output .= ''; - $html_output .= ''; - $html_output .= ''; - $html_output .= ''; - - $odd = true; - while ($row = $GLOBALS['dbi']->fetchAssoc($result)) { - $html_output .= ''; - $html_output .= ''; - $html_output .= ''; - $html_output .= ''; - $html_output .= ''; - - $html_output .= ''; - - $html_output .= ''; - - $odd = ! $odd; - } - - $html_output .= ''; - $html_output .= '
    ' - . __('User group') . '' . __('Server level tabs') . '' . __('Database level tabs') . '' . __('Table level tabs') . '' . __('Action') . '
    ' . htmlspecialchars($row['usergroup']) . '' . _getAllowedTabNames($row, 'server') . '' . _getAllowedTabNames($row, 'db') . '' . _getAllowedTabNames($row, 'table') . ''; - $html_output .= '' - . PMA_Util::getIcon('b_usrlist.png', __('View users')) . ''; - $html_output .= '  '; - $html_output .= '' - . PMA_Util::getIcon('b_edit.png', __('Edit')) . ''; - $html_output .= '  '; - $html_output .= '' - . PMA_Util::getIcon('b_drop.png', __('Delete')) . ''; - $html_output .= '
    '; - $html_output .= '
    '; - } - $GLOBALS['dbi']->freeResult($result); - - $html_output .= '
    '; - $html_output .= '' - . PMA_Util::getIcon('b_usradd.png') - . __('Add user group') . ''; - $html_output .= '
    '; - - return $html_output; -} - -/** - * Returns the list of allowed menu tab names - * based on a data row from usergroup table. - * - * @param array $row row of usergroup table - * @param string $level 'server', 'db' or 'table' - * - * @return string comma seperated list of allowed menu tab names - */ -function _getAllowedTabNames($row, $level) -{ - $tabNames = array(); - $tabs = PMA_Util::getMenuTabList($level); - foreach ($tabs as $tab => $tabName) { - if (! isset($row[$level . '_' . $tab]) - || $row[$level . '_' . $tab] == 'Y' - ) { - $tabNames[] = $tabName; - } - } - return implode(', ', $tabNames); -} - -/** - * Deletes a user group - * - * @param string $userGroup user group name - * - * @return void - */ -function PMA_deleteUserGroup($userGroup) -{ - $userTable = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) - . "." . PMA_Util::backquote($GLOBALS['cfg']['Server']['users']); - $groupTable = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) - . "." . PMA_Util::backquote($GLOBALS['cfg']['Server']['usergroups']); - $sql_query = "DELETE FROM " . $userTable - . " WHERE `usergroup`='" . PMA_Util::sqlAddSlashes($userGroup) . "'"; - PMA_queryAsControlUser($sql_query, true); - $sql_query = "DELETE FROM " . $groupTable - . " WHERE `usergroup`='" . PMA_Util::sqlAddSlashes($userGroup) . "'"; - PMA_queryAsControlUser($sql_query, true); -} - -/** - * Returns HTML for add/edit user group dialog - * - * @param string $userGroup name of the user group in case of editing - * - * @return string HTML for add/edit user group dialog - */ -function PMA_getHtmlToEditUserGroup($userGroup = null) -{ - $html_output = ''; - if ($userGroup == null) { - $html_output .= '

    ' . __('Add user group') . '

    '; - } else { - $html_output .= '

    ' - . sprintf(__('Edit user group: \'%s\''), htmlspecialchars($userGroup)) - . '

    '; - } - - $html_output .= '
    '; - $urlParams = array(); - if ($userGroup != null) { - $urlParams['userGroup'] = $userGroup; - $urlParams['editUserGroupSubmit'] = '1'; - } else { - $urlParams['addUserGroupSubmit'] = '1'; - } - $html_output .= PMA_URL_getHiddenInputs($urlParams); - - $html_output .= '
    '; - $html_output .= '' . __('User group menu assignments') - . '   ' - . '' - . '' - . ''; - - if ($userGroup == null) { - $html_output .= ''; - $html_output .= ''; - $html_output .= '
    '; - } - - $allowedTabs = array( - 'server' => array(), - 'db' => array(), - 'table' => array() - ); - if ($userGroup != null) { - $groupTable = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) - . "." . PMA_Util::backquote($GLOBALS['cfg']['Server']['usergroups']); - $sql_query = "SELECT * FROM " . $groupTable - . " WHERE `usergroup`='" . PMA_Util::sqlAddSlashes($userGroup) . "'"; - $result = PMA_queryAsControlUser($sql_query, false); - if ($result) { - $row = $GLOBALS['dbi']->fetchAssoc($result); - foreach ($row as $key => $value) { - if (substr($key, 0, 7) == 'server_' && $value == 'Y') { - $allowedTabs['server'][] = substr($key, 7); - } elseif (substr($key, 0, 3) == 'db_' && $value == 'Y') { - $allowedTabs['db'][] = substr($key, 3); - } elseif (substr($key, 0, 6) == 'table_' && $value == 'Y') { - $allowedTabs['table'][] = substr($key, 6); - } - } - } - $GLOBALS['dbi']->freeResult($result); - } - - $html_output .= _getTabList( - __('Server-level tabs'), 'server', $allowedTabs['server'] - ); - $html_output .= _getTabList( - __('Database-level tabs'), 'db', $allowedTabs['db'] - ); - $html_output .= _getTabList( - __('Table-level tabs'), 'table', $allowedTabs['table'] - ); - - $html_output .= '
    '; - - $html_output .= ''; - - return $html_output; -} - -/** - * Returns HTML for checkbox groups to choose - * tabs of 'server', 'db' or 'table' levels. - * - * @param string $title title of the checkbox group - * @param string $level 'server', 'db' or 'table' - * @param array $selected array of selected allowed tabs - * - * @return string HTML for checkbox groups - */ -function _getTabList($title, $level, $selected) -{ - $tabs = PMA_Util::getMenuTabList($level); - $html_output = '
    '; - $html_output .= '' . $title . ''; - foreach ($tabs as $tab => $tabName) { - $html_output .= '
    '; - $html_output .= ''; - $html_output .= ''; - $html_output .= '
    '; - } - $html_output .= '
    '; - return $html_output; -} - -/** - * Add/update a user group with allowed menu tabs. - * - * @param string $userGroup user group name - * @param boolean $new whether this is a new user group - * - * @return void - */ -function PMA_editUserGroup($userGroup, $new = false) -{ - $tabs = PMA_Util::getMenuTabList(); - $groupTable = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) - . "." . PMA_Util::backquote($GLOBALS['cfg']['Server']['usergroups']); - - $cols = ""; - $vals = ""; - $colsNvals = ""; - foreach ($tabs as $tabGroupName => $tabGroup) { - foreach ($tabs[$tabGroupName] as $tab => $tabName) { - $colName = $tabGroupName . '_' . $tab; - $cols .= "," . PMA_Util::backquote($colName); - if (isset($_REQUEST[$colName])&& $_REQUEST[$colName] == 'Y') { - $vals .= ",'Y'"; - $colsNvals .= "," . PMA_Util::backquote($colName) . "='Y'"; - } else { - $vals .= ",'N'"; - $colsNvals .= "," . PMA_Util::backquote($colName) . "='N'"; - } - } - } - if ($new) { - $sql_query = "INSERT INTO " . $groupTable - . "(`usergroup`" . $cols . ")" - . " VALUES" - . " ('" . PMA_Util::sqlAddSlashes($userGroup) . "'" . $vals . ")"; - } else { - $sql_query = "UPDATE " . $groupTable . " SET " . substr($colsNvals, 1) - . " WHERE `usergroup`='" . PMA_Util::sqlAddSlashes($userGroup) . "'"; - } - PMA_queryAsControlUser($sql_query, true); -} - /** * Get HTML snippet for display user properties * @@ -4294,44 +4177,4 @@ function PMA_getSqlQueriesForDisplayAndAddUser($username, $hostname, $password) $sql_query ); } - -/** - * Get HTML for secondary level menu tabs on 'Users' page - * - * @param string $selfUrl Url of the file - * - * @return string HTML for secondary level menu tabs on 'Users' page - */ -function PMA_getHtmlForSubMenusOnUsersPage($selfUrl) -{ - $url_params = PMA_URL_getCommon(); - $items = array( - array( - 'name' => __('Users overview'), - 'url' => 'server_privileges.php' - ), - array( - 'name' => __('User groups'), - 'url' => 'server_user_groups.php' - ) - ); - - $retval = '
      '; - foreach ($items as $item) { - $class = ''; - if ($item['url'] === $selfUrl) { - $class = ' class="tabactive"'; - } - $retval .= '
    • '; - $retval .= ''; - $retval .= $item['name']; - $retval .= ''; - $retval .= '
    • '; - } - $retval .= '
    '; - $retval .= '
    '; - - return $retval; -} ?> diff --git a/libraries/server_user_groups.lib.php b/libraries/server_user_groups.lib.php new file mode 100644 index 0000000000..7085b60b4a --- /dev/null +++ b/libraries/server_user_groups.lib.php @@ -0,0 +1,355 @@ +' + . sprintf(__('Users of \'%s\' user group'), htmlspecialchars($userGroup)) + . ''; + + $usersTable = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) + . "." . PMA_Util::backquote($GLOBALS['cfg']['Server']['users']); + $sql_query = "SELECT `username` FROM " . $usersTable + . " WHERE `usergroup`='" . PMA_Util::sqlAddSlashes($userGroup) . "'"; + $result = PMA_queryAsControlUser($sql_query, false); + if ($result) { + if ($GLOBALS['dbi']->numRows($result) == 0) { + $html_output .= '

    ' + . __('No users were found belonging to this user group.') + . '

    '; + } else { + $html_output .= '' + . '' + . ''; + $i = 0; + while ($row = $GLOBALS['dbi']->fetchRow($result)) { + $i++; + $html_output .= '' + . '' + . '' + . ''; + } + $html_output .= '' + . '
    #' . __('User') . '
    ' . $i . ' ' . htmlspecialchars($row[0]) . '
    '; + } + } + $GLOBALS['dbi']->freeResult($result); + return $html_output; +} + +/** + * Returns HTML for the 'user groups' table + * + * @return string HTML for the 'user groups' table + */ +function PMA_getHtmlForUserGroupsTable() +{ + $tabs = PMA_Util::getMenuTabList(); + + $html_output = '

    ' . __('User groups') . '

    '; + $groupTable = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) + . "." . PMA_Util::backquote($GLOBALS['cfg']['Server']['usergroups']); + $sql_query = "SELECT * FROM " . $groupTable . " ORDER BY `usergroup` ASC"; + $result = PMA_queryAsControlUser($sql_query, false); + + if ($result && $GLOBALS['dbi']->numRows($result)) { + $html_output .= ''; + $html_output .= PMA_URL_getHiddenInputs(); + $html_output .= ''; + $html_output .= ''; + $html_output .= ''; + $html_output .= ''; + $html_output .= ''; + $html_output .= ''; + $html_output .= ''; + $html_output .= ''; + $html_output .= ''; + + $odd = true; + $userGroups = array(); + while ($row = $GLOBALS['dbi']->fetchAssoc($result)) { + $groupName = $row['usergroup']; + if (! isset($userGroups[$groupName])) { + $userGroups[$groupName] = array(); + } + $userGroups[$groupName][$row['tab']] = $row['allowed']; + } + foreach ($userGroups as $groupName => $tabs) { + $html_output .= ''; + $html_output .= ''; + $html_output .= ''; + $html_output .= ''; + $html_output .= ''; + + $html_output .= ''; + + $html_output .= ''; + + $odd = ! $odd; + } + + $html_output .= ''; + $html_output .= '
    ' + . __('User group') . '' . __('Server level tabs') . '' . __('Database level tabs') . '' . __('Table level tabs') . '' . __('Action') . '
    ' . htmlspecialchars($groupName) . '' . _getAllowedTabNames($tabs, 'server') . '' . _getAllowedTabNames($tabs, 'db') . '' . _getAllowedTabNames($tabs, 'table') . ''; + $html_output .= '' + . PMA_Util::getIcon('b_usrlist.png', __('View users')) . ''; + $html_output .= '  '; + $html_output .= '' + . PMA_Util::getIcon('b_edit.png', __('Edit')) . ''; + $html_output .= '  '; + $html_output .= '' + . PMA_Util::getIcon('b_drop.png', __('Delete')) . ''; + $html_output .= '
    '; + $html_output .= '
    '; + } + $GLOBALS['dbi']->freeResult($result); + + $html_output .= '
    '; + $html_output .= '' + . PMA_Util::getIcon('b_usradd.png') + . __('Add user group') . ''; + $html_output .= '
    '; + + return $html_output; +} + +/** + * Returns the list of allowed menu tab names + * based on a data row from usergroup table. + * + * @param array $row row of usergroup table + * @param string $level 'server', 'db' or 'table' + * + * @return string comma seperated list of allowed menu tab names + */ +function _getAllowedTabNames($row, $level) +{ + $tabNames = array(); + $tabs = PMA_Util::getMenuTabList($level); + foreach ($tabs as $tab => $tabName) { + if (! isset($row[$level . '_' . $tab]) + || $row[$level . '_' . $tab] == 'Y' + ) { + $tabNames[] = $tabName; + } + } + return implode(', ', $tabNames); +} + +/** + * Deletes a user group + * + * @param string $userGroup user group name + * + * @return void + */ +function PMA_deleteUserGroup($userGroup) +{ + $userTable = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) + . "." . PMA_Util::backquote($GLOBALS['cfg']['Server']['users']); + $groupTable = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) + . "." . PMA_Util::backquote($GLOBALS['cfg']['Server']['usergroups']); + $sql_query = "DELETE FROM " . $userTable + . " WHERE `usergroup`='" . PMA_Util::sqlAddSlashes($userGroup) . "'"; + PMA_queryAsControlUser($sql_query, true); + $sql_query = "DELETE FROM " . $groupTable + . " WHERE `usergroup`='" . PMA_Util::sqlAddSlashes($userGroup) . "'"; + PMA_queryAsControlUser($sql_query, true); +} + +/** + * Returns HTML for add/edit user group dialog + * + * @param string $userGroup name of the user group in case of editing + * + * @return string HTML for add/edit user group dialog + */ +function PMA_getHtmlToEditUserGroup($userGroup = null) +{ + $html_output = ''; + if ($userGroup == null) { + $html_output .= '

    ' . __('Add user group') . '

    '; + } else { + $html_output .= '

    ' + . sprintf(__('Edit user group: \'%s\''), htmlspecialchars($userGroup)) + . '

    '; + } + + $html_output .= '
    '; + $urlParams = array(); + if ($userGroup != null) { + $urlParams['userGroup'] = $userGroup; + $urlParams['editUserGroupSubmit'] = '1'; + } else { + $urlParams['addUserGroupSubmit'] = '1'; + } + $html_output .= PMA_URL_getHiddenInputs($urlParams); + + $html_output .= '
    '; + $html_output .= '' . __('User group menu assignments') + . '   ' + . '' + . '' + . ''; + + if ($userGroup == null) { + $html_output .= ''; + $html_output .= ''; + $html_output .= '
    '; + } + + $allowedTabs = array( + 'server' => array(), + 'db' => array(), + 'table' => array() + ); + if ($userGroup != null) { + $groupTable = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) + . "." . PMA_Util::backquote($GLOBALS['cfg']['Server']['usergroups']); + $sql_query = "SELECT * FROM " . $groupTable + . " WHERE `usergroup`='" . PMA_Util::sqlAddSlashes($userGroup) . "'"; + $result = PMA_queryAsControlUser($sql_query, false); + if ($result) { + while ($row = $GLOBALS['dbi']->fetchAssoc($result)) { + $key = $row['tab']; + $value = $row['allowed']; + if (substr($key, 0, 7) == 'server_' && $value == 'Y') { + $allowedTabs['server'][] = substr($key, 7); + } elseif (substr($key, 0, 3) == 'db_' && $value == 'Y') { + $allowedTabs['db'][] = substr($key, 3); + } elseif (substr($key, 0, 6) == 'table_' && $value == 'Y') { + $allowedTabs['table'][] = substr($key, 6); + } + } + } + $GLOBALS['dbi']->freeResult($result); + } + + $html_output .= _getTabList( + __('Server-level tabs'), 'server', $allowedTabs['server'] + ); + $html_output .= _getTabList( + __('Database-level tabs'), 'db', $allowedTabs['db'] + ); + $html_output .= _getTabList( + __('Table-level tabs'), 'table', $allowedTabs['table'] + ); + + $html_output .= '
    '; + + $html_output .= ''; + + return $html_output; +} + +/** + * Returns HTML for checkbox groups to choose + * tabs of 'server', 'db' or 'table' levels. + * + * @param string $title title of the checkbox group + * @param string $level 'server', 'db' or 'table' + * @param array $selected array of selected allowed tabs + * + * @return string HTML for checkbox groups + */ +function _getTabList($title, $level, $selected) +{ + $tabs = PMA_Util::getMenuTabList($level); + $html_output = '
    '; + $html_output .= '' . $title . ''; + foreach ($tabs as $tab => $tabName) { + $html_output .= '
    '; + $html_output .= ''; + $html_output .= ''; + $html_output .= '
    '; + } + $html_output .= '
    '; + return $html_output; +} + +/** + * Add/update a user group with allowed menu tabs. + * + * @param string $userGroup user group name + * @param boolean $new whether this is a new user group + * + * @return void + */ +function PMA_editUserGroup($userGroup, $new = false) +{ + $tabs = PMA_Util::getMenuTabList(); + $groupTable = PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) + . "." . PMA_Util::backquote($GLOBALS['cfg']['Server']['usergroups']); + + if (! $new) { + $sql_query = "DELETE FROM " . $groupTable + . " WHERE `usergroup`='" . PMA_Util::sqlAddSlashes($userGroup) . "';"; + PMA_queryAsControlUser($sql_query, true); + } + + $sql_query = "INSERT INTO " . $groupTable + . "(`usergroup`, `tab`, `allowed`)" + . " VALUES "; + $first = true; + foreach ($tabs as $tabGroupName => $tabGroup) { + foreach ($tabs[$tabGroupName] as $tab => $tabName) { + if (! $first) { + $sql_query .= ", "; + } + $tabName = $tabGroupName . '_' . $tab; + $allowed = isset($_REQUEST[$tabName]) && $_REQUEST[$tabName] == 'Y'; + $sql_query .= "('" . $userGroup . "', '" . $tabName . "', '" + . ($allowed ? "Y" : "N") . "')"; + $first = false; + } + } + $sql_query .= ";"; + PMA_queryAsControlUser($sql_query, true); +} +?> \ No newline at end of file diff --git a/libraries/server_users.lib.php b/libraries/server_users.lib.php new file mode 100644 index 0000000000..57d59b7657 --- /dev/null +++ b/libraries/server_users.lib.php @@ -0,0 +1,55 @@ + __('Users overview'), + 'url' => 'server_privileges.php', + 'specific_params' => '&viewing_mode=server' + ), + array( + 'name' => __('User groups'), + 'url' => 'server_user_groups.php', + 'specific_params' => '' + ) + ); + + $retval = '
      '; + foreach ($items as $item) { + $class = ''; + if ($item['url'] === $selfUrl) { + $class = ' class="tabactive"'; + } + $retval .= '
    • '; + $retval .= ''; + $retval .= $item['name']; + $retval .= ''; + $retval .= '
    • '; + } + $retval .= '
    '; + $retval .= '
    '; + + return $retval; +} +?> \ No newline at end of file diff --git a/libraries/sql.lib.php b/libraries/sql.lib.php index 98b67c6455..6639c4ec28 100644 --- a/libraries/sql.lib.php +++ b/libraries/sql.lib.php @@ -2284,7 +2284,7 @@ function PMA_executeQueryAndSendQueryResponse($analyzed_sql_results, $sql_limit_to_append = ''; } - $reload = PMA_hasCurrentDbChanged($db); + $GLOBALS['reload'] = PMA_hasCurrentDbChanged($db); // Execute the query list($result, $num_rows, $unlim_num_rows, $profiling_results, diff --git a/libraries/tbl_columns_definition_form.lib.php b/libraries/tbl_columns_definition_form.lib.php index f141af0859..94f395dd1a 100644 --- a/libraries/tbl_columns_definition_form.lib.php +++ b/libraries/tbl_columns_definition_form.lib.php @@ -391,18 +391,18 @@ function PMA_getRowDataForRegeneration($columnNumber, $submit_fulltext) $parts = explode($_REQUEST['field_key'][$columnNumber], '_', 2); if (count($parts) == 2 && $parts[1] == $columnNumber) { switch ($parts[0]) { - case 'primary': - $columnMeta['Key'] = 'PRI'; - break; - case 'index': - $columnMeta['Key'] = 'MUL'; - break; - case 'unique': - $columnMeta['Key'] = 'UNI'; - break; - case 'fulltext': - $columnMeta['Key'] = 'FULLTEXT'; - break; + case 'primary': + $columnMeta['Key'] = 'PRI'; + break; + case 'index': + $columnMeta['Key'] = 'MUL'; + break; + case 'unique': + $columnMeta['Key'] = 'UNI'; + break; + case 'fulltext': + $columnMeta['Key'] = 'FULLTEXT'; + break; } } } diff --git a/libraries/tbl_gis_visualization.lib.php b/libraries/tbl_gis_visualization.lib.php index 6f184fc75b..2d41182ba9 100644 --- a/libraries/tbl_gis_visualization.lib.php +++ b/libraries/tbl_gis_visualization.lib.php @@ -199,9 +199,9 @@ function PMA_getHtmlForOptionsList($options, $select) $html = ''; foreach ($options as $option) { $html .= '