Completed
Push — master ( e6d481...59c475 )
by Greg
01:34
created

ConfigOverlay::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
rs 9.4285
cc 1
eloc 3
nc 1
nop 0
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
        throw new \Exception('The method "import" is not supported for the ConfigOverlay class.');
141
    }
142
143
    /**
144
     * @inheritdoc
145
     */
146
    public function export()
147
    {
148
        $export = [];
149
        foreach ($this->contexts as $name => $config) {
150
            $export = array_merge_recursive($export, $config->export());
151
        }
152
        return $export;
153
    }
154
155
    /**
156
     * @inheritdoc
157
     */
158
    public function hasDefault($key)
159
    {
160
        return $this->contexts[self::DEFAULT_CONTEXT]->has($key);
161
    }
162
163
    /**
164
     * @inheritdoc
165
     */
166
    public function getDefault($key, $default = null)
167
    {
168
        return $this->contexts[self::DEFAULT_CONTEXT]->get($key, $default);
169
    }
170
171
    /**
172
     * @inheritdoc
173
     */
174
    public function setDefault($key, $value)
175
    {
176
        $this->contexts[self::DEFAULT_CONTEXT]->set($key, $value);
177
        return $this;
178
    }
179
}
180