PageRenderTime 26ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/pma/libraries/config/ConfigFile.class.php

https://bitbucket.org/pavolve/masterskayaludmila
PHP | 503 lines | 243 code | 46 blank | 214 comment | 36 complexity | c1b7686bec30ae1fbafcf0ec62cf0de7 MD5 | raw file
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Config file management
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. /**
  9. * Config file management class.
  10. * Stores its data in $_SESSION
  11. *
  12. * @package phpMyAdmin
  13. */
  14. class ConfigFile
  15. {
  16. /**
  17. * Stores default PMA config from config.default.php
  18. * @var array
  19. */
  20. private $cfg;
  21. /**
  22. * Stores original PMA_Config object, not modified by user preferences
  23. * @var PMA_Config
  24. */
  25. private $orgCfgObject;
  26. /**
  27. * Stores allowed values for non-standard fields
  28. * @var array
  29. */
  30. private $cfgDb;
  31. /**
  32. * Keys which will be always written to config file
  33. * @var array
  34. */
  35. private $persistKeys = array();
  36. /**
  37. * Changes keys while updating config in {@link updateWithGlobalConfig()} or reading
  38. * by {@link getConfig()} or {@link getConfigArray()}
  39. * @var array
  40. */
  41. private $cfgUpdateReadMapping = array();
  42. /**
  43. * Key filter for {@link set()}
  44. * @var array|null
  45. */
  46. private $setFilter;
  47. /**
  48. * Instance id (key in $_SESSION array, separate for each server - ConfigFile{server id})
  49. * @var string
  50. */
  51. private $id;
  52. /**
  53. * Result for {@link _flattenArray()}
  54. * @var array
  55. */
  56. private $_flattenArrayResult;
  57. /**
  58. * ConfigFile instance
  59. * @var ConfigFile
  60. */
  61. private static $_instance;
  62. /**
  63. * Private constructor, use {@link getInstance()}
  64. *
  65. */
  66. private function __construct()
  67. {
  68. // load default config values
  69. $cfg = &$this->cfg;
  70. include './libraries/config.default.php';
  71. $cfg['fontsize'] = '82%';
  72. // create PMA_Config to read config.inc.php values
  73. $this->orgCfgObject = new PMA_Config(CONFIG_FILE);
  74. // load additional config information
  75. $cfg_db = &$this->cfgDb;
  76. include './libraries/config.values.php';
  77. // apply default values overrides
  78. if (count($cfg_db['_overrides'])) {
  79. foreach ($cfg_db['_overrides'] as $path => $value) {
  80. PMA_array_write($path, $cfg, $value);
  81. }
  82. }
  83. $this->id = 'ConfigFile' . $GLOBALS['server'];
  84. if (!isset($_SESSION[$this->id])) {
  85. $_SESSION[$this->id] = array();
  86. }
  87. }
  88. /**
  89. * Returns class instance
  90. *
  91. * @return ConfigFile
  92. */
  93. public static function getInstance()
  94. {
  95. if (is_null(self::$_instance)) {
  96. self::$_instance = new ConfigFile();
  97. }
  98. return self::$_instance;
  99. }
  100. /**
  101. * Returns PMA_Config without user preferences applied
  102. *
  103. * @return PMA_Config
  104. */
  105. public function getOrgConfigObj()
  106. {
  107. return $this->orgCfgObject;
  108. }
  109. /**
  110. * Sets names of config options which will be placed in config file even if they are set
  111. * to their default values (use only full paths)
  112. *
  113. * @param array $keys
  114. */
  115. public function setPersistKeys($keys)
  116. {
  117. // checking key presence is much faster than searching so move values to keys
  118. $this->persistKeys = array_flip($keys);
  119. }
  120. /**
  121. * Returns flipped array set by {@link setPersistKeys()}
  122. *
  123. * @return array
  124. */
  125. public function getPersistKeysMap()
  126. {
  127. return $this->persistKeys;
  128. }
  129. /**
  130. * By default ConfigFile allows setting of all configuration keys, use this method
  131. * to set up a filter on {@link set()} method
  132. *
  133. * @param array|null $keys array of allowed keys or null to remove filter
  134. */
  135. public function setAllowedKeys($keys)
  136. {
  137. if ($keys === null) {
  138. $this->setFilter = null;
  139. return;
  140. }
  141. // checking key presence is much faster than searching so move values to keys
  142. $this->setFilter = array_flip($keys);
  143. }
  144. /**
  145. * Sets path mapping for updating config in {@link updateWithGlobalConfig()} or reading
  146. * by {@link getConfig()} or {@link getConfigArray()}
  147. * @var array
  148. */
  149. public function setCfgUpdateReadMapping(array $mapping)
  150. {
  151. $this->cfgUpdateReadMapping = $mapping;
  152. }
  153. /**
  154. * Resets configuration data
  155. */
  156. public function resetConfigData()
  157. {
  158. $_SESSION[$this->id] = array();
  159. }
  160. /**
  161. * Sets configuration data (overrides old data)
  162. *
  163. * @param array $cfg
  164. */
  165. public function setConfigData(array $cfg)
  166. {
  167. $_SESSION[$this->id] = $cfg;
  168. }
  169. /**
  170. * Sets config value
  171. *
  172. * @param string $path
  173. * @param mixed $value
  174. * @param string $canonical_path
  175. */
  176. public function set($path, $value, $canonical_path = null)
  177. {
  178. if ($canonical_path === null) {
  179. $canonical_path = $this->getCanonicalPath($path);
  180. }
  181. // apply key whitelist
  182. if ($this->setFilter !== null && !isset($this->setFilter[$canonical_path])) {
  183. return;
  184. }
  185. // remove if the path isn't protected and it's empty or has a default value
  186. if (!isset($this->persistKeys[$canonical_path])) {
  187. $default_value = $this->getDefault($canonical_path);
  188. // we need oryginal config values not overwritten by user preferences
  189. // to allow for overwriting options set in config.inc.php with default values
  190. $instance_default_value = PMA_array_read($canonical_path, $this->orgCfgObject->settings);
  191. if (($value === $default_value && (defined('PMA_SETUP') || $instance_default_value === $default_value))
  192. || (empty($value) && empty($default_value) && (defined('PMA_SETUP') || empty($current_global)))) {
  193. PMA_array_remove($path, $_SESSION[$this->id]);
  194. return;
  195. }
  196. }
  197. PMA_array_write($path, $_SESSION[$this->id], $value);
  198. }
  199. /**
  200. * Flattens multidimensional array, changes indices to paths (eg. 'key/subkey').
  201. * Used as array_walk() callback.
  202. *
  203. * @param mixed $value
  204. * @param mixed $key
  205. * @param mixed $prefix
  206. */
  207. private function _flattenArray($value, $key, $prefix)
  208. {
  209. // no recursion for numeric arrays
  210. if (is_array($value) && !isset($value[0])) {
  211. $prefix .= $key . '/';
  212. array_walk($value, array($this, '_flattenArray'), $prefix);
  213. } else {
  214. $this->_flattenArrayResult[$prefix . $key] = $value;
  215. }
  216. }
  217. /**
  218. * Returns default config in a flattened array
  219. *
  220. * @return array
  221. */
  222. public function getFlatDefaultConfig()
  223. {
  224. $this->_flattenArrayResult = array();
  225. array_walk($this->cfg, array($this, '_flattenArray'), '');
  226. $flat_cfg = $this->_flattenArrayResult;
  227. $this->_flattenArrayResult = null;
  228. return $flat_cfg;
  229. }
  230. /**
  231. * Updates config with values read from given array
  232. * (config will contain differences to defaults from config.defaults.php).
  233. *
  234. * @param array $cfg
  235. */
  236. public function updateWithGlobalConfig(array $cfg)
  237. {
  238. // load config array and flatten it
  239. $this->_flattenArrayResult = array();
  240. array_walk($cfg, array($this, '_flattenArray'), '');
  241. $flat_cfg = $this->_flattenArrayResult;
  242. $this->_flattenArrayResult = null;
  243. // save values
  244. // map for translating a few user preferences paths, should be complemented
  245. // by code reading from generated config to perform inverse mapping
  246. foreach ($flat_cfg as $path => $value) {
  247. if (isset($this->cfgUpdateReadMapping[$path])) {
  248. $path = $this->cfgUpdateReadMapping[$path];
  249. }
  250. $this->set($path, $value, $path);
  251. }
  252. }
  253. /**
  254. * Returns config value or $default if it's not set
  255. *
  256. * @param string $path
  257. * @param mixed $default
  258. * @return mixed
  259. */
  260. public function get($path, $default = null)
  261. {
  262. return PMA_array_read($path, $_SESSION[$this->id], $default);
  263. }
  264. /**
  265. * Returns default config value or $default it it's not set ie. it doesn't
  266. * exist in config.default.php ($cfg) and config.values.php
  267. * ($_cfg_db['_overrides'])
  268. *
  269. * @param string $canonical_path
  270. * @param mixed $default
  271. * @return mixed
  272. */
  273. public function getDefault($canonical_path, $default = null)
  274. {
  275. return PMA_array_read($canonical_path, $this->cfg, $default);
  276. }
  277. /**
  278. * Returns config value, if it's not set uses the default one; returns
  279. * $default if the path isn't set and doesn't contain a default value
  280. *
  281. * @param string $path
  282. * @param mixed $default
  283. * @return mixed
  284. */
  285. public function getValue($path, $default = null)
  286. {
  287. $v = PMA_array_read($path, $_SESSION[$this->id], null);
  288. if ($v !== null) {
  289. return $v;
  290. }
  291. $path = $this->getCanonicalPath($path);
  292. return $this->getDefault($path, $default);
  293. }
  294. /**
  295. * Returns canonical path
  296. *
  297. * @param string $path
  298. * @return string
  299. */
  300. public function getCanonicalPath($path) {
  301. return preg_replace('#^Servers/([\d]+)/#', 'Servers/1/', $path);
  302. }
  303. /**
  304. * Returns config database entry for $path ($cfg_db in config_info.php)
  305. *
  306. * @param string $path
  307. * @param mixed $default
  308. * @return mixed
  309. */
  310. public function getDbEntry($path, $default = null)
  311. {
  312. return PMA_array_read($path, $this->cfgDb, $default);
  313. }
  314. /**
  315. * Returns server count
  316. *
  317. * @return int
  318. */
  319. public function getServerCount()
  320. {
  321. return isset($_SESSION[$this->id]['Servers'])
  322. ? count($_SESSION[$this->id]['Servers'])
  323. : 0;
  324. }
  325. /**
  326. * Returns server list
  327. *
  328. * @return array|null
  329. */
  330. public function getServers()
  331. {
  332. return isset($_SESSION[$this->id]['Servers'])
  333. ? $_SESSION[$this->id]['Servers']
  334. : null;
  335. }
  336. /**
  337. * Returns DSN of given server
  338. *
  339. * @param integer $server
  340. * @return string
  341. */
  342. function getServerDSN($server)
  343. {
  344. if (!isset($_SESSION[$this->id]['Servers'][$server])) {
  345. return '';
  346. }
  347. $path = 'Servers/' . $server;
  348. $dsn = $this->getValue("$path/extension") . '://';
  349. if ($this->getValue("$path/auth_type") == 'config') {
  350. $dsn .= $this->getValue("$path/user");
  351. if (!$this->getValue("$path/nopassword")) {
  352. $dsn .= ':***';
  353. }
  354. $dsn .= '@';
  355. }
  356. if ($this->getValue("$path/connect_type") == 'tcp') {
  357. $dsn .= $this->getValue("$path/host");
  358. $port = $this->getValue("$path/port");
  359. if ($port) {
  360. $dsn .= ':' . $port;
  361. }
  362. } else {
  363. $dsn .= $this->getValue("$path/socket");
  364. }
  365. return $dsn;
  366. }
  367. /**
  368. * Returns server name
  369. *
  370. * @param int $id
  371. * @return string
  372. */
  373. public function getServerName($id)
  374. {
  375. if (!isset($_SESSION[$this->id]['Servers'][$id])) {
  376. return '';
  377. }
  378. $verbose = $this->get("Servers/$id/verbose");
  379. if (!empty($verbose)) {
  380. return $verbose;
  381. }
  382. $host = $this->get("Servers/$id/host");
  383. return empty($host) ? 'localhost' : $host;
  384. }
  385. /**
  386. * Removes server
  387. *
  388. * @param int $server
  389. */
  390. public function removeServer($server)
  391. {
  392. if (!isset($_SESSION[$this->id]['Servers'][$server])) {
  393. return;
  394. }
  395. $last_server = $this->getServerCount();
  396. for ($i = $server; $i < $last_server; $i++) {
  397. $_SESSION[$this->id]['Servers'][$i] = $_SESSION[$this->id]['Servers'][$i+1];
  398. }
  399. unset($_SESSION[$this->id]['Servers'][$last_server]);
  400. if (isset($_SESSION[$this->id]['ServerDefault'])
  401. && $_SESSION[$this->id]['ServerDefault'] >= 0) {
  402. unset($_SESSION[$this->id]['ServerDefault']);
  403. }
  404. }
  405. /**
  406. * Returns config file path, relative to phpMyAdmin's root path
  407. *
  408. * @return string
  409. */
  410. public function getFilePath()
  411. {
  412. // Load paths
  413. if (!defined('SETUP_CONFIG_FILE')) {
  414. include_once './libraries/vendor_config.php';
  415. }
  416. return SETUP_CONFIG_FILE;
  417. }
  418. /**
  419. * Returns configuration array (full, multidimensional format)
  420. *
  421. * @return array
  422. */
  423. public function getConfig()
  424. {
  425. $c = $_SESSION[$this->id];
  426. foreach ($this->cfgUpdateReadMapping as $map_to => $map_from) {
  427. PMA_array_write($map_to, $c, PMA_array_read($map_from, $c));
  428. PMA_array_remove($map_from, $c);
  429. }
  430. return $c;
  431. }
  432. /**
  433. * Returns configuration array (flat format)
  434. *
  435. * @return array
  436. */
  437. public function getConfigArray()
  438. {
  439. $this->_flattenArrayResult = array();
  440. array_walk($_SESSION[$this->id], array($this, '_flattenArray'), '');
  441. $c = $this->_flattenArrayResult;
  442. $this->_flattenArrayResult = null;
  443. $persistKeys = array_diff(array_keys($this->persistKeys), array_keys($c));
  444. foreach ($persistKeys as $k) {
  445. $c[$k] = $this->getDefault($k);
  446. }
  447. foreach ($this->cfgUpdateReadMapping as $map_to => $map_from) {
  448. if (!isset($c[$map_from])) {
  449. continue;
  450. }
  451. $c[$map_to] = $c[$map_from];
  452. unset($c[$map_from]);
  453. }
  454. return $c;
  455. }
  456. }
  457. ?>