2 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 * Config file management
8 namespace PMA\libraries\config
;
10 use PMA\libraries\Config
;
11 use PMA\libraries\Core
;
14 * Config file management class.
15 * Stores its data in $_SESSION
22 * Stores default PMA config from config.default.php
28 * Stores allowed values for non-standard fields
34 * Stores original PMA config, not modified by user preferences
40 * Whether we are currently working in PMA Setup context
46 * Keys which will be always written to config file
49 private $_persistKeys = array();
52 * Changes keys while updating config in {@link updateWithGlobalConfig()}
53 * or reading by {@link getConfig()} or {@link getConfigArray()}
56 private $_cfgUpdateReadMapping = array();
59 * Key filter for {@link set()}
65 * Instance id (key in $_SESSION array, separate for each server -
66 * ConfigFile{server id})
72 * Result for {@link _flattenArray()}
75 private $_flattenArrayResult;
80 * @param array $base_config base configuration read from
81 * {@link PMA\libraries\Config::$base_config},
82 * use only when not in PMA Setup
84 public function __construct(array $base_config = null)
86 // load default config values
87 $cfg = &$this->_defaultCfg
;
88 include './libraries/config.default.php';
89 $cfg['fontsize'] = '82%';
91 // load additional config information
92 $cfg_db = &$this->_cfgDb
;
93 include './libraries/config.values.php';
95 // apply default values overrides
96 if (count($cfg_db['_overrides'])) {
97 foreach ($cfg_db['_overrides'] as $path => $value) {
98 Core
::arrayWrite($path, $cfg, $value);
102 $this->_baseCfg
= $base_config;
103 $this->_isInSetup
= is_null($base_config);
104 $this->_id
= 'ConfigFile' . $GLOBALS['server'];
105 if (!isset($_SESSION[$this->_id
])) {
106 $_SESSION[$this->_id
] = array();
111 * Sets names of config options which will be placed in config file even if
112 * they are set to their default values (use only full paths)
114 * @param array $keys the names of the config options
118 public function setPersistKeys(array $keys)
120 // checking key presence is much faster than searching so move values
122 $this->_persistKeys
= array_flip($keys);
126 * Returns flipped array set by {@link setPersistKeys()}
130 public function getPersistKeysMap()
132 return $this->_persistKeys
;
136 * By default ConfigFile allows setting of all configuration keys, use
137 * this method to set up a filter on {@link set()} method
139 * @param array|null $keys array of allowed keys or null to remove filter
143 public function setAllowedKeys($keys)
145 if ($keys === null) {
146 $this->_setFilter
= null;
149 // checking key presence is much faster than searching so move values
151 $this->_setFilter
= array_flip($keys);
155 * Sets path mapping for updating config in
156 * {@link updateWithGlobalConfig()} or reading
157 * by {@link getConfig()} or {@link getConfigArray()}
159 * @param array $mapping Contains the mapping of "Server/config options"
160 * to "Server/1/config options"
164 public function setCfgUpdateReadMapping(array $mapping)
166 $this->_cfgUpdateReadMapping
= $mapping;
170 * Resets configuration data
174 public function resetConfigData()
176 $_SESSION[$this->_id
] = array();
180 * Sets configuration data (overrides old data)
182 * @param array $cfg Configuration options
186 public function setConfigData(array $cfg)
188 $_SESSION[$this->_id
] = $cfg;
194 * @param string $path Path
195 * @param mixed $value Value
196 * @param string $canonical_path Canonical path
200 public function set($path, $value, $canonical_path = null)
202 if ($canonical_path === null) {
203 $canonical_path = $this->getCanonicalPath($path);
205 // apply key whitelist
206 if ($this->_setFilter
!== null
207 && ! isset($this->_setFilter
[$canonical_path])
211 // if the path isn't protected it may be removed
212 if (isset($this->_persistKeys
[$canonical_path])) {
213 Core
::arrayWrite($path, $_SESSION[$this->_id
], $value);
217 $default_value = $this->getDefault($canonical_path);
218 $remove_path = $value === $default_value;
219 if ($this->_isInSetup
) {
220 // remove if it has a default value or is empty
221 $remove_path = $remove_path
222 ||
(empty($value) && empty($default_value));
224 // get original config values not overwritten by user
225 // preferences to allow for overwriting options set in
226 // config.inc.php with default values
227 $instance_default_value = Core
::arrayRead(
231 // remove if it has a default value and base config (config.inc.php)
232 // uses default value
233 $remove_path = $remove_path
234 && ($instance_default_value === $default_value);
237 Core
::arrayRemove($path, $_SESSION[$this->_id
]);
241 Core
::arrayWrite($path, $_SESSION[$this->_id
], $value);
245 * Flattens multidimensional array, changes indices to paths
246 * (eg. 'key/subkey').
247 * Used as array_walk() callback.
249 * @param mixed $value Value
250 * @param mixed $key Key
251 * @param mixed $prefix Prefix
255 private function _flattenArray($value, $key, $prefix)
257 // no recursion for numeric arrays
258 if (is_array($value) && !isset($value[0])) {
259 $prefix .= $key . '/';
260 array_walk($value, array($this, '_flattenArray'), $prefix);
262 $this->_flattenArrayResult
[$prefix . $key] = $value;
267 * Returns default config in a flattened array
271 public function getFlatDefaultConfig()
273 $this->_flattenArrayResult
= array();
274 array_walk($this->_defaultCfg
, array($this, '_flattenArray'), '');
275 $flat_cfg = $this->_flattenArrayResult
;
276 $this->_flattenArrayResult
= null;
281 * Updates config with values read from given array
282 * (config will contain differences to defaults from config.defaults.php).
284 * @param array $cfg Configuration
288 public function updateWithGlobalConfig(array $cfg)
290 // load config array and flatten it
291 $this->_flattenArrayResult
= array();
292 array_walk($cfg, array($this, '_flattenArray'), '');
293 $flat_cfg = $this->_flattenArrayResult
;
294 $this->_flattenArrayResult
= null;
296 // save values map for translating a few user preferences paths,
297 // should be complemented by code reading from generated config
298 // to perform inverse mapping
299 foreach ($flat_cfg as $path => $value) {
300 if (isset($this->_cfgUpdateReadMapping
[$path])) {
301 $path = $this->_cfgUpdateReadMapping
[$path];
303 $this->set($path, $value, $path);
308 * Returns config value or $default if it's not set
310 * @param string $path Path of config file
311 * @param mixed $default Default values
315 public function get($path, $default = null)
317 return Core
::arrayRead($path, $_SESSION[$this->_id
], $default);
321 * Returns default config value or $default it it's not set ie. it doesn't
322 * exist in config.default.php ($cfg) and config.values.php
323 * ($_cfg_db['_overrides'])
325 * @param string $canonical_path Canonical path
326 * @param mixed $default Default value
330 public function getDefault($canonical_path, $default = null)
332 return Core
::arrayRead($canonical_path, $this->_defaultCfg
, $default);
336 * Returns config value, if it's not set uses the default one; returns
337 * $default if the path isn't set and doesn't contain a default value
339 * @param string $path Path
340 * @param mixed $default Default value
344 public function getValue($path, $default = null)
346 $v = Core
::arrayRead($path, $_SESSION[$this->_id
], null);
350 $path = $this->getCanonicalPath($path);
351 return $this->getDefault($path, $default);
355 * Returns canonical path
357 * @param string $path Path
361 public function getCanonicalPath($path)
363 return preg_replace('#^Servers/([\d]+)/#', 'Servers/1/', $path);
367 * Returns config database entry for $path ($cfg_db in config_info.php)
369 * @param string $path path of the variable in config db
370 * @param mixed $default default value
374 public function getDbEntry($path, $default = null)
376 return Core
::arrayRead($path, $this->_cfgDb
, $default);
380 * Returns server count
384 public function getServerCount()
386 return isset($_SESSION[$this->_id
]['Servers'])
387 ?
count($_SESSION[$this->_id
]['Servers'])
392 * Returns server list
396 public function getServers()
398 return isset($_SESSION[$this->_id
]['Servers'])
399 ?
$_SESSION[$this->_id
]['Servers']
404 * Returns DSN of given server
406 * @param integer $server server index
410 public function getServerDSN($server)
412 if (!isset($_SESSION[$this->_id
]['Servers'][$server])) {
416 $path = 'Servers/' . $server;
418 if ($this->getValue("$path/auth_type") == 'config') {
419 $dsn .= $this->getValue("$path/user");
420 if (! empty($this->getValue("$path/password"))) {
425 if ($this->getValue("$path/host") != 'localhost') {
426 $dsn .= $this->getValue("$path/host");
427 $port = $this->getValue("$path/port");
432 $dsn .= $this->getValue("$path/socket");
438 * Returns server name
440 * @param int $id server index
444 public function getServerName($id)
446 if (!isset($_SESSION[$this->_id
]['Servers'][$id])) {
449 $verbose = $this->get("Servers/$id/verbose");
450 if (!empty($verbose)) {
453 $host = $this->get("Servers/$id/host");
454 return empty($host) ?
'localhost' : $host;
460 * @param int $server server index
464 public function removeServer($server)
466 if (!isset($_SESSION[$this->_id
]['Servers'][$server])) {
469 $last_server = $this->getServerCount();
471 for ($i = $server; $i < $last_server; $i++
) {
472 $_SESSION[$this->_id
]['Servers'][$i]
473 = $_SESSION[$this->_id
]['Servers'][$i +
1];
475 unset($_SESSION[$this->_id
]['Servers'][$last_server]);
477 if (isset($_SESSION[$this->_id
]['ServerDefault'])
478 && $_SESSION[$this->_id
]['ServerDefault'] == $last_server
480 unset($_SESSION[$this->_id
]['ServerDefault']);
485 * Returns configuration array (full, multidimensional format)
489 public function getConfig()
491 $c = $_SESSION[$this->_id
];
492 foreach ($this->_cfgUpdateReadMapping
as $map_to => $map_from) {
493 // if the key $c exists in $map_to
494 if (Core
::arrayRead($map_to, $c) !== null) {
495 Core
::arrayWrite($map_to, $c, Core
::arrayRead($map_from, $c));
496 Core
::arrayRemove($map_from, $c);
503 * Returns configuration array (flat format)
507 public function getConfigArray()
509 $this->_flattenArrayResult
= array();
510 array_walk($_SESSION[$this->_id
], array($this, '_flattenArray'), '');
511 $c = $this->_flattenArrayResult
;
512 $this->_flattenArrayResult
= null;
514 $persistKeys = array_diff(
515 array_keys($this->_persistKeys
),
518 foreach ($persistKeys as $k) {
519 $c[$k] = $this->getDefault($this->getCanonicalPath($k));
522 foreach ($this->_cfgUpdateReadMapping
as $map_to => $map_from) {
523 if (!isset($c[$map_from])) {
526 $c[$map_to] = $c[$map_from];
527 unset($c[$map_from]);