1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace TomPHP\ContainerConfigurator; |
4
|
|
|
|
5
|
|
|
use Assert\Assertion; |
6
|
|
|
use InvalidArgumentException; |
7
|
|
|
use TomPHP\ContainerConfigurator\Exception\NoMatchingFilesException; |
8
|
|
|
use TomPHP\ContainerConfigurator\Exception\UnknownSettingException; |
9
|
|
|
|
10
|
|
|
final class Configurator |
11
|
|
|
{ |
12
|
|
|
const SETTING_PREFIX = 'config_prefix'; |
13
|
|
|
const SETTING_SEPARATOR = 'config_separator'; |
14
|
|
|
const SETTING_SERVICES_KEY = 'services_key'; |
15
|
|
|
const SETTING_INFLECTORS_KEY = 'inflectors_key'; |
16
|
|
|
const SETTING_DEFAULT_SINGLETON_SERVICES = 'default_singleton_services'; |
17
|
|
|
|
18
|
|
|
const FILE_READERS = [ |
19
|
|
|
'.json' => FileReader\JSONFileReader::class, |
20
|
|
|
'.php' => FileReader\PHPFileReader::class, |
21
|
|
|
]; |
22
|
|
|
|
23
|
|
|
const CONTAINER_ADAPTERS = [ |
24
|
|
|
\League\Container\Container::class => League\LeagueContainerAdapter::class, |
25
|
|
|
\Pimple\Container::class => Pimple\PimpleContainerAdapter::class, |
26
|
|
|
]; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* @var ApplicationConfig |
30
|
|
|
*/ |
31
|
|
|
private $config; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* @var FileReader\ReaderFactory |
35
|
|
|
*/ |
36
|
|
|
private $readerFactory; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* @var array |
40
|
|
|
*/ |
41
|
|
|
private $settings = [ |
42
|
|
|
self::SETTING_PREFIX => 'config', |
43
|
|
|
self::SETTING_SEPARATOR => '.', |
44
|
|
|
self::SETTING_SERVICES_KEY => 'di.services', |
45
|
|
|
self::SETTING_INFLECTORS_KEY => 'di.inflectors', |
46
|
|
|
self::SETTING_DEFAULT_SINGLETON_SERVICES => false, |
47
|
|
|
]; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @api |
51
|
|
|
* |
52
|
|
|
* @return Configurator |
53
|
|
|
*/ |
54
|
|
|
public static function apply() |
55
|
|
|
{ |
56
|
|
|
return new self(); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
private function __construct() |
60
|
|
|
{ |
61
|
|
|
$this->config = new ApplicationConfig([]); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* @api |
66
|
|
|
* |
67
|
|
|
* @param array $config |
68
|
|
|
* |
69
|
|
|
* @return Configurator |
70
|
|
|
*/ |
71
|
|
|
public function configFromArray(array $config) |
72
|
|
|
{ |
73
|
|
|
$this->config->merge($config); |
74
|
|
|
|
75
|
|
|
return $this; |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* @api |
80
|
|
|
* |
81
|
|
|
* @param string $filename |
82
|
|
|
* |
83
|
|
|
* @return Configurator |
84
|
|
|
*/ |
85
|
|
|
public function configFromFile($filename) |
86
|
|
|
{ |
87
|
|
|
Assertion::file($filename); |
88
|
|
|
|
89
|
|
|
$this->readFileAndMergeConfig($filename); |
90
|
|
|
|
91
|
|
|
return $this; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* @api |
96
|
|
|
* |
97
|
|
|
* @param string $pattern |
98
|
|
|
* |
99
|
|
|
* @return Configurator |
100
|
|
|
* |
101
|
|
|
* @throws NoMatchingFilesException |
102
|
|
|
* @throws InvalidArgumentException |
103
|
|
|
*/ |
104
|
|
|
public function configFromFiles($pattern) |
105
|
|
|
{ |
106
|
|
|
Assertion::string($pattern); |
107
|
|
|
|
108
|
|
|
$locator = new FileReader\FileLocator(); |
109
|
|
|
|
110
|
|
|
$files = $locator->locate($pattern); |
111
|
|
|
|
112
|
|
|
if (count($files) === 0) { |
113
|
|
|
throw NoMatchingFilesException::fromPattern($pattern); |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
foreach ($files as $filename) { |
117
|
|
|
$this->readFileAndMergeConfig($filename); |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
return $this; |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* @api |
125
|
|
|
* |
126
|
|
|
* @param string $name |
127
|
|
|
* @param mixed $value |
128
|
|
|
* |
129
|
|
|
* @return Configurator |
130
|
|
|
* |
131
|
|
|
* @throws UnknownSettingException |
132
|
|
|
* @throws InvalidArgumentException |
133
|
|
|
*/ |
134
|
|
|
public function withSetting($name, $value) |
135
|
|
|
{ |
136
|
|
|
Assertion::string($name); |
137
|
|
|
Assertion::scalar($value); |
138
|
|
|
|
139
|
|
|
if (!array_key_exists($name, $this->settings)) { |
140
|
|
|
throw UnknownSettingException::fromSetting($name, array_keys($this->settings)); |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
$this->settings[$name] = $value; |
144
|
|
|
|
145
|
|
|
return $this; |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* @api |
150
|
|
|
* |
151
|
|
|
* @param object $container |
152
|
|
|
* |
153
|
|
|
* @return void |
154
|
|
|
*/ |
155
|
|
|
public function to($container) |
156
|
|
|
{ |
157
|
|
|
$this->config->setSeparator($this->settings[self::SETTING_SEPARATOR]); |
158
|
|
|
|
159
|
|
|
$factory = new ContainerAdapterFactory(self::CONTAINER_ADAPTERS); |
160
|
|
|
|
161
|
|
|
$configurator = $factory->create($container); |
162
|
|
|
|
163
|
|
|
$configurator->addApplicationConfig($this->config, $this->settings[self::SETTING_PREFIX]); |
164
|
|
|
|
165
|
|
View Code Duplication |
if (isset($this->config[$this->settings[self::SETTING_SERVICES_KEY]])) { |
|
|
|
|
166
|
|
|
$configurator->addServiceConfig(new ServiceConfig( |
167
|
|
|
$this->config[$this->settings[self::SETTING_SERVICES_KEY]], |
168
|
|
|
$this->settings[self::SETTING_DEFAULT_SINGLETON_SERVICES] |
169
|
|
|
)); |
170
|
|
|
} |
171
|
|
|
|
172
|
|
View Code Duplication |
if (isset($this->config[$this->settings[self::SETTING_INFLECTORS_KEY]])) { |
|
|
|
|
173
|
|
|
$configurator->addInflectorConfig(new InflectorConfig( |
174
|
|
|
$this->config[$this->settings[self::SETTING_INFLECTORS_KEY]] |
175
|
|
|
)); |
176
|
|
|
} |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* @param string $filename |
181
|
|
|
* |
182
|
|
|
* @return void |
183
|
|
|
*/ |
184
|
|
|
private function readFileAndMergeConfig($filename) |
185
|
|
|
{ |
186
|
|
|
$reader = $this->getReaderFor($filename); |
187
|
|
|
|
188
|
|
|
$this->config->merge($reader->read($filename)); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* @param string $filename |
193
|
|
|
* |
194
|
|
|
* @return FileReader\FileReader |
195
|
|
|
*/ |
196
|
|
|
private function getReaderFor($filename) |
197
|
|
|
{ |
198
|
|
|
if (!$this->readerFactory) { |
199
|
|
|
$this->readerFactory = new FileReader\ReaderFactory(self::FILE_READERS); |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
return $this->readerFactory->create($filename); |
203
|
|
|
} |
204
|
|
|
} |
205
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.