Completed
Pull Request — master (#552)
by Greg
03:13
created

Config   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 221
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 22
lcom 1
cbo 2
dl 0
loc 221
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 10 2
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
        $processor->add($data);
0 ignored issues
show
Bug introduced by
It seems like $data defined by parameter $data on line 92 can also be of type object<Robo\Config\ConfigLoaderInterface>; however, Robo\Config\ConfigProcessor::add() does only seem to accept array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
100
        return $this->import($processor->export());
101
    }
102
103
    /**
104
     * Export all configuration as a nested array.
105
     */
106
    public function export()
107
    {
108
        return $this->config->export();
109
    }
110
111
    /**
112
     * Given an object that contains configuration methods, inject any
113
     * configuration found in the configuration file.
114
     *
115
     * The proper use for this method is to call setter methods of the
116
     * provided object. Using configuration to call methods that do work
117
     * is an abuse of this mechanism.
118
     *
119
     * TODO: We could use reflection to test to see if the return type
120
     * of the provided object is a reference to the object itself. All
121
     * setter methods should do this. This test is insufficient to guarentee
122
     * that the method is valid, but it would be a good start.
123
     */
124
    public function applyConfiguration($object, $configurationKey)
125
    {
126
        if ($this->has($configurationKey)) {
127
            $settings = $this->get($configurationKey);
128
            foreach ($settings as $setterMethod => $args) {
129
                // TODO: Should it be possible to make $args a nested array
130
                // to make this code call the setter method multiple times?
131
                call_user_func_array([$object, $setterMethod], (array)$args);
132
            }
133
        }
134
    }
135
136
    /**
137
     * Return an associative array containing all of the global configuration
138
     * options and their default values.
139
     *
140
     * @return array
141
     */
142
    public function getGlobalOptionDefaultValues()
143
    {
144
        $globalOptions =
145
        [
146
            self::PROGRESS_BAR_AUTO_DISPLAY_INTERVAL => self::DEFAULT_PROGRESS_DELAY,
147
            self::SIMULATE => false,
148
        ];
149
150
        return $globalOptions;
151
    }
152
153
    /**
154
     * Return the default value for a given configuration item.
155
     *
156
     * @param string $key
157
     * @param mixed $defaultOverride
158
     *
159
     * @return mixed
160
     */
161
    public function getDefault($key, $defaultOverride = null)
162
    {
163
        return isset($this->defaults[$key]) ? $this->defaults[$key] : $defaultOverride;
164
    }
165
166
    /**
167
     * Set the default value for a configuration setting. This allows us to
168
     * set defaults either before or after more specific configuration values
169
     * are loaded. Keeping defaults separate from current settings also
170
     * allows us to determine when a setting has been overridden.
171
     *
172
     * @param string $key
173
     * @param string $value
174
     */
175
    public function setDefault($key, $value)
176
    {
177
        $this->defaults[$key] = $value;
178
        return $this;
179
    }
180
181
    /**
182
     * @return bool
183
     */
184
    public function isSimulated()
185
    {
186
        return $this->get(self::SIMULATE);
187
    }
188
189
    /**
190
     * @param bool $simulated
191
     *
192
     * @return $this
193
     */
194
    public function setSimulated($simulated = true)
195
    {
196
        return $this->set(self::SIMULATE, $simulated);
197
    }
198
199
    /**
200
     * @return bool
201
     */
202
    public function isDecorated()
203
    {
204
        return $this->get(self::DECORATED);
205
    }
206
207
    /**
208
     * @param bool $decorated
209
     *
210
     * @return $this
211
     */
212
    public function setDecorated($decorated = true)
213
    {
214
        return $this->set(self::DECORATED, $decorated);
215
    }
216
217
    /**
218
     * @param int $interval
219
     *
220
     * @return $this
221
     */
222
    public function setProgressBarAutoDisplayInterval($interval)
223
    {
224
        return $this->set(self::PROGRESS_BAR_AUTO_DISPLAY_INTERVAL, $interval);
225
    }
226
}
227