PageRenderTime 44ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/public/phpmyadmin/libraries/config/ConfigFile.class.php

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