Skip to content

Commit b7b29ec

Browse files
committed
Initial commit
0 parents  commit b7b29ec

File tree

4 files changed

+295
-0
lines changed

4 files changed

+295
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*.swp
2+
composer.lock
3+
/vendor

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2015 Michael Härtl
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

composer.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "codemix/yii2-configloader",
3+
"description": "Build configuration arrays from config files and env vars.",
4+
"keywords": ["yii2", "config", "environment"],
5+
"license": "MIT",
6+
"authors": [
7+
{
8+
"name": "Michael Härtl",
9+
"email": "haertl.mike@gmail.com"
10+
}
11+
],
12+
"require": {
13+
"yiisoft/yii2": "*",
14+
"vlucas/phpdotenv": "1.0.*"
15+
},
16+
"autoload": {
17+
"psr-4": {
18+
"codemix\\yii2confload\\": "src/"
19+
}
20+
}
21+
}

src/Config.php

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
<?php
2+
namespace codemix\yii2confload;
3+
4+
/**
5+
* Config helps to build application configuration from a set of config files.
6+
* It can also initialize the Yii environment from environment vars and help
7+
* to load the latter from a `.env` file.
8+
*
9+
* ```php
10+
* // Init Yii environment from env vars (or `.env` file) and load configuration
11+
* // from `config/web.php` or `config/console.php` respectively
12+
* $config = new Config('/path/to/app')->web();
13+
* $config = new Config('/path/to/app')->console();
14+
*
15+
* // Merge a `config/local.php` or `config/console-local.php` with local overrides
16+
* // This also happens if `ENABLE_LOCALCONF` environment variable is set.
17+
* $config = new Config('/path/to/app')->web([], true);
18+
* $config = new Config('/path/to/app')->console([], true);
19+
* ```
20+
*
21+
* The class normally is used with this set of files:
22+
*
23+
* - `.env`: Defines environment variables (usually only used for local development)
24+
* - `config/web.php`: Web configuration
25+
* - `config/console.php`: Console configuration
26+
*
27+
* A typical example for an `.env` file:
28+
*
29+
* ```
30+
* YII_DEBUG=1
31+
* DB_DSN=mysql:host=db;dbname=web
32+
* DB_USER=user
33+
* DB_PASSWORD=secret
34+
* ```
35+
*
36+
* The `web.php` is loaded in the context of this class, so you can easily access
37+
* these settings there like:
38+
*
39+
* ```php
40+
* return [
41+
* 'components' => [
42+
* 'db' => [
43+
* 'dsn' => self::env('DB_DSN'),
44+
* 'username' => self::env('DB_USER'),
45+
* 'password' => self::env('DB_PASSWORD'),
46+
* ```
47+
*
48+
* In your `console.php` you can also reuse parts of your web configuration:
49+
*
50+
* ``php
51+
* $web = $this->web();
52+
* return [
53+
* 'components' => [
54+
* 'db' => $web['components']['db'],
55+
* ```
56+
*
57+
* The initialization of the Yii environment and loading of `.env` file
58+
* is optional and can also be supressed:
59+
*
60+
* ```php
61+
* $config = new Config('/path/to/app', false)->web();
62+
* ```
63+
*
64+
* Vice versa the class can also be used to only initialize the Yii environment
65+
* and load a `.env` file:
66+
*
67+
* ```php
68+
* Config::initEnv('/path/to/app');
69+
*
70+
* // Get setting from environment variable or .env file
71+
* $setting = Config::env('MY_SETTING', 'default');
72+
* ```
73+
*/
74+
class Config
75+
{
76+
/**
77+
* @var string the application base directory
78+
*/
79+
public $directory;
80+
81+
/**
82+
* Initialize the app directory path and the Yii environment.
83+
*
84+
* If an `.env` file is found in the app directory, it's loaded with `Dotenv`.
85+
* If a `YII_DEBUG` or `YII_ENV` environment variable is set, the Yii constants
86+
* are set accordingly. In debug mode the error reporting is also set to `E_ALL`.
87+
*
88+
* @param string $directory the application base directory
89+
* @param bool $initEnv whether to initialize the Yii environment. Default
90+
* is `true
91+
* @param string|null $envDir the directory to look for a `.env` file or
92+
* `null` to not load any environment variables from that file.
93+
*/
94+
public function __construct($directory, $initEnv = true)
95+
{
96+
$this->directory = $directory;
97+
98+
if ($initEnv) {
99+
self::initEnv($directory);
100+
}
101+
102+
}
103+
104+
/**
105+
* Gets the filename for a config file
106+
*
107+
* @param string $name
108+
* @param bool $required whether the file must exist. Default is `true`.
109+
* @param string $directory the name of the config directory. Default is `config`.
110+
* @return string|null the full path to the config file or `null` if $required
111+
* is set to `false` and the file does not exist
112+
* @throws \Exception
113+
*/
114+
public function getConfigFile($name, $required = true, $directory = 'config')
115+
{
116+
$sep = DIRECTORY_SEPARATOR;
117+
$path = rtrim($this->directory, $sep) . $sep . trim($directory, $sep) . $sep . $name;
118+
if (!file_exists($path)) {
119+
if ($required) {
120+
throw new \Exception("Config file '$path' does not exist");
121+
} else {
122+
return null;
123+
}
124+
}
125+
return $path;
126+
}
127+
128+
/**
129+
* Builds the web configuration.
130+
*
131+
* If $local is set to `true` and a `local.php` config file exists, it
132+
* is merged into the web configuration.
133+
*
134+
* Alternatively an environment variable `ENABLE_LOCALCONF` can be set
135+
* to 1. Setting $local to `false` completely disables the local config.
136+
*
137+
* @param array $config additional configuration to merge into the result
138+
* @param bool|null $local whether to check for local configuration overrides.
139+
* The default is `null`, which will check `ENABLE_LOCALCONF` env var.
140+
* @return array the web configuration array
141+
* @throws \Exception
142+
*/
143+
public function web($config = [], $local = null)
144+
{
145+
$files = [$this->getConfigFile('web.php')];
146+
if ($local === null) {
147+
$local = $this->env('ENABLE_LOCALCONF', false);
148+
}
149+
if ($local) {
150+
$localFile = $this->getConfigFile('local.php', false);
151+
if ($localFile !==null) {
152+
$files[] = $localFile;
153+
}
154+
}
155+
return $this->mergeFiles($files, $config);
156+
}
157+
158+
/**
159+
* Builds the console configuration.
160+
*
161+
* If $local is set to `true` and a `local-console.php` config file exists,
162+
* it is merged into the console configuration.
163+
*
164+
* Alternatively an environment variable `ENABLE_LOCALCONF` can be set
165+
* to 1. Setting $local to `false` completely disables the local config.
166+
*
167+
* @param array $config additional configuration to merge into the result
168+
* @param bool|null $local whether to check for local configuration overrides.
169+
* The default is `null`, which will check `ENABLE_LOCALCONF` env var.
170+
* @return array the web configuration array
171+
* @throws \Exception
172+
*/
173+
public function console($config = [], $local = null)
174+
{
175+
$files = [$this->getConfigFile('console.php')];
176+
if ($local === null) {
177+
$local = $this->env('ENABLE_LOCALCONF', false);
178+
}
179+
if ($local) {
180+
$localFile = $this->getConfigFile('local-console.php', false);
181+
if ($localFile !==null) {
182+
$files[] = $localFile;
183+
}
184+
}
185+
return $this->mergeFiles($files, $config);
186+
}
187+
188+
/**
189+
* Load configuration files and merge them together.
190+
*
191+
* The files are loaded in the context of this class. So you can use `$this`
192+
* and `self` to access instance / class methods.
193+
*
194+
* @param array $files list of configuration files to load and merge.
195+
* Configuration from later files will override earlier values.
196+
* @param array $config additional configuration to merge into the result
197+
* @return array the resulting configuration array
198+
*/
199+
public function mergeFiles($files, $config = [])
200+
{
201+
$configs = array_map(function ($f) { return require($f); }, $files);
202+
$configs[] = $config;
203+
return call_user_func_array('yii\helpers\ArrayHelper::merge', $configs);
204+
}
205+
206+
/**
207+
* Init the Yii environment from environment variables.
208+
*
209+
* If $directory is passed and contains a `.env` file, that file is loaded
210+
* with `Dotenv` first.
211+
*
212+
* @param string|null $directory the directory to check for an `.env` file
213+
*/
214+
public static function initEnv($directory = null)
215+
{
216+
if ($directory !== null && file_exists($directory . DIRECTORY_SEPARATOR . '.env')) {
217+
\Dotenv::load($directory);
218+
}
219+
220+
// Define main Yii environment variables
221+
if (isset($_ENV['YII_DEBUG'])) {
222+
define('YII_DEBUG', (bool)$_ENV['YII_DEBUG']);
223+
if (YII_DEBUG) {
224+
error_reporting(E_ALL);
225+
}
226+
}
227+
if (isset($_ENV['YII_ENV'])) {
228+
define('YII_ENV', $_ENV['YII_ENV']);
229+
}
230+
}
231+
232+
/**
233+
* Get either an env var or a default value if the var is not set.
234+
*
235+
* @param string $name the name of the variable to get
236+
* @param mixed $default the default value to return if variable is not set.
237+
* Default is `null`.
238+
* @param bool $required whether the var must be set. $default is ignored in
239+
* this case. Default is `false`.
240+
* @return mixed the content of the environment variable or $default if not set
241+
*/
242+
public static function env($name, $default = null, $required = false)
243+
{
244+
if ($required) {
245+
Dotenv::required($name);
246+
}
247+
return isset($_ENV[$name]) ? $_ENV[$name] : $default;
248+
}
249+
250+
}

0 commit comments

Comments
 (0)