diff --git a/libraries/Config.class.php b/libraries/Config.class.php index 7b72240ca..c290e54de 100644 --- a/libraries/Config.class.php +++ b/libraries/Config.class.php @@ -413,31 +413,38 @@ class PMA_Config * loads user preferences and merges them with current config * must be called after control connection has been estabilished * - * @uses PMA_array_merge_recursive - * @uses PMA_backquote() - * @uses PMA_DBI_fetch_value - * @uses PMA_getRelationsParam() - * @uses PMA_sqlAddslashes() * @uses $GLOBALS['cfg'] - * @uses $GLOBALS['controllink'] + * @uses $_SESSION['cache']['config_mtime'] + * @uses $_SESSION['cache']['userprefs'] + * @uses $_SESSION['cache']['userprefs_mtime'] + * @uses PMA_apply_userprefs() + * @uses PMA_array_merge_recursive() + * @uses PMA_load_userprefs() * @return boolean */ function loadUserPreferences() { - $cfgRelation = PMA_getRelationsParam(); - if (!$cfgRelation['userconfigwork']) { - return false; + // index.php should load these settings, so that phpmyadmin.css.php + // will have everything avaiable in session cache + if (!defined('PMA_MINIMUM_COMMON')) { + $config_mtime = max($this->default_source_mtime, $this->source_mtime); + // cache user preferences, use database only when needed + if (!isset($_SESSION['cache']['userprefs']) + || $_SESSION['cache']['config_mtime'] < $config_mtime) { + require_once './libraries/user_preferences.lib.php'; + require_once './libraries/config/config_functions.lib.php'; + $prefs = PMA_load_userprefs(); + $_SESSION['cache']['userprefs'] = PMA_apply_userprefs($prefs['config_data']); + $_SESSION['cache']['userprefs_mtime'] = $prefs['mtime']; + $_SESSION['cache']['config_mtime'] = $config_mtime; + } + } else if (!isset($_SESSION['cache']['userprefs'])) { + return; } - $query_table = PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['userconfig']); - $query = ' - SELECT `config_data` - FROM ' . $query_table . ' - WHERE `username` = \'' . PMA_sqlAddslashes($cfgRelation['user']) . '\''; - $config_data = PMA_DBI_fetch_value($query, 0, 0, $GLOBALS['controllink']); + $config_data = $_SESSION['cache']['userprefs']; if (!$config_data) { return false; } - $config_data = unserialize($config_data); $this->settings = PMA_array_merge_recursive($this->settings, $config_data); $GLOBALS['cfg'] = PMA_array_merge_recursive($GLOBALS['cfg'], $config_data); $this->set('user_preferences_loaded', true); @@ -572,6 +579,7 @@ class PMA_Config $fontsize + $this->source_mtime + $this->default_source_mtime + + (isset($_SESSION['cache']['userprefs_mtime']) ? $_SESSION['cache']['userprefs_mtime'] : 0) + $_SESSION['PMA_Theme']->mtime_info + $_SESSION['PMA_Theme']->filesize_info) . (isset($_SESSION['tmp_user_values']['custom_color']) ? substr($_SESSION['tmp_user_values']['custom_color'],1,6) : ''); diff --git a/libraries/common.inc.php b/libraries/common.inc.php index 8dfb7e7d3..694bcecb9 100644 --- a/libraries/common.inc.php +++ b/libraries/common.inc.php @@ -954,9 +954,6 @@ if (! defined('PMA_MINIMUM_COMMON')) { } // end server connecting - // load user preferences - $GLOBALS['PMA_Config']->loadUserPreferences(); - /** * check if profiling was requested and remember it * (note: when $cfg['ServerDefault'] = 0, constant is not defined) @@ -978,6 +975,9 @@ if (! defined('PMA_MINIMUM_COMMON')) { } } // end if !defined('PMA_MINIMUM_COMMON') +// load user preferences +$GLOBALS['PMA_Config']->loadUserPreferences(); + // remove sensitive values from session $GLOBALS['PMA_Config']->set('blowfish_secret', ''); $GLOBALS['PMA_Config']->set('Servers', ''); diff --git a/libraries/config/ConfigFile.class.php b/libraries/config/ConfigFile.class.php index acbb260f8..4eff1d13a 100644 --- a/libraries/config/ConfigFile.class.php +++ b/libraries/config/ConfigFile.class.php @@ -167,7 +167,8 @@ class ConfigFile } /** - * Flattens multidimensional array, changes indices to paths (eg. 'key/subkey') + * Flattens multidimensional array, changes indices to paths (eg. 'key/subkey'). + * Used as array_walk() callback. * * @param mixed $value * @param mixed $key @@ -385,18 +386,20 @@ class ConfigFile } /** - * Returns configuration array + * Returns configuration array (flat format) * * @return array */ public function getConfigArray() { - $c = $_SESSION[$this->id]; + $this->_flattenArrayResult = array(); + array_walk($_SESSION[$this->id], array($this, '_flattenArray'), ''); + $c = $this->_flattenArrayResult; + $this->_flattenArrayResult = null; + $persistKeys = array_diff(array_keys($this->persistKeys), array_keys($c)); foreach ($persistKeys as $k) { - if (strpos($k, '/') === false) { - $c[$k] = $this->getDefault($k); - } + $c[$k] = $this->getDefault($k); } return $c; } diff --git a/libraries/config/FormDisplay.tpl.php b/libraries/config/FormDisplay.tpl.php index 6345c2651..2ec8142cd 100644 --- a/libraries/config/FormDisplay.tpl.php +++ b/libraries/config/FormDisplay.tpl.php @@ -139,6 +139,9 @@ function display_input($path, $name, $description = '', $type, $value, $value_is Wiki + + + diff --git a/libraries/config/user_preferences.forms.php b/libraries/config/user_preferences.forms.php index a60c162d2..98c9275d8 100644 --- a/libraries/config/user_preferences.forms.php +++ b/libraries/config/user_preferences.forms.php @@ -59,7 +59,6 @@ $forms['Left_frame']['Left_databases'] = array( 'DisplayDatabasesList', 'LeftFrameDBTree', 'LeftFrameDBSeparator', - 'LeftFrameTableLevel', 'ShowTooltipAliasDB'); $forms['Left_frame']['Left_tables'] = array( 'LeftDefaultTabTable', diff --git a/libraries/user_preferences.lib.php b/libraries/user_preferences.lib.php index 74ed13dd5..71356ced7 100644 --- a/libraries/user_preferences.lib.php +++ b/libraries/user_preferences.lib.php @@ -6,9 +6,57 @@ * @package phpMyAdmin */ +/** + * Loads user preferences + * + * Returns false or an array: + * * config_data - path => value pairs + * * mtime - last modification time + * + * @uses PMA_array_merge_recursive + * @uses PMA_backquote() + * @uses PMA_DBI_fetch_single_row() + * @uses PMA_getRelationsParam() + * @uses PMA_sqlAddslashes() + * @uses $GLOBALS['controllink'] + * @return false|array + */ +function PMA_load_userprefs() +{ + $cfgRelation = PMA_getRelationsParam(); + if (!$cfgRelation['userconfigwork']) { + return false; + } + $query_table = PMA_backquote($cfgRelation['db']) . '.' . PMA_backquote($cfgRelation['userconfig']); + $query = ' + SELECT `config_data`, UNIX_TIMESTAMP(`timevalue`) ts + FROM ' . $query_table . ' + WHERE `username` = \'' . PMA_sqlAddslashes($cfgRelation['user']) . '\''; + $row = PMA_DBI_fetch_single_row($query, 'ASSOC', $GLOBALS['controllink']); + if (!$row) { + return false; + } + $config_data = unserialize($row['config_data']); + return array( + 'config_data' => $config_data, + 'mtime' => $row['ts']); +} + /** * Saves user preferences * + * @uses $GLOBALS['controllink'] + * @uses $_SESSION['cache']['userprefs'] + * @uses ConfigFile::getConfigArray() + * @uses ConfigFile::getInstance() + * @uses PMA_backquote() + * @uses PMA_DBI_fetch_value + * @uses PMA_DBI_getError() + * @uses PMA_DBI_try_query() + * @uses PMA_Message::addMessage() + * @uses PMA_Message::error() + * @uses PMA_Message::rawError() + * @uses PMA_sqlAddslashes() * @uses PMA_getRelationsParam() * @return true|PMA_Message */ @@ -37,6 +85,9 @@ function PMA_save_userprefs() VALUES (\'' . PMA_sqlAddslashes($cfgRelation['user']) . '\', \'' . PMA_sqlAddslashes($config_data) . '\')'; } + if (isset($_SESSION['cache']['userprefs'])) { + unset($_SESSION['cache']['userprefs']); + } if (!PMA_DBI_try_query($query, $GLOBALS['controllink'])) { $message = PMA_Message::error(__('Could not save configuration')); $message->addMessage('

'); @@ -45,4 +96,27 @@ function PMA_save_userprefs() } return true; } + +/** + * Returns a user preferences array filtered by $cfg['UserprefsDisallow'] + * (blacklist) and keys from user preferences form (whitelist) + * + * @uses PMA_array_write() + * @uses PMA_read_userprefs_fieldnames() + * @param array $config_data path => value pairs + * @return array + */ +function PMA_apply_userprefs(array $config_data) +{ + $cfg = array(); + $blacklist = array_flip($GLOBALS['cfg']['UserprefsDisallow']); + $whitelist = array_flip(PMA_read_userprefs_fieldnames()); + foreach ($config_data as $path => $value) { + if (!isset($whitelist[$path]) || isset($blacklist[$path])) { + continue; + } + PMA_array_write($path, $cfg, $value); + } + return $cfg; +} ?> \ No newline at end of file diff --git a/themes/original/css/theme_right.css.php b/themes/original/css/theme_right.css.php index 26f231eb0..745d11ff9 100644 --- a/themes/original/css/theme_right.css.php +++ b/themes/original/css/theme_right.css.php @@ -1309,10 +1309,17 @@ table#serverconnection_trg_local { background: transparent; } -.config-form fieldset .doc { +.config-form fieldset .doc, .config-form fieldset .disabled-notice { margin-left: 1em; } +.config-form fieldset .disabled-notice { + font-size: 80%; + text-transform: uppercase; + color: #E00; + cursor: help; +} + .config-form fieldset td { padding-top: 0.3em; padding-bottom: 0.3em; diff --git a/user_preferences.php b/user_preferences.php index dcab713fa..f67c9e7db 100644 --- a/user_preferences.php +++ b/user_preferences.php @@ -29,17 +29,39 @@ if (!isset($forms[$form_param])) { $forms_keys = array_keys($forms); $form_param = array_shift($forms_keys); } +$tabs_icons = array( + 'Features' => 'b_tblops.png', + 'Sql_queries' => 'b_sql.png', + 'Left_frame' => 'b_select.png', + 'Main_frame' => 'b_props.png', + 'Import' => 'b_import.png', + 'Export' => 'b_export.png'); foreach (array_keys($forms) as $formset) { $tabs[] = array( 'link' => 'user_preferences.php', 'text' => PMA_ifSetOr($GLOBALS['strSetupForm_' . $formset], $formset), // TODO: remove ifSetOr + 'icon' => $tabs_icons[$formset], 'active' => $formset == $form_param, - 'url_params' => array('form' => $formset) - ); + 'url_params' => array('form' => $formset)); } echo PMA_generate_html_tabs($tabs, array()); +// show "configuration saved" message and reload navigation frame if needed +if (!empty($_GET['saved'])) { + $message = PMA_Message::rawSuccess(__('Configuration has been saved')); + $message->display(); + if (isset($_GET['refresh_left_frame']) && $_GET['refresh_left_frame'] == '1') { +?> + + $v) { $arr2[] = "$k " . var_export($v, true); } $arr2 = implode(', ', $arr2); -$msg = !empty($arr2) ? PMA_Message::notice('Debug: ' . $arr2) : PMA_Message::notice('no settings'); +$arr2 .= '
Blacklist: ' . (empty($cfg['UserprefsDisallow']) + ? 'empty' + : implode(', ', $cfg['UserprefsDisallow'])); +$msg = PMA_Message::notice('Debug: ' . $arr2); $msg->display(); $form_display = new FormDisplay(); @@ -87,15 +112,30 @@ if (!$form_display->process(false)) { $form_display->display(true, true); } else { // save settings + $old_settings = PMA_load_userprefs(); $result = PMA_save_userprefs(); if ($result === true) { - $message = PMA_Message::rawSuccess(__('Configuration has been saved')); - $message->display(); + // compute differences and check whether left frame should be refreshed + $old_settings = isset($old_settings['config_data']) + ? $old_settings['config_data'] + : array(); + $new_settings = ConfigFile::getInstance()->getConfigArray(); + $diff_keys = array_keys(array_diff_assoc($old_settings, $new_settings) + + array_diff_assoc($new_settings, $old_settings)); + $check_keys = array('NaturalOrder', 'MainPageIconic', 'DefaultTabDatabase'); + $check_keys = array_merge($check_keys, $forms['Left_frame']['Left_frame'], + $forms['Left_frame']['Left_servers'], $forms['Left_frame']['Left_databases']); + $diff = array_intersect($check_keys, $diff_keys); + $refresh_left_frame = !empty($diff); + // redirect - //$url_params = array('form' => $form_param); - //PMA_sendHeaderLocation($cfg['PmaAbsoluteUri'] . 'user_preferences.php' - // . PMA_generate_common_url($url_params, '&')); - //exit; + $url_params = array( + 'form' => $form_param, + 'saved' => 1, + 'refresh_left_frame' => $refresh_left_frame); + PMA_sendHeaderLocation($cfg['PmaAbsoluteUri'] . 'user_preferences.php' + . PMA_generate_common_url($url_params, '&')); + exit; } else { $result->display(); }