PageRenderTime 40ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/cakephp/core/StaticConfigTrait.php

http://github.com/josegonzalez/git-php
PHP | 381 lines | 166 code | 36 blank | 179 comment | 21 complexity | 043cedffdd43d3484bd52396faf22a10 MD5 | raw file
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @link https://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.0
  13. * @license https://opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Core;
  16. use BadMethodCallException;
  17. use InvalidArgumentException;
  18. use LogicException;
  19. /**
  20. * A trait that provides a set of static methods to manage configuration
  21. * for classes that provide an adapter facade or need to have sets of
  22. * configuration data registered and manipulated.
  23. *
  24. * Implementing objects are expected to declare a static `$_dsnClassMap` property.
  25. */
  26. trait StaticConfigTrait
  27. {
  28. /**
  29. * Configuration sets.
  30. *
  31. * @var array
  32. */
  33. protected static $_config = [];
  34. /**
  35. * This method can be used to define configuration adapters for an application.
  36. *
  37. * To change an adapter's configuration at runtime, first drop the adapter and then
  38. * reconfigure it.
  39. *
  40. * Adapters will not be constructed until the first operation is done.
  41. *
  42. * ### Usage
  43. *
  44. * Assuming that the class' name is `Cache` the following scenarios
  45. * are supported:
  46. *
  47. * Setting a cache engine up.
  48. *
  49. * ```
  50. * Cache::setConfig('default', $settings);
  51. * ```
  52. *
  53. * Injecting a constructed adapter in:
  54. *
  55. * ```
  56. * Cache::setConfig('default', $instance);
  57. * ```
  58. *
  59. * Configure multiple adapters at once:
  60. *
  61. * ```
  62. * Cache::setConfig($arrayOfConfig);
  63. * ```
  64. *
  65. * @param string|array $key The name of the configuration, or an array of multiple configs.
  66. * @param array $config An array of name => configuration data for adapter.
  67. * @throws \BadMethodCallException When trying to modify an existing config.
  68. * @throws \LogicException When trying to store an invalid structured config array.
  69. * @return void
  70. */
  71. public static function setConfig($key, $config = null)
  72. {
  73. if ($config === null) {
  74. if (!is_array($key)) {
  75. throw new LogicException('If config is null, key must be an array.');
  76. }
  77. foreach ($key as $name => $settings) {
  78. static::setConfig($name, $settings);
  79. }
  80. return;
  81. }
  82. if (isset(static::$_config[$key])) {
  83. throw new BadMethodCallException(sprintf('Cannot reconfigure existing key "%s"', $key));
  84. }
  85. if (is_object($config)) {
  86. $config = ['className' => $config];
  87. }
  88. if (isset($config['url'])) {
  89. $parsed = static::parseDsn($config['url']);
  90. unset($config['url']);
  91. $config = $parsed + $config;
  92. }
  93. if (isset($config['engine']) && empty($config['className'])) {
  94. $config['className'] = $config['engine'];
  95. unset($config['engine']);
  96. }
  97. static::$_config[$key] = $config;
  98. }
  99. /**
  100. * Reads existing configuration.
  101. *
  102. * @param string $key The name of the configuration.
  103. * @return array|null Array of configuration data.
  104. */
  105. public static function getConfig($key)
  106. {
  107. return isset(static::$_config[$key]) ? static::$_config[$key] : null;
  108. }
  109. /**
  110. * This method can be used to define configuration adapters for an application
  111. * or read existing configuration.
  112. *
  113. * To change an adapter's configuration at runtime, first drop the adapter and then
  114. * reconfigure it.
  115. *
  116. * Adapters will not be constructed until the first operation is done.
  117. *
  118. * ### Usage
  119. *
  120. * Assuming that the class' name is `Cache` the following scenarios
  121. * are supported:
  122. *
  123. * Reading config data back:
  124. *
  125. * ```
  126. * Cache::config('default');
  127. * ```
  128. *
  129. * Setting a cache engine up.
  130. *
  131. * ```
  132. * Cache::config('default', $settings);
  133. * ```
  134. *
  135. * Injecting a constructed adapter in:
  136. *
  137. * ```
  138. * Cache::config('default', $instance);
  139. * ```
  140. *
  141. * Configure multiple adapters at once:
  142. *
  143. * ```
  144. * Cache::config($arrayOfConfig);
  145. * ```
  146. *
  147. * @deprecated 3.4.0 Use setConfig()/getConfig() instead.
  148. * @param string|array $key The name of the configuration, or an array of multiple configs.
  149. * @param array|null $config An array of name => configuration data for adapter.
  150. * @return array|null Null when adding configuration or an array of configuration data when reading.
  151. * @throws \BadMethodCallException When trying to modify an existing config.
  152. */
  153. public static function config($key, $config = null)
  154. {
  155. deprecationWarning(
  156. get_called_class() . '::config() is deprecated. ' .
  157. 'Use setConfig()/getConfig() instead.'
  158. );
  159. if ($config !== null || is_array($key)) {
  160. static::setConfig($key, $config);
  161. return null;
  162. }
  163. return static::getConfig($key);
  164. }
  165. /**
  166. * Drops a constructed adapter.
  167. *
  168. * If you wish to modify an existing configuration, you should drop it,
  169. * change configuration and then re-add it.
  170. *
  171. * If the implementing objects supports a `$_registry` object the named configuration
  172. * will also be unloaded from the registry.
  173. *
  174. * @param string $config An existing configuration you wish to remove.
  175. * @return bool Success of the removal, returns false when the config does not exist.
  176. */
  177. public static function drop($config)
  178. {
  179. if (!isset(static::$_config[$config])) {
  180. return false;
  181. }
  182. if (isset(static::$_registry)) {
  183. static::$_registry->unload($config);
  184. }
  185. unset(static::$_config[$config]);
  186. return true;
  187. }
  188. /**
  189. * Returns an array containing the named configurations
  190. *
  191. * @return array Array of configurations.
  192. */
  193. public static function configured()
  194. {
  195. return array_keys(static::$_config);
  196. }
  197. /**
  198. * Parses a DSN into a valid connection configuration
  199. *
  200. * This method allows setting a DSN using formatting similar to that used by PEAR::DB.
  201. * The following is an example of its usage:
  202. *
  203. * ```
  204. * $dsn = 'mysql://user:pass@localhost/database?';
  205. * $config = ConnectionManager::parseDsn($dsn);
  206. *
  207. * $dsn = 'Cake\Log\Engine\FileLog://?types=notice,info,debug&file=debug&path=LOGS';
  208. * $config = Log::parseDsn($dsn);
  209. *
  210. * $dsn = 'smtp://user:secret@localhost:25?timeout=30&client=null&tls=null';
  211. * $config = Email::parseDsn($dsn);
  212. *
  213. * $dsn = 'file:///?className=\My\Cache\Engine\FileEngine';
  214. * $config = Cache::parseDsn($dsn);
  215. *
  216. * $dsn = 'File://?prefix=myapp_cake_core_&serialize=true&duration=+2 minutes&path=/tmp/persistent/';
  217. * $config = Cache::parseDsn($dsn);
  218. * ```
  219. *
  220. * For all classes, the value of `scheme` is set as the value of both the `className`
  221. * unless they have been otherwise specified.
  222. *
  223. * Note that querystring arguments are also parsed and set as values in the returned configuration.
  224. *
  225. * @param string $dsn The DSN string to convert to a configuration array
  226. * @return array The configuration array to be stored after parsing the DSN
  227. * @throws \InvalidArgumentException If not passed a string, or passed an invalid string
  228. */
  229. public static function parseDsn($dsn)
  230. {
  231. if (empty($dsn)) {
  232. return [];
  233. }
  234. if (!is_string($dsn)) {
  235. throw new InvalidArgumentException('Only strings can be passed to parseDsn');
  236. }
  237. $pattern = <<<'REGEXP'
  238. {
  239. ^
  240. (?P<_scheme>
  241. (?P<scheme>[\w\\\\]+)://
  242. )
  243. (?P<_username>
  244. (?P<username>.*?)
  245. (?P<_password>
  246. :(?P<password>.*?)
  247. )?
  248. @
  249. )?
  250. (?P<_host>
  251. (?P<host>[^?#/:@]+)
  252. (?P<_port>
  253. :(?P<port>\d+)
  254. )?
  255. )?
  256. (?P<_path>
  257. (?P<path>/[^?#]*)
  258. )?
  259. (?P<_query>
  260. \?(?P<query>[^#]*)
  261. )?
  262. (?P<_fragment>
  263. \#(?P<fragment>.*)
  264. )?
  265. $
  266. }x
  267. REGEXP;
  268. preg_match($pattern, $dsn, $parsed);
  269. if (!$parsed) {
  270. throw new InvalidArgumentException("The DSN string '{$dsn}' could not be parsed.");
  271. }
  272. $exists = [];
  273. foreach ($parsed as $k => $v) {
  274. if (is_int($k)) {
  275. unset($parsed[$k]);
  276. } elseif (strpos($k, '_') === 0) {
  277. $exists[substr($k, 1)] = ($v !== '');
  278. unset($parsed[$k]);
  279. } elseif ($v === '' && !$exists[$k]) {
  280. unset($parsed[$k]);
  281. }
  282. }
  283. $query = '';
  284. if (isset($parsed['query'])) {
  285. $query = $parsed['query'];
  286. unset($parsed['query']);
  287. }
  288. parse_str($query, $queryArgs);
  289. foreach ($queryArgs as $key => $value) {
  290. if ($value === 'true') {
  291. $queryArgs[$key] = true;
  292. } elseif ($value === 'false') {
  293. $queryArgs[$key] = false;
  294. } elseif ($value === 'null') {
  295. $queryArgs[$key] = null;
  296. }
  297. }
  298. $parsed = $queryArgs + $parsed;
  299. if (empty($parsed['className'])) {
  300. $classMap = static::getDsnClassMap();
  301. $parsed['className'] = $parsed['scheme'];
  302. if (isset($classMap[$parsed['scheme']])) {
  303. $parsed['className'] = $classMap[$parsed['scheme']];
  304. }
  305. }
  306. return $parsed;
  307. }
  308. /**
  309. * Updates the DSN class map for this class.
  310. *
  311. * @param array $map Additions/edits to the class map to apply.
  312. * @return void
  313. */
  314. public static function setDsnClassMap(array $map)
  315. {
  316. static::$_dsnClassMap = $map + static::$_dsnClassMap;
  317. }
  318. /**
  319. * Returns the DSN class map for this class.
  320. *
  321. * @return array
  322. */
  323. public static function getDsnClassMap()
  324. {
  325. return static::$_dsnClassMap;
  326. }
  327. /**
  328. * Returns or updates the DSN class map for this class.
  329. *
  330. * @deprecated 3.4.0 Use setDsnClassMap()/getDsnClassMap() instead.
  331. * @param array|null $map Additions/edits to the class map to apply.
  332. * @return array
  333. */
  334. public static function dsnClassMap(array $map = null)
  335. {
  336. deprecationWarning(
  337. get_called_class() . '::setDsnClassMap() is deprecated. ' .
  338. 'Use setDsnClassMap()/getDsnClassMap() instead.'
  339. );
  340. if ($map !== null) {
  341. static::setDsnClassMap($map);
  342. }
  343. return static::getDsnClassMap();
  344. }
  345. }