|
1
|
|
|
<?php |
|
2
|
|
|
namespace CloudFramework\Core\Tool; |
|
3
|
|
|
|
|
4
|
|
|
use CloudFramework\Exceptions\LoaderException; |
|
5
|
|
|
use CloudFramework\Patterns\CFClass; |
|
6
|
|
|
use Symfony\Component\Yaml\Exception\ParseException; |
|
7
|
|
|
use Symfony\Component\Yaml\Yaml; |
|
8
|
|
|
|
|
9
|
|
|
/** |
|
10
|
|
|
* Class ConfigLoader |
|
11
|
|
|
* @package CloudFramework\Core |
|
12
|
|
|
*/ |
|
13
|
|
|
class ConfigLoader extends CFClass |
|
14
|
|
|
{ |
|
15
|
|
|
private $config = array(); |
|
16
|
|
|
|
|
17
|
1 |
|
public function __construct($configFilename = '') |
|
18
|
|
|
{ |
|
19
|
1 |
|
parent::__construct(); |
|
20
|
1 |
|
$this->loadConfigFile($configFilename); |
|
21
|
1 |
|
} |
|
22
|
|
|
|
|
23
|
|
|
/** |
|
24
|
|
|
* Parser YAML configuration file |
|
25
|
|
|
* @param string $filename |
|
26
|
|
|
* @return array |
|
27
|
|
|
* @throws \Symfony\Component\Yaml\Exception\ParseException If the YAML is not valid |
|
28
|
|
|
*/ |
|
29
|
1 |
|
public static function parseYamlConfigFile($filename = null) |
|
30
|
|
|
{ |
|
31
|
|
|
try { |
|
32
|
1 |
|
return Yaml::parse(file_get_contents($filename)); |
|
33
|
1 |
|
} catch (ParseException $p) { |
|
34
|
|
|
throw $p; |
|
35
|
1 |
|
} catch (\Exception $e) { |
|
36
|
1 |
|
return null; |
|
37
|
|
|
} |
|
38
|
|
|
} |
|
39
|
|
|
|
|
40
|
|
|
/** |
|
41
|
|
|
* Create directory |
|
42
|
|
|
* @param string $directory |
|
43
|
|
|
* @return bool |
|
44
|
|
|
*/ |
|
45
|
|
|
public static function createDir($directory) |
|
46
|
|
|
{ |
|
47
|
|
|
return (false !== @mkdir($directory)); |
|
48
|
|
|
} |
|
49
|
|
|
|
|
50
|
|
|
/** |
|
51
|
|
|
* Save configuration to file |
|
52
|
|
|
* @param string $filename |
|
53
|
|
|
* @return bool |
|
54
|
|
|
* @throws \CloudFramework\Exceptions\LoaderException |
|
55
|
|
|
*/ |
|
56
|
|
|
public function saveConfigFile($filename) |
|
57
|
|
|
{ |
|
58
|
|
|
$config = Yaml::dump($this->config); |
|
59
|
|
|
if (false === ConfigLoader::createDir(dirname($filename)) || false === @file_put_contents($filename, $config)) { |
|
60
|
|
|
throw new LoaderException('Can not save configuration to ' . $filename); |
|
61
|
|
|
} |
|
62
|
|
|
return true; |
|
63
|
|
|
} |
|
64
|
|
|
|
|
65
|
|
|
/** |
|
66
|
|
|
* Search config key and returns this value |
|
67
|
|
|
* @param string $key |
|
68
|
|
|
* @param array $config |
|
69
|
|
|
* @return mixed |
|
70
|
|
|
*/ |
|
71
|
1 |
|
public function getConfigParam($key, $config = array()) |
|
72
|
|
|
{ |
|
73
|
1 |
|
$config = (count($config) == 0) ? $this->config : $config; |
|
74
|
1 |
|
$value = null; |
|
75
|
1 |
|
if (count($config) > 0) { |
|
76
|
1 |
|
$configKey = explode(".", trim($key)); |
|
77
|
1 |
|
$parentKey = reset($configKey); |
|
78
|
1 |
|
$existsKeyInConfig = array_key_exists($parentKey, $config); |
|
79
|
1 |
|
if (count($configKey) > 1 && $existsKeyInConfig) { |
|
80
|
1 |
|
$value = $this->getConfigParam($this->getChildConfigKey($key), $config[$parentKey]); |
|
81
|
1 |
|
} elseif ($existsKeyInConfig) { |
|
82
|
1 |
|
$value = $config[$parentKey]; |
|
83
|
1 |
|
} |
|
84
|
1 |
|
} |
|
85
|
1 |
|
return $value; |
|
86
|
|
|
} |
|
87
|
|
|
|
|
88
|
|
|
/** |
|
89
|
|
|
* Extract child keys from parent config key |
|
90
|
|
|
* @param string $key |
|
91
|
|
|
* @return string |
|
92
|
|
|
*/ |
|
93
|
1 |
|
private function getChildConfigKey($key) |
|
94
|
|
|
{ |
|
95
|
1 |
|
$childKey = ''; |
|
96
|
1 |
|
$dotPosition = strpos($key, '.'); |
|
97
|
1 |
|
if (false !== $dotPosition) { |
|
98
|
1 |
|
$childKey = substr($key, $dotPosition + 1, strlen($key) - $dotPosition); |
|
99
|
1 |
|
} |
|
100
|
1 |
|
return $childKey; |
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
|
|
/** |
|
104
|
|
|
* Set a config parameter |
|
105
|
|
|
* @param string $key |
|
106
|
|
|
* @param mixed $value |
|
107
|
|
|
* @return \CloudFramework\Core\ConfigLoader |
|
108
|
|
|
*/ |
|
109
|
1 |
|
public function setConfigParam($key, $value = null) |
|
110
|
|
|
{ |
|
111
|
1 |
|
$this->config = $this->setConfigValue($key, $value, $this->config); |
|
112
|
1 |
|
return $this; |
|
113
|
|
|
} |
|
114
|
|
|
|
|
115
|
|
|
/** |
|
116
|
|
|
* Recursive process that set a config value |
|
117
|
|
|
* @param string $key |
|
118
|
|
|
* @param mixed $value |
|
119
|
|
|
* @param mixed $config |
|
120
|
|
|
* @return array |
|
121
|
|
|
*/ |
|
122
|
1 |
|
private function setConfigValue($key, $value = null, $config = null) |
|
123
|
|
|
{ |
|
124
|
1 |
|
$keys = explode('.', $key); |
|
125
|
1 |
|
if (count($keys) === 0) { |
|
126
|
|
|
$keys = array($key); |
|
127
|
|
|
} |
|
128
|
1 |
|
$keyCount = count($keys); |
|
129
|
1 |
|
$aux = $config; |
|
130
|
1 |
|
foreach ($keys as $_key) { |
|
131
|
1 |
|
$keyCount--; |
|
132
|
1 |
|
if (!array_key_exists($_key, $aux)) { |
|
133
|
1 |
|
$aux[$_key] = array(); |
|
134
|
1 |
|
} |
|
135
|
1 |
|
if ($keyCount > 0) { |
|
136
|
1 |
|
$aux[$_key] = $this->setConfigValue($this->getChildConfigKey($key), $value, $aux[$_key]); |
|
137
|
1 |
|
} else { |
|
138
|
1 |
|
$aux[$_key] = $value; |
|
139
|
|
|
} |
|
140
|
1 |
|
break; |
|
141
|
1 |
|
} |
|
142
|
1 |
|
return $aux; |
|
143
|
|
|
} |
|
144
|
|
|
|
|
145
|
|
|
/** |
|
146
|
|
|
* Reload config file |
|
147
|
|
|
* @param $configFilename |
|
148
|
|
|
* @throws \Exception |
|
149
|
|
|
* @throws \ParseException |
|
150
|
|
|
*/ |
|
151
|
2 |
|
public function loadConfigFile($configFilename = '') |
|
152
|
|
|
{ |
|
153
|
2 |
|
if (strlen($configFilename) > 0 && file_exists($configFilename)) { |
|
154
|
1 |
|
$this->config = ConfigLoader::parseYamlConfigFile($configFilename); |
|
|
|
|
|
|
155
|
1 |
|
} |
|
156
|
2 |
|
} |
|
157
|
|
|
} |
|
158
|
|
|
|
Our type inference engine has found an assignment of a scalar value (like a string, an integer or null) to a property which is an array.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.
To type hint that a parameter can be either an array or null, you can set a type hint of array and a default value of null. The PHP interpreter will then accept both an array or null for that parameter.
The function can be called with either null or an array for the parameter
$needlebut will only accept an array as$haystack.