d1f12697742fdff20b6954b5ef89aa61c1d51877
[yaffs-website] / vendor / consolidation / config / src / Util / ConfigOverlay.php
1 <?php
2 namespace Consolidation\Config\Util;
3
4 use Consolidation\Config\Config;
5 use Consolidation\Config\ConfigInterface;
6
7 /**
8  * Overlay different configuration objects that implement ConfigInterface
9  * to make a priority-based, merged configuration object.
10  *
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.
14  */
15 class ConfigOverlay implements ConfigInterface
16 {
17     protected $contexts = [];
18
19     const DEFAULT_CONTEXT = 'default';
20     const PROCESS_CONTEXT = 'process';
21
22     public function __construct()
23     {
24         $this->contexts[self::DEFAULT_CONTEXT] = new Config();
25         $this->contexts[self::PROCESS_CONTEXT] = new Config();
26     }
27
28     /**
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
32      * highest priority.
33      *
34      * If a context has already been added, its priority will not change.
35      */
36     public function addContext($name, ConfigInterface $config)
37     {
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;
42
43         return $this;
44     }
45
46     /**
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().
51      *
52      * @param string $name
53      * @return $this
54      */
55     public function addPlaceholder($name)
56     {
57         return $this->addContext($name, new Config());
58     }
59
60     /**
61      * Increase the priority of the named context such that it is higher
62      * in priority than any existing context except for the 'process'
63      * context.
64      *
65      * @param string $name
66      * @return $this
67      */
68     public function increasePriority($name)
69     {
70         $config = $this->getContext($name);
71         unset($this->contexts[$name]);
72         return $this->addContext($name, $config);
73     }
74
75     public function hasContext($name)
76     {
77         return isset($this->contexts[$name]);
78     }
79
80     public function getContext($name)
81     {
82         if ($this->hasContext($name)) {
83             return $this->contexts[$name];
84         }
85         return new Config();
86     }
87
88     public function removeContext($name)
89     {
90         unset($this->contexts[$name]);
91     }
92
93     /**
94      * Determine if a non-default config value exists.
95      */
96     public function findContext($key)
97     {
98         foreach (array_reverse($this->contexts) as $name => $config) {
99             if ($config->has($key)) {
100                 return $config;
101             }
102         }
103         return false;
104     }
105
106     /**
107      * @inheritdoc
108      */
109     public function has($key)
110     {
111         return $this->findContext($key) != false;
112     }
113
114     /**
115      * @inheritdoc
116      */
117     public function get($key, $default = null)
118     {
119         $context = $this->findContext($key);
120         if ($context) {
121             return $context->get($key, $default);
122         }
123         return $default;
124     }
125
126     /**
127      * @inheritdoc
128      */
129     public function set($key, $value)
130     {
131         $this->contexts[self::PROCESS_CONTEXT]->set($key, $value);
132         return $this;
133     }
134
135     /**
136      * @inheritdoc
137      */
138     public function import($data)
139     {
140         $this->unsupported(__FUNCTION__);
141     }
142
143     /**
144      * @inheritdoc
145      */
146     public function replace($data)
147     {
148         $this->unsupported(__FUNCTION__);
149     }
150
151     /**
152      * @inheritdoc
153      */
154     public function combine($data)
155     {
156         $this->unsupported(__FUNCTION__);
157     }
158
159     /**
160      * @inheritdoc
161      */
162     protected function unsupported($fn)
163     {
164         throw new \Exception("The method '$fn' is not supported for the ConfigOverlay class.");
165     }
166
167     /**
168      * @inheritdoc
169      */
170     public function export()
171     {
172         $export = [];
173         foreach ($this->contexts as $name => $config) {
174             $export = array_merge_recursive($export, $config->export());
175         }
176         return $export;
177     }
178
179     /**
180      * @inheritdoc
181      */
182     public function hasDefault($key)
183     {
184         return $this->contexts[self::DEFAULT_CONTEXT]->has($key);
185     }
186
187     /**
188      * @inheritdoc
189      */
190     public function getDefault($key, $default = null)
191     {
192         return $this->contexts[self::DEFAULT_CONTEXT]->get($key, $default);
193     }
194
195     /**
196      * @inheritdoc
197      */
198     public function setDefault($key, $value)
199     {
200         $this->contexts[self::DEFAULT_CONTEXT]->set($key, $value);
201         return $this;
202     }
203 }