Completed
Pull Request — master (#552)
by Greg
02:57
created

Config   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 225
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 23
lcom 1
cbo 2
dl 0
loc 225
rs 10
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A has() 0 4 1
A get() 0 7 2
A set() 0 5 1
A import() 0 7 2
A extend() 0 14 3
A export() 0 4 1
A applyConfiguration() 0 11 3
A getGlobalOptionDefaultValues() 0 10 1
A getDefault() 0 4 2
A setDefault() 0 5 1
A isSimulated() 0 4 1
A setSimulated() 0 4 1
A isDecorated() 0 4 1
A setDecorated() 0 4 1
A setProgressBarAutoDisplayInterval() 0 4 1
1
<?php
2
namespace Robo\Config;
3
4
use Dflydev\DotAccessData\Data;
5
6
class Config
7
{
8
    const PROGRESS_BAR_AUTO_DISPLAY_INTERVAL = 'progress-delay';
9
    const DEFAULT_PROGRESS_DELAY = 2;
10
    const SIMULATE = 'simulate';
11
    const DECORATED = 'decorated';
12
13
    /**
14
     * @var Data
15
     */
16
    protected $config;
17
18
    /**
19
     * @var array
20
     */
21
    protected $defaults;
22
23
    /**
24
     * Create a new configuration object, and initialize it with
25
     * the provided nested array containing configuration data.
26
     */
27
    public function __construct(array $data = null)
28
    {
29
        $this->config = new Data($data);
30
        $this->defaults = $this->getGlobalOptionDefaultValues();
31
    }
32
33
    /**
34
     * Determine if a non-default config value exists.
35
     */
36
    public function has($key)
37
    {
38
        return ($this->config->has($key));
39
    }
40
41
    /**
42
     * Fetch a configuration value
43
     *
44
     * @param string $key Which config item to look up
45
     * @param string|null $defaultOverride Override usual default value with a different default. Deprecated; provide defaults to the config processor instead.
46
     *
47
     * @return mixed
48
     */
49
    public function get($key, $defaultOverride = null)
50
    {
51
        if ($this->has($key)) {
52
            return $this->config->get($key);
53
        }
54
        return $this->getDefault($key, $defaultOverride);
55
    }
56
57
    /**
58
     * Set a config value
59
     *
60
     * @param string $key
61
     * @param mixed $value
62
     *
63
     * @return $this
64
     */
65
    public function set($key, $value)
66
    {
67
        $this->config->set($key, $value);
68
        return $this;
69
    }
70
71
    /**
72
     * Import configuration from the provided nexted array, replacing whatever
73
     * was here previously. No processing is done on the provided data.
74
     *
75
     * @param array $data
76
     * @return Config
77
     */
78
    public function import($data)
79
    {
80
        if (!empty($data)) {
81
            $this->config->import($data, true);
82
        }
83
        return $this;
84
    }
85
86
    /**
87
     * Extend this configuration by merging the provided nested array.
88
     * This will also do some simple processing on the data.
89
     *
90
     * @param array|ConfigLoaderInterface $data
91
     */
92
    public function extend($data)
93
    {
94
        if (empty($data)) {
95
            return;
96
        }
97
        $processor = new ConfigProcessor();
98
        $processor->add($this->config->export());
99
        if ($data instanceof ConfigLoaderInterface) {
100
            $processor->extend($data);
101
        } else {
102
            $processor->add($data);
103
        }
104
        return $this->import($processor->export());
105
    }
106
107
    /**
108
     * Export all configuration as a nested array.
109
     */
110
    public function export()
111
    {
112
        return $this->config->export();
113
    }
114
115
    /**
116
     * Given an object that contains configuration methods, inject any
117
     * configuration found in the configuration file.
118
     *
119
     * The proper use for this method is to call setter methods of the
120
     * provided object. Using configuration to call methods that do work
121
     * is an abuse of this mechanism.
122
     *
123
     * TODO: We could use reflection to test to see if the return type
124
     * of the provided object is a reference to the object itself. All
125
     * setter methods should do this. This test is insufficient to guarentee
126
     * that the method is valid, but it would be a good start.
127
     */
128
    public function applyConfiguration($object, $configurationKey)
129
    {
130
        if ($this->has($configurationKey)) {
131
            $settings = $this->get($configurationKey);
132
            foreach ($settings as $setterMethod => $args) {
133
                // TODO: Should it be possible to make $args a nested array
134
                // to make this code call the setter method multiple times?
135
                call_user_func_array([$object, $setterMethod], (array)$args);
136
            }
137
        }
138
    }
139
140
    /**
141
     * Return an associative array containing all of the global configuration
142
     * options and their default values.
143
     *
144
     * @return array
145
     */
146
    public function getGlobalOptionDefaultValues()
147
    {
148
        $globalOptions =
149
        [
150
            self::PROGRESS_BAR_AUTO_DISPLAY_INTERVAL => self::DEFAULT_PROGRESS_DELAY,
151
            self::SIMULATE => false,
152
        ];
153
154
        return $globalOptions;
155
    }
156
157
    /**
158
     * Return the default value for a given configuration item.
159
     *
160
     * @param string $key
161
     * @param mixed $defaultOverride
162
     *
163
     * @return mixed
164
     */
165
    public function getDefault($key, $defaultOverride = null)
166
    {
167
        return isset($this->defaults[$key]) ? $this->defaults[$key] : $defaultOverride;
168
    }
169
170
    /**
171
     * Set the default value for a configuration setting. This allows us to
172
     * set defaults either before or after more specific configuration values
173
     * are loaded. Keeping defaults separate from current settings also
174
     * allows us to determine when a setting has been overridden.
175
     *
176
     * @param string $key
177
     * @param string $value
178
     */
179
    public function setDefault($key, $value)
180
    {
181
        $this->defaults[$key] = $value;
182
        return $this;
183
    }
184
185
    /**
186
     * @return bool
187
     */
188
    public function isSimulated()
189
    {
190
        return $this->get(self::SIMULATE);
191
    }
192
193
    /**
194
     * @param bool $simulated
195
     *
196
     * @return $this
197
     */
198
    public function setSimulated($simulated = true)
199
    {
200
        return $this->set(self::SIMULATE, $simulated);
201
    }
202
203
    /**
204
     * @return bool
205
     */
206
    public function isDecorated()
207
    {
208
        return $this->get(self::DECORATED);
209
    }
210
211
    /**
212
     * @param bool $decorated
213
     *
214
     * @return $this
215
     */
216
    public function setDecorated($decorated = true)
217
    {
218
        return $this->set(self::DECORATED, $decorated);
219
    }
220
221
    /**
222
     * @param int $interval
223
     *
224
     * @return $this
225
     */
226
    public function setProgressBarAutoDisplayInterval($interval)
227
    {
228
        return $this->set(self::PROGRESS_BAR_AUTO_DISPLAY_INTERVAL, $interval);
229
    }
230
}
231