user_preferences.lib.php 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Functions for displaying user preferences pages
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. if (! defined('PHPMYADMIN')) {
  9. exit;
  10. }
  11. /**
  12. * Common initialization for user preferences modification pages
  13. *
  14. * @param ConfigFile $cf Config file instance
  15. *
  16. * @return void
  17. */
  18. function PMA_userprefsPageInit(ConfigFile $cf)
  19. {
  20. $forms_all_keys = PMA_readUserprefsFieldNames($GLOBALS['forms']);
  21. $cf->resetConfigData(); // start with a clean instance
  22. $cf->setAllowedKeys($forms_all_keys);
  23. $cf->setCfgUpdateReadMapping(
  24. array(
  25. 'Server/hide_db' => 'Servers/1/hide_db',
  26. 'Server/only_db' => 'Servers/1/only_db'
  27. )
  28. );
  29. $cf->updateWithGlobalConfig($GLOBALS['cfg']);
  30. }
  31. /**
  32. * Loads user preferences
  33. *
  34. * Returns an array:
  35. * * config_data - path => value pairs
  36. * * mtime - last modification time
  37. * * type - 'db' (config read from pmadb) or 'session' (read from user session)
  38. *
  39. * @return array
  40. */
  41. function PMA_loadUserprefs()
  42. {
  43. $cfgRelation = PMA_getRelationsParam();
  44. if (! $cfgRelation['userconfigwork']) {
  45. // no pmadb table, use session storage
  46. if (! isset($_SESSION['userconfig'])) {
  47. $_SESSION['userconfig'] = array(
  48. 'db' => array(),
  49. 'ts' => time());
  50. }
  51. return array(
  52. 'config_data' => $_SESSION['userconfig']['db'],
  53. 'mtime' => $_SESSION['userconfig']['ts'],
  54. 'type' => 'session');
  55. }
  56. // load configuration from pmadb
  57. $query_table = PMA_Util::backquote($cfgRelation['db']) . '.'
  58. . PMA_Util::backquote($cfgRelation['userconfig']);
  59. $query = 'SELECT `config_data`, UNIX_TIMESTAMP(`timevalue`) ts'
  60. . ' FROM ' . $query_table
  61. . ' WHERE `username` = \''
  62. . PMA_Util::sqlAddSlashes($cfgRelation['user'])
  63. . '\'';
  64. $row = $GLOBALS['dbi']->fetchSingleRow($query, 'ASSOC', $GLOBALS['controllink']);
  65. return array(
  66. 'config_data' => $row ? (array)json_decode($row['config_data']) : array(),
  67. 'mtime' => $row ? $row['ts'] : time(),
  68. 'type' => 'db');
  69. }
  70. /**
  71. * Saves user preferences
  72. *
  73. * @param array $config_array configuration array
  74. *
  75. * @return true|PMA_Message
  76. */
  77. function PMA_saveUserprefs(array $config_array)
  78. {
  79. $cfgRelation = PMA_getRelationsParam();
  80. $server = isset($GLOBALS['server'])
  81. ? $GLOBALS['server']
  82. : $GLOBALS['cfg']['ServerDefault'];
  83. $cache_key = 'server_' . $server;
  84. if (! $cfgRelation['userconfigwork']) {
  85. // no pmadb table, use session storage
  86. $_SESSION['userconfig'] = array(
  87. 'db' => $config_array,
  88. 'ts' => time());
  89. if (isset($_SESSION['cache'][$cache_key]['userprefs'])) {
  90. unset($_SESSION['cache'][$cache_key]['userprefs']);
  91. }
  92. return true;
  93. }
  94. // save configuration to pmadb
  95. $query_table = PMA_Util::backquote($cfgRelation['db']) . '.'
  96. . PMA_Util::backquote($cfgRelation['userconfig']);
  97. $query = 'SELECT `username` FROM ' . $query_table
  98. . ' WHERE `username` = \''
  99. . PMA_Util::sqlAddSlashes($cfgRelation['user'])
  100. . '\'';
  101. $has_config = $GLOBALS['dbi']->fetchValue(
  102. $query, 0, 0, $GLOBALS['controllink']
  103. );
  104. $config_data = json_encode($config_array);
  105. if ($has_config) {
  106. $query = 'UPDATE ' . $query_table
  107. . ' SET `config_data` = \''
  108. . PMA_Util::sqlAddSlashes($config_data)
  109. . '\''
  110. . ' WHERE `username` = \''
  111. . PMA_Util::sqlAddSlashes($cfgRelation['user'])
  112. . '\'';
  113. } else {
  114. $query = 'INSERT INTO ' . $query_table . ' (`username`, `config_data`) '
  115. . 'VALUES (\''
  116. . PMA_Util::sqlAddSlashes($cfgRelation['user']) . '\', \''
  117. . PMA_Util::sqlAddSlashes($config_data) . '\')';
  118. }
  119. if (isset($_SESSION['cache'][$cache_key]['userprefs'])) {
  120. unset($_SESSION['cache'][$cache_key]['userprefs']);
  121. }
  122. if (!$GLOBALS['dbi']->tryQuery($query, $GLOBALS['controllink'])) {
  123. $message = PMA_Message::error(__('Could not save configuration'));
  124. $message->addMessage('<br /><br />');
  125. $message->addMessage(
  126. PMA_Message::rawError(
  127. $GLOBALS['dbi']->getError($GLOBALS['controllink'])
  128. )
  129. );
  130. return $message;
  131. }
  132. return true;
  133. }
  134. /**
  135. * Returns a user preferences array filtered by $cfg['UserprefsDisallow']
  136. * (blacklist) and keys from user preferences form (whitelist)
  137. *
  138. * @param array $config_data path => value pairs
  139. *
  140. * @return array
  141. */
  142. function PMA_applyUserprefs(array $config_data)
  143. {
  144. $cfg = array();
  145. $blacklist = array_flip($GLOBALS['cfg']['UserprefsDisallow']);
  146. if (!$GLOBALS['cfg']['UserprefsDeveloperTab']) {
  147. // disallow everything in the Developers tab
  148. $blacklist['Error_Handler/display'] = true;
  149. $blacklist['Error_Handler/gather'] = true;
  150. $blacklist['DBG/sql'] = true;
  151. }
  152. $whitelist = array_flip(PMA_readUserprefsFieldNames());
  153. // whitelist some additional fields which are custom handled
  154. $whitelist['ThemeDefault'] = true;
  155. $whitelist['fontsize'] = true;
  156. $whitelist['lang'] = true;
  157. $whitelist['collation_connection'] = true;
  158. $whitelist['Server/hide_db'] = true;
  159. $whitelist['Server/only_db'] = true;
  160. foreach ($config_data as $path => $value) {
  161. if (! isset($whitelist[$path]) || isset($blacklist[$path])) {
  162. continue;
  163. }
  164. PMA_arrayWrite($path, $cfg, $value);
  165. }
  166. return $cfg;
  167. }
  168. /**
  169. * Reads user preferences field names
  170. *
  171. * @param array|null $forms Forms
  172. *
  173. * @return array
  174. */
  175. function PMA_readUserprefsFieldNames(array $forms = null)
  176. {
  177. static $names;
  178. if (defined('TESTSUITE')) {
  179. $names = null;
  180. }
  181. // return cached results
  182. if ($names !== null) {
  183. return $names;
  184. }
  185. if (is_null($forms)) {
  186. $forms = array();
  187. include 'libraries/config/user_preferences.forms.php';
  188. }
  189. $names = array();
  190. foreach ($forms as $formset) {
  191. foreach ($formset as $form) {
  192. foreach ($form as $k => $v) {
  193. $names[] = is_int($k) ? $v : $k;
  194. }
  195. }
  196. }
  197. return $names;
  198. }
  199. /**
  200. * Updates one user preferences option (loads and saves to database).
  201. *
  202. * No validation is done!
  203. *
  204. * @param string $path configuration
  205. * @param mixed $value value
  206. * @param mixed $default_value default value
  207. *
  208. * @return void
  209. */
  210. function PMA_persistOption($path, $value, $default_value)
  211. {
  212. $prefs = PMA_loadUserprefs();
  213. if ($value === $default_value) {
  214. if (isset($prefs['config_data'][$path])) {
  215. unset($prefs['config_data'][$path]);
  216. } else {
  217. return;
  218. }
  219. } else {
  220. $prefs['config_data'][$path] = $value;
  221. }
  222. PMA_saveUserprefs($prefs['config_data']);
  223. }
  224. /**
  225. * Redirects after saving new user preferences
  226. *
  227. * @param string $file_name Filename
  228. * @param array $params URL parameters
  229. * @param string $hash Hash value
  230. *
  231. * @return void
  232. */
  233. function PMA_userprefsRedirect($file_name,
  234. $params = null, $hash = null
  235. ) {
  236. // redirect
  237. $url_params = array('saved' => 1);
  238. if (is_array($params)) {
  239. $url_params = array_merge($params, $url_params);
  240. }
  241. if ($hash) {
  242. $hash = '#' . urlencode($hash);
  243. }
  244. PMA_sendHeaderLocation(
  245. $GLOBALS['cfg']['PmaAbsoluteUri'] . $file_name
  246. . PMA_URL_getCommon($url_params, '&') . $hash
  247. );
  248. }
  249. /**
  250. * Shows form which allows to quickly load
  251. * settings stored in browser's local storage
  252. *
  253. * @return string
  254. */
  255. function PMA_userprefsAutoloadGetHeader()
  256. {
  257. $retval = '';
  258. if (isset($_REQUEST['prefs_autoload'])
  259. && $_REQUEST['prefs_autoload'] == 'hide'
  260. ) {
  261. $_SESSION['userprefs_autoload'] = true;
  262. } else {
  263. $script_name = basename(basename($GLOBALS['PMA_PHP_SELF']));
  264. $return_url = htmlspecialchars(
  265. $script_name . '?' . http_build_query($_GET, '', '&')
  266. );
  267. $retval .= '<div id="prefs_autoload" class="notice" style="display:none">';
  268. $retval .= '<form action="prefs_manage.php" method="post">';
  269. $retval .= PMA_URL_getHiddenInputs();
  270. $retval .= '<input type="hidden" name="json" value="" />';
  271. $retval .= '<input type="hidden" name="submit_import" value="1" />';
  272. $retval .= '<input type="hidden" name="return_url" value="'
  273. . $return_url . '" />';
  274. $retval .= __(
  275. 'Your browser has phpMyAdmin configuration for this domain. '
  276. . 'Would you like to import it for current session?'
  277. );
  278. $retval .= '<br />';
  279. $retval .= '<a href="#yes">' . __('Yes') . '</a>';
  280. $retval .= ' / ';
  281. $retval .= '<a href="#no">' . __('No') . '</a>';
  282. $retval .= '</form>';
  283. $retval .= '</div>';
  284. }
  285. return $retval;
  286. }
  287. ?>