2 namespace Consolidation\Config\Util;
4 use Consolidation\Config\Config;
5 use Consolidation\Config\ConfigInterface;
8 * Overlay different configuration objects that implement ConfigInterface
9 * to make a priority-based, merged configuration object.
11 * Note that using a ConfigOverlay hides the defaults stored in each
12 * individual configuration context. When using overlays, always call
13 * getDefault / setDefault on the ConfigOverlay object itself.
15 class ConfigOverlay implements ConfigInterface
17 protected $contexts = [];
19 const DEFAULT_CONTEXT = 'default';
20 const PROCESS_CONTEXT = 'process';
22 public function __construct()
24 $this->contexts[self::DEFAULT_CONTEXT] = new Config();
25 $this->contexts[self::PROCESS_CONTEXT] = new Config();
29 * Add a named configuration object to the configuration overlay.
30 * Configuration objects added LAST have HIGHEST priority, with the
31 * exception of the fact that the process context always has the
34 * If a context has already been added, its priority will not change.
36 public function addContext($name, ConfigInterface $config)
38 $process = $this->contexts[self::PROCESS_CONTEXT];
39 unset($this->contexts[self::PROCESS_CONTEXT]);
40 $this->contexts[$name] = $config;
41 $this->contexts[self::PROCESS_CONTEXT] = $process;
47 * Add a placeholder context that will be prioritized higher than
48 * existing contexts. This is done to ensure that contexts added
49 * later will maintain a higher priority if the placeholder context
50 * is later relaced with a different configuration set via addContext().
55 public function addPlaceholder($name)
57 return $this->addContext($name, new Config());
61 * Increase the priority of the named context such that it is higher
62 * in priority than any existing context except for the 'process'
68 public function increasePriority($name)
70 $config = $this->getContext($name);
71 unset($this->contexts[$name]);
72 return $this->addContext($name, $config);
75 public function hasContext($name)
77 return isset($this->contexts[$name]);
80 public function getContext($name)
82 if ($this->hasContext($name)) {
83 return $this->contexts[$name];
88 public function removeContext($name)
90 unset($this->contexts[$name]);
94 * Determine if a non-default config value exists.
96 public function findContext($key)
98 foreach (array_reverse($this->contexts) as $name => $config) {
99 if ($config->has($key)) {
109 public function has($key)
111 return $this->findContext($key) != false;
117 public function get($key, $default = null)
119 $context = $this->findContext($key);
121 return $context->get($key, $default);
129 public function set($key, $value)
131 $this->contexts[self::PROCESS_CONTEXT]->set($key, $value);
138 public function import($data)
140 $this->unsupported(__FUNCTION__);
146 public function replace($data)
148 $this->unsupported(__FUNCTION__);
154 public function combine($data)
156 $this->unsupported(__FUNCTION__);
162 protected function unsupported($fn)
164 throw new \Exception("The method '$fn' is not supported for the ConfigOverlay class.");
170 public function export()
173 foreach ($this->contexts as $name => $config) {
174 $export = array_merge_recursive($export, $config->export());
182 public function hasDefault($key)
184 return $this->contexts[self::DEFAULT_CONTEXT]->has($key);
190 public function getDefault($key, $default = null)
192 return $this->contexts[self::DEFAULT_CONTEXT]->get($key, $default);
198 public function setDefault($key, $value)
200 $this->contexts[self::DEFAULT_CONTEXT]->set($key, $value);