/vendor/laravel/framework/src/Illuminate/Config/Repository.php

https://bitbucket.org/larryg/powerhut · PHP · 414 lines · 157 code · 56 blank · 201 comment · 7 complexity · 35f762ba3035838c1ccc081d017a4e5b MD5 · raw file

  1. <?php namespace Illuminate\Config;
  2. use Closure;
  3. use ArrayAccess;
  4. use Illuminate\Support\NamespacedItemResolver;
  5. class Repository extends NamespacedItemResolver implements ArrayAccess {
  6. /**
  7. * The loader implementation.
  8. *
  9. * @var \Illuminate\Config\LoaderInterface
  10. */
  11. protected $loader;
  12. /**
  13. * The current environment.
  14. *
  15. * @var string
  16. */
  17. protected $environment;
  18. /**
  19. * All of the configuration items.
  20. *
  21. * @var array
  22. */
  23. protected $items = array();
  24. /**
  25. * All of the registered packages.
  26. *
  27. * @var array
  28. */
  29. protected $packages = array();
  30. /**
  31. * The after load callbacks for namespaces.
  32. *
  33. * @var array
  34. */
  35. protected $afterLoad = array();
  36. /**
  37. * Create a new configuration repository.
  38. *
  39. * @param \Illuminate\Config\LoaderInterface $loader
  40. * @param string $environment
  41. * @return void
  42. */
  43. public function __construct(LoaderInterface $loader, $environment)
  44. {
  45. $this->loader = $loader;
  46. $this->environment = $environment;
  47. }
  48. /**
  49. * Determine if the given configuration value exists.
  50. *
  51. * @param string $key
  52. * @return bool
  53. */
  54. public function has($key)
  55. {
  56. $default = microtime(true);
  57. return $this->get($key, $default) != $default;
  58. }
  59. /**
  60. * Determine if a configuration group exists.
  61. *
  62. * @param string $key
  63. * @return bool
  64. */
  65. public function hasGroup($key)
  66. {
  67. list($namespace, $group, $item) = $this->parseKey($key);
  68. return $this->loader->exists($group, $namespace);
  69. }
  70. /**
  71. * Get the specified configuration value.
  72. *
  73. * @param string $key
  74. * @param mixed $default
  75. * @return mixed
  76. */
  77. public function get($key, $default = null)
  78. {
  79. list($namespace, $group, $item) = $this->parseKey($key);
  80. // Configuration items are actually keyed by "collection", which is simply a
  81. // combination of each namespace and groups, which allows a unique way to
  82. // identify the arrays of configuration items for the particular files.
  83. $collection = $this->getCollection($group, $namespace);
  84. $this->load($group, $namespace, $collection);
  85. return array_get($this->items[$collection], $item, $default);
  86. }
  87. /**
  88. * Set a given configuration value.
  89. *
  90. * @param string $key
  91. * @param mixed $value
  92. * @return void
  93. */
  94. public function set($key, $value)
  95. {
  96. list($namespace, $group, $item) = $this->parseKey($key);
  97. $collection = $this->getCollection($group, $namespace);
  98. // We'll need to go ahead and lazy load each configuration groups even when
  99. // we're just setting a configuration item so that the set item does not
  100. // get overwritten if a different item in the group is requested later.
  101. $this->load($group, $namespace, $collection);
  102. if (is_null($item))
  103. {
  104. $this->items[$collection] = $value;
  105. }
  106. else
  107. {
  108. array_set($this->items[$collection], $item, $value);
  109. }
  110. }
  111. /**
  112. * Load the configuration group for the key.
  113. *
  114. * @param string $key
  115. * @param string $namespace
  116. * @param string $collection
  117. * @return void
  118. */
  119. protected function load($group, $namespace, $collection)
  120. {
  121. $env = $this->environment;
  122. // If we've already loaded this collection, we will just bail out since we do
  123. // not want to load it again. Once items are loaded a first time they will
  124. // stay kept in memory within this class and not loaded from disk again.
  125. if (isset($this->items[$collection]))
  126. {
  127. return;
  128. }
  129. $items = $this->loader->load($env, $group, $namespace);
  130. // If we've already loaded this collection, we will just bail out since we do
  131. // not want to load it again. Once items are loaded a first time they will
  132. // stay kept in memory within this class and not loaded from disk again.
  133. if (isset($this->afterLoad[$namespace]))
  134. {
  135. $items = $this->callAfterLoad($namespace, $group, $items);
  136. }
  137. $this->items[$collection] = $items;
  138. }
  139. /**
  140. * Call the after load callback for a namespace.
  141. *
  142. * @param string $namespace
  143. * @param string $group
  144. * @param array $items
  145. * @return array
  146. */
  147. protected function callAfterLoad($namespace, $group, $items)
  148. {
  149. $callback = $this->afterLoad[$namespace];
  150. return call_user_func($callback, $this, $group, $items);
  151. }
  152. /**
  153. * Parse an array of namespaced segments.
  154. *
  155. * @param string $key
  156. * @return array
  157. */
  158. protected function parseNamespacedSegments($key)
  159. {
  160. list($namespace, $item) = explode('::', $key);
  161. // If the namespace is registered as a package, we will just assume the group
  162. // is equal to the namespace since all packages cascade in this way having
  163. // a single file per package, otherwise we'll just parse them as normal.
  164. if (in_array($namespace, $this->packages))
  165. {
  166. return $this->parsePackageSegments($key, $namespace, $item);
  167. }
  168. return parent::parseNamespacedSegments($key);
  169. }
  170. /**
  171. * Parse the segments of a package namespace.
  172. *
  173. * @param string $namespace
  174. * @param string $item
  175. * @return array
  176. */
  177. protected function parsePackageSegments($key, $namespace, $item)
  178. {
  179. $itemSegments = explode('.', $item);
  180. // If the configuration file doesn't exist for the given package group we can
  181. // assume that we should implicitly use the config file matching the name
  182. // of the namespace. Generally packages should use one type or another.
  183. if ( ! $this->loader->exists($itemSegments[0], $namespace))
  184. {
  185. return array($namespace, 'config', $item);
  186. }
  187. return parent::parseNamespacedSegments($key);
  188. }
  189. /**
  190. * Register a package for cascading configuration.
  191. *
  192. * @param string $package
  193. * @param string $hint
  194. * @param string $namespace
  195. * @return void
  196. */
  197. public function package($package, $hint, $namespace = null)
  198. {
  199. $namespace = $this->getPackageNamespace($package, $namespace);
  200. $this->packages[] = $namespace;
  201. // First we will simply register the namespace with the repository so that it
  202. // can be loaded. Once we have done that we'll register an after namespace
  203. // callback so that we can cascade an application package configuration.
  204. $this->addNamespace($namespace, $hint);
  205. $this->afterLoading($namespace, function($me, $group, $items) use ($package)
  206. {
  207. $env = $me->getEnvironment();
  208. $loader = $me->getLoader();
  209. return $loader->cascadePackage($env, $package, $group, $items);
  210. });
  211. }
  212. /**
  213. * Get the configuration namespace for a package.
  214. *
  215. * @param string $package
  216. * @param string $namespace
  217. * @return string
  218. */
  219. protected function getPackageNamespace($package, $namespace)
  220. {
  221. if (is_null($namespace))
  222. {
  223. list($vendor, $namespace) = explode('/', $package);
  224. }
  225. return $namespace;
  226. }
  227. /**
  228. * Register an after load callback for a given namespace.
  229. *
  230. * @param string $namespace
  231. * @param Closure $callback
  232. * @return void
  233. */
  234. public function afterLoading($namespace, Closure $callback)
  235. {
  236. $this->afterLoad[$namespace] = $callback;
  237. }
  238. /**
  239. * Get the collection identifier.
  240. *
  241. * @param string $group
  242. * @param string $namespace
  243. * @return string
  244. */
  245. protected function getCollection($group, $namespace = null)
  246. {
  247. $namespace = $namespace ?: '*';
  248. return $namespace.'::'.$group;
  249. }
  250. /**
  251. * Add a new namespace to the loader.
  252. *
  253. * @param string $namespace
  254. * @param string $hint
  255. * @return void
  256. */
  257. public function addNamespace($namespace, $hint)
  258. {
  259. return $this->loader->addNamespace($namespace, $hint);
  260. }
  261. /**
  262. * Returns all registered namespaces with the config
  263. * loader.
  264. *
  265. * @return array
  266. */
  267. public function getNamespaces()
  268. {
  269. return $this->loader->getNamespaces();
  270. }
  271. /**
  272. * Get the loader implementation.
  273. *
  274. * @return \Illuminate\Config\LoaderInterface
  275. */
  276. public function getLoader()
  277. {
  278. return $this->loader;
  279. }
  280. /**
  281. * Set the loader implementation.
  282. *
  283. * @param \Illuminate\Config\LoaderInterface $loader
  284. * @return void
  285. */
  286. public function setLoader(LoaderInterface $loader)
  287. {
  288. $this->loader = $loader;
  289. }
  290. /**
  291. * Get the current configuration environment.
  292. *
  293. * @return string
  294. */
  295. public function getEnvironment()
  296. {
  297. return $this->environment;
  298. }
  299. /**
  300. * Get the after load callback array.
  301. *
  302. * @return array
  303. */
  304. public function getAfterLoadCallbacks()
  305. {
  306. return $this->afterLoad;
  307. }
  308. /**
  309. * Get all of the configuration items.
  310. *
  311. * @return array
  312. */
  313. public function getItems()
  314. {
  315. return $this->items;
  316. }
  317. /**
  318. * Determine if the given configuration option exists.
  319. *
  320. * @param string $key
  321. * @return bool
  322. */
  323. public function offsetExists($key)
  324. {
  325. return $this->has($key);
  326. }
  327. /**
  328. * Get a configuration option.
  329. *
  330. * @param string $key
  331. * @return bool
  332. */
  333. public function offsetGet($key)
  334. {
  335. return $this->get($key);
  336. }
  337. /**
  338. * Set a configuration option.
  339. *
  340. * @param string $key
  341. * @param string $value
  342. * @return void
  343. */
  344. public function offsetSet($key, $value)
  345. {
  346. $this->set($key, $value);
  347. }
  348. /**
  349. * Unset a configuration option.
  350. *
  351. * @param string $key
  352. * @return void
  353. */
  354. public function offsetUnset($key)
  355. {
  356. $this->set($key, null);
  357. }
  358. }