Completed
Pull Request — master (#1952)
by Basil
02:12
created

Config::addDefinition()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace luya;
4
5
use luya\helpers\ArrayHelper;
6
7
/**
8
 * Configuration array Helper.
9
 * 
10
 * The {{luya\Config}} allows you to create the configuration for different hosts and difference between web and console config.
11
 * 
12
 * ```php
13
 * $config = new Config('myapp', dirname(__DIR__), [
14
 *     'siteTitle' => 'My LUYA Project',
15
 *     'defaultRoute' => 'cms',
16
 *     // other application level configurations
17
 * ]);
18
 * 
19
 * // define global components which works either for console or web runtime
20
 * 
21
 * $config->component('mail', [
22
 *     'host' => 'xyz',
23
 *     'from' => '[email protected]',
24
 * ]);
25
 * 
26
 * $config->component('db', [
27
 *     'class' => 'yii\db\Connection',
28
 *     'dsn' => 'mysql:host=localhost;dbname=prod_db',
29
 *     'username' => 'foo',
30
 *     'password' => 'bar',
31
 * ])->env('martin');
32
 * 
33
 * 
34
 * 
35
 * // define components which are only for web or console runtime:
36
 * 
37
 * $config->webComponent('request', [
38
 *     'cookieValidationKey' => 'xyz',
39
 * ]);
40
 * 
41
 * // which is equals to, but the above is better to read and structure in the config file
42
 * 
43
 * $config->component('request', [
44
 *     'cookieValidationKey' => 'xyz',
45
 * ])->webRuntime();
46
 * 
47
 * // adding modules
48
 * 
49
 * $config->module('admin', [
50
 *     'class' => 'luya\admin\Module',
51
 *     'secureLogin' => true,
52
 * ]);
53
 * 
54
 * $config->module('cms', 'luya\cms\frontend\Module'); // which is equals to $config->module('cms', ['class' => 'luya\cms\frontend\Module']);
55
 * 
56
 * // export and generate the config for a given enviroment or environment independent.
57
 * 
58
 * return $config->toArray(); // returns the config not taking care of enviroment variables like prod, env
59
 * 
60
 * return $config->toArray(Config::ENV_PROD);
61
 * ```
62
 * 
63
 * @author Basil Suter <[email protected]>
64
 * @since 1.0.10
65
 */
66
class Config
67
{
68
    const ENV_ALL = 'all';
69
70
    const ENV_PROD = 'prod';
71
    
72
    const ENV_PREP = 'prep';
73
    
74
    const ENV_DEV = 'dev';
75
    
76
    const ENV_LOCAL = 'local';
77
78
    const RUNTIME_ALL = 0;
79
80
    const RUNTIME_CONSOLE = 1;
81
82
    const RUNTIME_WEB = 2;
83
    
84
    public function __construct($id, $basePath, array $applicationConfig = [])
85
    {
86
        $applicationConfig['id'] = $id;
87
        $applicationConfig['basePath'] = $basePath;
88
89
        $this->application($applicationConfig);
90
    }
91
92
    /**
93
     * Undocumented function
94
     *
95
     * @param [type] $config
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
96
     * @return ConfigDefinition
97
     */
98
    public function application($config)
99
    {
100
        return $this->addDefinition(new ConfigDefinition(ConfigDefinition::GROUP_APPLICATIONS, md5(serialize($config)), $config));
101
    }
102
103
    /**
104
     * Undocumented function
105
     *
106
     * @param [type] $id
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
107
     * @param [type] $config
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
108
     * @return ConfigDefinition
109
     */
110
    public function module($id, $config)
111
    {
112
        return $this->addDefinition(new ConfigDefinition(ConfigDefinition::GROUP_MODULES, $id, $config));
113
    }
114
115
    /**
116
     * Undocumented function
117
     *
118
     * @param [type] $id
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
119
     * @param [type] $config
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
120
     * @param [type] $runtime
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
121
     * @return ConfigDefinition
122
     */
123
    public function component($id, $config, $runtime = self::RUNTIME_ALL)
124
    {
125
        return $this->addDefinition(new ConfigDefinition(ConfigDefinition::GROUP_COMPONENTS, $id, $config))->runtime($runtime);
126
    }
127
128
    /**
129
     * Undocumented function
130
     *
131
     * @param [type] $id
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
132
     * @param [type] $config
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
133
     * @return ConfigDefinition
134
     */
135
    public function webComponent($id, $config)
136
    {
137
        return $this->component($id, $config, self::RUNTIME_WEB);
138
    }
139
140
    /**
141
     * Undocumented function
142
     *
143
     * @param [type] $id
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
144
     * @param [type] $config
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
145
     * @return ConfigDefinition
146
     */
147
    public function consoleComponent($id, $config)
148
    {
149
        return $this->component($id, $config, self::RUNTIME_CONSOLE);
150
    }
151
152
    private $_definitions = [];
153
154
    /**
155
     * Undocumented function
156
     *
157
     * @param ConfigDefinition $definition
158
     * @return ConfigDefinition
159
     */
160
    private function addDefinition(ConfigDefinition $definition)
161
    {
162
        $this->_definitions[] = $definition;
163
164
        return $definition;
165
    }
166
167
    private $_isCliRuntime;
168
169
    /**
170
     * Whether runtime is cli or not
171
     *
172
     * @return boolean
173
     */
174
    public function isCliRuntime()
175
    {
176
        if ($this->_isCliRuntime === null) {
177
            $this->_isCliRuntime = strtolower(php_sapi_name()) === 'cli';
178
        }
179
180
        return $this->_isCliRuntime;
181
    }
182
183
    public function setCliRuntime($value)
184
    {
185
        $this->_isCliRuntime = $value;
186
    }
187
188
    public function toArray(array $envs = [])
189
    {
190
        $config = [];
191
        $envs = array_merge($envs, [self::ENV_ALL]);
192
        foreach ($this->_definitions as $definition) {
193
            /** @var ConfigDefinition $definition */
194
195
            if (!$definition->validateEnvs($envs)) {
196
                continue;
197
            }
198
199
            if ($definition->validateRuntime(self::RUNTIME_ALL)) {
200
                $this->appendConfig($config, $definition);
201
            } elseif ($this->isCliRuntime() && $definition->validateRuntime(self::RUNTIME_CONSOLE)) {
202
                $this->appendConfig($config, $definition);
203
            } elseif (!$this->isCliRuntime() && $definition->validateRuntime(self::RUNTIME_WEB)) {
204
                $this->appendConfig($config, $definition);
205
            }
206
        }
207
208
        return $config;
209
    }
210
211
    private function appendConfig(&$config, ConfigDefinition $definition)
212
    {
213
        switch ($definition->getGroup()) {
214
            case ConfigDefinition::GROUP_APPLICATIONS:
215
                foreach ($definition->getConfig() as $k => $v) {
216
                    $config[$k] = $v;
217
                }
218
                break;
219
            case ConfigDefinition::GROUP_COMPONENTS:
220
                $this->handleKeyBaseMerge($config, $definition, 'components');
221
                break;
222
223
            case ConfigDefinition::GROUP_MODULES:
224
                $this->handleKeyBaseMerge($config, $definition, 'modules');
225
                break;
226
        }
227
    }
228
229
    private function handleKeyBaseMerge(&$config, ConfigDefinition $definition, $section)
230
    {
231
        if (!array_key_exists($section, $config)) {
232
            $config[$section] = [];
233
        }
234
235
        if (isset($config[$section][$definition->getKey()])) {
236
            $config[$section][$definition->getKey()] = ArrayHelper::merge($config[$section][$definition->getKey()], $definition->getConfig());
237
        } else {
238
            $config[$section][$definition->getKey()] = $definition->getConfig();
239
        }
240
    }
241
}