diff --git a/.gsoc/todo.txt b/.gsoc/todo.txt
index e36b79397..961215a7b 100644
--- a/.gsoc/todo.txt
+++ b/.gsoc/todo.txt
@@ -2,3 +2,5 @@ restore cache'ing in phpmyadmin.css.php
make CSS for darkblue_orange
check input escaping, $cfg is no longer safe to use
+preference:
+- synchronize language, theme ThemeDefault
\ No newline at end of file
diff --git a/js/config.js b/js/config.js
index aa2e41bd0..2b07f0a7a 100644
--- a/js/config.js
+++ b/js/config.js
@@ -1,5 +1,5 @@
/**
- * Functions used in configuration forms
+ * Functions used in configuration forms and on user preferences pages
*/
// default values for fields
@@ -625,3 +625,48 @@ $(function() {
//
// END: "Restore default" and "set value" buttons
// ------------------------------------------------------------------
+
+// ------------------------------------------------------------------
+// User preferences import/export
+//
+
+$(function() {
+ var radios = $('#import_local_storage, #export_local_storage');
+ if (!radios.length) {
+ return;
+ }
+
+ // enable JavaScript dependent fields
+ radios
+ .attr('disabled', false)
+ .add('#export_text_file, #import_text_file')
+ .click(function(){
+ var show_id = $(this).attr('id');
+ var hide_id = show_id.match(/local_storage$/)
+ ? show_id.replace(/local_storage$/, 'text_file')
+ : show_id.replace(/text_file$/, 'local_storage');
+ $('#opts_'+hide_id).hide('fast');
+ $('#opts_'+show_id).show('fast');
+ });
+
+ // detect localStorage state
+ var ls_supported = window.localStorage || false;
+ var ls_exists = ls_supported ? (window.localStorage['config'] || false) : false;
+ $('.localStorage-'+(ls_supported ? 'un' : '')+'supported').hide();
+ $('.localStorage-'+(ls_exists ? 'empty' : 'exists')).hide();
+ $('form.prefs-form').change(function(){
+ var form = $(this);
+ var disabled = false;
+ if (!ls_supported) {
+ disabled = form.find('input[type=radio][value$=local_storage]').attr('checked');
+ } else if (!ls_exists && form.attr('name') == 'prefs_import'
+ && $('#import_local_storage')[0].checked) {
+ disabled = true;
+ }
+ form.find('input[type=submit]').attr('disabled', disabled);
+ });
+});
+
+//
+// END: User preferences import/export
+// ------------------------------------------------------------------
\ No newline at end of file
diff --git a/libraries/config/ConfigFile.class.php b/libraries/config/ConfigFile.class.php
index 62b23e0c4..1f501140a 100644
--- a/libraries/config/ConfigFile.class.php
+++ b/libraries/config/ConfigFile.class.php
@@ -185,6 +185,20 @@ class ConfigFile
}
}
+ /**
+ * Returns default config in a flattened array
+ *
+ * @return array
+ */
+ public function getFlatDefaultConfig()
+ {
+ $this->_flattenArrayResult = array();
+ array_walk($this->cfg, array($this, '_flattenArray'), '');
+ $flat_cfg = $this->_flattenArrayResult;
+ $this->_flattenArrayResult = null;
+ return $flat_cfg;
+ }
+
/**
* Updates config with values read from PMA_Config class
* (config will contain differences to defaults from config.defaults.php).
diff --git a/libraries/config/FormDisplay.class.php b/libraries/config/FormDisplay.class.php
index cd2d6a407..ef8592a9c 100644
--- a/libraries/config/FormDisplay.class.php
+++ b/libraries/config/FormDisplay.class.php
@@ -111,12 +111,12 @@ class FormDisplay
* Processes forms, returns true on successful save
*
* @param bool $allow_partial_save allows for partial form saving on failed validation
+ * @param bool $check_form_submit whether check for $_POST['submit_save']
* @return boolean
*/
- public function process($allow_partial_save = true)
+ public function process($allow_partial_save = true, $check_form_submit = true)
{
- // gather list of forms to save
- if (!isset($_POST['submit_save'])) {
+ if ($check_form_submit && !isset($_POST['submit_save'])) {
return false;
}
@@ -475,6 +475,11 @@ class FormDisplay
$work_path = array_search($system_path, $this->system_paths);
$key = $this->translated_paths[$work_path];
+ // skip groups
+ if ($form->getOptionType($field) == 'group') {
+ continue;
+ }
+
// ensure the value is set
if (!isset($_POST[$key])) {
// checkboxes aren't set by browsers if they're off
diff --git a/libraries/server_links.inc.php b/libraries/server_links.inc.php
index b0a78247e..34e327f88 100644
--- a/libraries/server_links.inc.php
+++ b/libraries/server_links.inc.php
@@ -92,8 +92,10 @@ $tabs['synchronize']['link'] = 'server_synchronize.php';
$tabs['synchronize']['text'] = __('Synchronize');
$tabs['settings']['icon'] = 'b_tblops.png';
-$tabs['settings']['link'] = 'prefs_forms.php';
+$tabs['settings']['link'] = 'prefs_manage.php';
$tabs['settings']['text'] = __('Settings');
+$tabs['settings']['active'] = in_array(basename($GLOBALS['PMA_PHP_SELF']),
+ array('prefs_forms.php', 'prefs_manage.php'));
echo PMA_generate_html_tabs($tabs, array());
unset($tabs);
diff --git a/libraries/user_preferences.inc.php b/libraries/user_preferences.inc.php
new file mode 100644
index 000000000..2cdb01368
--- /dev/null
+++ b/libraries/user_preferences.inc.php
@@ -0,0 +1,82 @@
+ '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');
+echo '
';
+
+// 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') {
+?>
+
+setAllowedKeys($forms_all_keys);
+$cf->updateWithGlobalConfig($GLOBALS['PMA_Config']);
+
+// todo: debug - remove
+$arr = $cf->getConfigArray();
+$arr2 = array();
+foreach ($arr as $k => $v) {
+ $arr2[] = "$k " . var_export($v, true);
+}
+$arr2 = implode(', ', $arr2);
+$arr2 .= '
Blacklist: ' . (empty($cfg['UserprefsDisallow'])
+ ? 'empty'
+ : implode(', ', $cfg['UserprefsDisallow']));
+$msg = PMA_Message::notice('Debug: ' . $arr2);
+$msg->display();
+
+if (isset($error) && $error) {
+ if (!$error instanceof PMA_Message) {
+ $error = PMA_Message::error($error);
+ }
+ $error->display();
+}
diff --git a/libraries/user_preferences.lib.php b/libraries/user_preferences.lib.php
index 8477e96f0..3b52e9bbf 100644
--- a/libraries/user_preferences.lib.php
+++ b/libraries/user_preferences.lib.php
@@ -174,4 +174,38 @@ function PMA_persist_option($path, $value, $default_value)
}
PMA_save_userprefs($prefs['config_data']);
}
+
+/**
+ * Redirects after saving new user preferences
+ *
+ * @param array $forms
+ * @param array $old_settings
+ * @param string $file_name
+ * @param array $params
+ */
+function PMA_userprefs_redirect(array $forms, array $old_settings, $file_name, $params = null)
+{
+ // 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(
+ 'saved' => 1,
+ 'refresh_left_frame' => $refresh_left_frame);
+ if (is_array($params)) {
+ $url_params = array_merge($params, $url_params);
+ }
+ PMA_sendHeaderLocation($GLOBALS['cfg']['PmaAbsoluteUri'] . $file_name
+ . PMA_generate_common_url($url_params, '&'));
+}
?>
\ No newline at end of file
diff --git a/main.php b/main.php
index 7bd80ad6d..3ff65ad91 100644
--- a/main.php
+++ b/main.php
@@ -176,7 +176,7 @@ echo '';
echo '';
echo PMA_printListItem(__('More settings'), 'li_user_preferences',
- './prefs_forms.php?' . $common_url_query);
+ './prefs_manage.php?' . $common_url_query);
echo '';
echo '';
diff --git a/prefs_forms.php b/prefs_forms.php
index a964e5147..9e3a30789 100644
--- a/prefs_forms.php
+++ b/prefs_forms.php
@@ -19,71 +19,11 @@ require_once './libraries/config/FormDisplay.class.php';
require './libraries/config/user_preferences.forms.php';
$GLOBALS['js_include'][] = 'config.js';
-
require_once './libraries/header.inc.php';
-
-// show server tabs
-require './libraries/server_links.inc.php';
-
-// build user preferences menu
-$form_param = filter_input(INPUT_GET, 'form');
-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');
-echo '';
-
-// 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') {
-?>
-
-setAllowedKeys($forms_all_keys);
-$cf->updateWithGlobalConfig($GLOBALS['PMA_Config']);
-
-// todo: debug - remove
-$arr = $cf->getConfigArray();
-$arr2 = array();
-foreach ($arr as $k => $v) {
- $arr2[] = "$k " . var_export($v, true);
-}
-$arr2 = implode(', ', $arr2);
-$arr2 .= '
Blacklist: ' . (empty($cfg['UserprefsDisallow'])
- ? 'empty'
- : implode(', ', $cfg['UserprefsDisallow']));
-$msg = PMA_Message::notice('Debug: ' . $arr2);
-$msg->display();
-
$form_display = new FormDisplay();
foreach ($forms[$form_param] as $form_name => $form) {
$form_display->registerForm($form_name, $form);
@@ -117,26 +57,8 @@ if (!$form_display->process(false)) {
$old_settings = PMA_load_userprefs();
$result = PMA_save_userprefs($cf->getConfigArray());
if ($result === true) {
- // 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,
- 'saved' => 1,
- 'refresh_left_frame' => $refresh_left_frame);
- PMA_sendHeaderLocation($cfg['PmaAbsoluteUri'] . 'prefs_forms.php'
- . PMA_generate_common_url($url_params, '&'));
+ PMA_userprefs_redirect($forms, $old_settings, 'prefs_forms.php', array(
+ 'form' => $form_param));
exit;
} else {
$result->display();
diff --git a/prefs_manage.php b/prefs_manage.php
new file mode 100644
index 000000000..663ed0ea8
--- /dev/null
+++ b/prefs_manage.php
@@ -0,0 +1,203 @@
+ $formset) {
+ foreach ($formset as $form_name => $form) {
+ $form_display->registerForm($formset_id . ': ' . $form_name, $form);
+ }
+ }
+ $cf = ConfigFile::getInstance();
+ if (empty($_POST['import_merge'])) {
+ $cf->resetConfigData();
+ }
+ $_POST_bak = $_POST;
+ foreach ($cf->getFlatDefaultConfig() as $k => $v) {
+ $_POST[str_replace('/', '-', $k)] = $v;
+ }
+ $_POST = array_merge($_POST, $config);
+ $all_ok = $form_display->process(true, false);
+ $_POST = $_POST_bak;
+
+ if (!$all_ok) {
+ // todo: ask about saving that what can be saved
+ $form_display->displayErrors();
+ die('errors');
+ }
+
+ // save settings
+ $old_settings = PMA_load_userprefs();
+ $result = PMA_save_userprefs($cf->getConfigArray());
+ if ($result === true) {
+ PMA_userprefs_redirect($forms, $old_settings, 'prefs_manage.php');
+ exit;
+ } else {
+ $error = $result;
+ }
+ }
+} else if (isset($_POST['submit_clear'])) {
+ $old_settings = PMA_load_userprefs();
+ $result = PMA_save_userprefs(array());
+ ConfigFile::getInstance()->resetConfigData();
+ if ($result === true) {
+ PMA_userprefs_redirect($forms, $old_settings, 'prefs_manage.php');
+ exit;
+ } else {
+ $error = $result;
+ }
+ exit;
+}
+
+$GLOBALS['js_include'][] = 'config.js';
+require_once './libraries/header.inc.php';
+require_once './libraries/user_preferences.inc.php';
+?>
+
+
\ 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 b8257a56a..1fbc7652a 100644
--- a/themes/original/css/theme_right.css.php
+++ b/themes/original/css/theme_right.css.php
@@ -1214,6 +1214,12 @@ code.sql {
margin-top: 0;
}
+.group-cnt {
+ padding: 0 0 0 0.5em;
+ display: inline-block;
+ width: 100%;
+}
+
/* for elements that should be revealed only via js */
.hide {
display: none;