1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Nip\Container\ServiceProviders; |
4
|
|
|
|
5
|
|
|
use Nip\Container\ContainerAwareInterface; |
6
|
|
|
use Nip\Container\ContainerAwareTrait; |
7
|
|
|
use Nip\Container\ServiceProviders\Providers\AbstractServiceProvider; |
8
|
|
|
use Nip\Container\ServiceProviders\Providers\BootableServiceProviderInterface; |
9
|
|
|
use Nip\Container\ServiceProviders\Providers\ServiceProviderInterface; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* Class ServiceProviderAggregate |
13
|
|
|
* @package Nip\Container\ServiceProvider |
14
|
|
|
*/ |
15
|
|
|
class ProviderRepository implements ProviderRepositoryInterface |
16
|
|
|
{ |
17
|
|
|
use ContainerAwareTrait; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* @var array |
21
|
|
|
*/ |
22
|
|
|
protected $services = []; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @var AbstractServiceProvider[] |
26
|
|
|
*/ |
27
|
|
|
protected $providers = []; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @var array Array of registered providers class names |
31
|
|
|
*/ |
32
|
|
|
protected $registeredProviders = []; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* The deferred services and their providers. |
36
|
|
|
* |
37
|
|
|
* @var array |
38
|
|
|
*/ |
39
|
|
|
protected $deferredServices = []; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Indicates if the application has "booted". |
43
|
|
|
* |
44
|
|
|
* @var bool |
45
|
|
|
*/ |
46
|
|
|
protected $booted = false; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* Adds a new Service Provider |
50
|
|
|
* {@inheritdoc} |
51
|
|
|
*/ |
52
|
|
|
public function add($provider) |
53
|
|
|
{ |
54
|
|
|
if (is_string($provider) && class_exists($provider)) { |
55
|
|
|
$provider = $this->resolveProvider($provider); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
if ($provider instanceof ContainerAwareInterface) { |
59
|
|
|
$provider->setContainer($this->getContainer()); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
if ($provider instanceof ServiceProviderInterface) { |
63
|
|
|
foreach ($provider->provides() as $service) { |
64
|
|
|
$this->services[$service] = get_class($provider); |
65
|
|
|
} |
66
|
|
|
$this->providers[] = $provider; |
67
|
|
|
return $this; |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
throw new \InvalidArgumentException( |
71
|
|
|
'A service provider must be a fully qualified class name or instance ' . |
72
|
|
|
'of (\Nip\Container\ServiceProvider\ServiceProviderInterface)' |
73
|
|
|
); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* Resolve a service provider instance from the class name. |
78
|
|
|
* |
79
|
|
|
* @param string $provider |
80
|
|
|
* @return AbstractServiceProvider |
81
|
|
|
*/ |
82
|
|
|
public function resolveProvider($provider) |
83
|
|
|
{ |
84
|
|
|
return new $provider($this); |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
public function register() |
88
|
|
|
{ |
89
|
|
|
foreach ($this->providers as $provider) { |
90
|
|
|
$this->registerProvider($provider); |
91
|
|
|
} |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Register a service provider with the application. |
96
|
|
|
* |
97
|
|
|
* @param AbstractServiceProvider|string $provider |
98
|
|
|
* @return AbstractServiceProvider |
99
|
|
|
*/ |
100
|
|
|
public function registerProvider($provider) |
101
|
|
|
{ |
102
|
|
|
if (($provider = $this->getProvider($provider))) { |
|
|
|
|
103
|
|
|
} elseif (is_string($provider)) { |
104
|
|
|
$provider = $this->resolveProvider($provider); |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
if ($this->registeredProvider($provider)) { |
|
|
|
|
108
|
|
|
return $provider; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
if (method_exists($provider, 'register')) { |
112
|
|
|
$provider->register(); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
$this->markAsRegistered($provider); |
|
|
|
|
116
|
|
|
|
117
|
|
|
// If the application has already booted, we will call this boot method on |
118
|
|
|
// the provider class so it has an opportunity to do its boot logic and |
119
|
|
|
// will be ready for any usage by this developer's application logic. |
120
|
|
|
if ($this->booted) { |
121
|
|
|
$this->bootProvider($provider); |
|
|
|
|
122
|
|
|
} |
123
|
|
|
return $provider; |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* Get the registered service provider instance if it exists. |
128
|
|
|
* |
129
|
|
|
* @param AbstractServiceProvider|string $provider |
130
|
|
|
* @return AbstractServiceProvider|null |
131
|
|
|
*/ |
132
|
|
|
public function getProvider($provider) |
133
|
|
|
{ |
134
|
|
|
$name = is_string($provider) ? $provider : get_class($provider); |
135
|
|
|
return \Nip_Helper_Arrays::first($this->providers, function ($value) use ($name) { |
136
|
|
|
return $value instanceof $name; |
137
|
|
|
}); |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* @param AbstractServiceProvider $provider |
142
|
|
|
* @return bool |
143
|
|
|
*/ |
144
|
|
|
public function registeredProvider($provider) |
145
|
|
|
{ |
146
|
|
|
$providerClass = get_class($provider); |
147
|
|
|
if (isset($this->registeredProviders[$providerClass]) && $this->registeredProviders[$providerClass] === true) { |
148
|
|
|
return true; |
149
|
|
|
} |
150
|
|
|
return false; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* Mark the given provider as registered. |
155
|
|
|
* |
156
|
|
|
* @param AbstractServiceProvider $provider |
157
|
|
|
* @return void |
158
|
|
|
*/ |
159
|
|
|
protected function markAsRegistered($provider) |
160
|
|
|
{ |
161
|
|
|
$this->registeredProviders[get_class($provider)] = true; |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
/** |
165
|
|
|
* Boot the given service provider. |
166
|
|
|
* |
167
|
|
|
* @param AbstractServiceProvider $provider |
168
|
|
|
* @return mixed |
169
|
|
|
*/ |
170
|
|
|
protected function bootProvider(AbstractServiceProvider $provider) |
171
|
|
|
{ |
172
|
|
|
if ($provider instanceof BootableServiceProviderInterface) { |
173
|
|
|
return $provider->boot(); |
174
|
|
|
} |
175
|
|
|
return null; |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
/** |
179
|
|
|
* Check to see if the services is registered |
180
|
|
|
* {@inheritdoc} |
181
|
|
|
*/ |
182
|
|
|
public function provides($service) |
183
|
|
|
{ |
184
|
|
|
return array_key_exists($service, $this->providers); |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
public function boot() |
188
|
|
|
{ |
189
|
|
|
foreach ($this->providers as $provider) { |
190
|
|
|
$this->bootProvider($provider); |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
$this->setBooted(true); |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
/** |
197
|
|
|
* @param bool $booted |
198
|
|
|
*/ |
199
|
|
|
public function setBooted($booted) |
200
|
|
|
{ |
201
|
|
|
$this->booted = $booted; |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
/** |
205
|
|
|
* Load and boot all of the remaining deferred providers. |
206
|
|
|
* |
207
|
|
|
* @return void |
208
|
|
|
*/ |
209
|
|
|
public function loadDeferredProviders() |
210
|
|
|
{ |
211
|
|
|
// We will simply spin through each of the deferred providers and register each |
212
|
|
|
// one and boot them if the application has booted. This should make each of |
213
|
|
|
// the remaining services available to this application for immediate use. |
214
|
|
|
foreach ($this->deferredServices as $service => $provider) { |
215
|
|
|
$this->loadDeferredProvider($service); |
216
|
|
|
} |
217
|
|
|
$this->deferredServices = []; |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
/** |
221
|
|
|
* Load the provider for a deferred service. |
222
|
|
|
* |
223
|
|
|
* @param string $service |
224
|
|
|
* @return void |
225
|
|
|
*/ |
226
|
|
|
public function loadDeferredProvider($service) |
227
|
|
|
{ |
228
|
|
|
if (!isset($this->deferredServices[$service])) { |
229
|
|
|
return; |
230
|
|
|
} |
231
|
|
|
$provider = $this->deferredServices[$service]; |
232
|
|
|
|
233
|
|
|
// If the service provider has not already been loaded and registered we can |
234
|
|
|
// register it with the application and remove the service from this list |
235
|
|
|
// of deferred services, since it will already be loaded on subsequent. |
236
|
|
|
if (!isset($this->registeredProviders[$provider])) { |
237
|
|
|
$this->registerDeferredProvider($provider, $service); |
238
|
|
|
} |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* Register a deferred provider and service. |
243
|
|
|
* |
244
|
|
|
* @param string $provider |
245
|
|
|
* @param string $service |
246
|
|
|
* @return void |
247
|
|
|
*/ |
248
|
|
|
public function registerDeferredProvider($provider, $service = null) |
249
|
|
|
{ |
250
|
|
|
// Once the provider that provides the deferred service has been registered we |
251
|
|
|
// will remove it from our local list of the deferred services with related |
252
|
|
|
// providers so that this container does not try to resolve it out again. |
253
|
|
|
if ($service) { |
|
|
|
|
254
|
|
|
unset($this->deferredServices[$service]); |
255
|
|
|
} |
256
|
|
|
$this->registerProvider($instance = new $provider($this)); |
257
|
|
|
} |
258
|
|
|
} |
259
|
|
|
|
This check looks for the bodies of
if
statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.These
if
bodies can be removed. If you have an empty if but statements in theelse
branch, consider inverting the condition.could be turned into
This is much more concise to read.