1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the puli/manager package. |
5
|
|
|
* |
6
|
|
|
* (c) Bernhard Schussek <[email protected]> |
7
|
|
|
* |
8
|
|
|
* For the full copyright and license information, please view the LICENSE |
9
|
|
|
* file that was distributed with this source code. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace Puli\Manager\Api\Discovery; |
13
|
|
|
|
14
|
|
|
use Exception; |
15
|
|
|
use Puli\Discovery\Api\Binding\Binding; |
16
|
|
|
use Puli\Discovery\Binding\ResourceBinding; |
17
|
|
|
use Puli\Manager\Api\AlreadyLoadedException; |
18
|
|
|
use Puli\Manager\Api\Module\Module; |
19
|
|
|
use Puli\Manager\Api\Module\RootModule; |
20
|
|
|
use Puli\Manager\Api\NotLoadedException; |
21
|
|
|
use Rhumsaa\Uuid\Uuid; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* Describes a resource binding. |
25
|
|
|
* |
26
|
|
|
* This class contains a high-level model of {@link ResourceBinding} as it is |
27
|
|
|
* used in this module. |
28
|
|
|
* |
29
|
|
|
* @since 1.0 |
30
|
|
|
* |
31
|
|
|
* @author Bernhard Schussek <[email protected]> |
32
|
|
|
* |
33
|
|
|
* @see ResourceBinding |
34
|
|
|
*/ |
35
|
|
|
class BindingDescriptor |
36
|
|
|
{ |
37
|
|
|
/** |
38
|
|
|
* @var Binding |
39
|
|
|
*/ |
40
|
|
|
private $binding; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @var int |
44
|
|
|
*/ |
45
|
|
|
private $state; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* @var Module |
49
|
|
|
*/ |
50
|
|
|
private $containingModule; |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* @var BindingTypeDescriptor |
54
|
|
|
*/ |
55
|
|
|
private $typeDescriptor; |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* @var Exception[] |
59
|
|
|
*/ |
60
|
|
|
private $loadErrors; |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Creates a new binding descriptor. |
64
|
|
|
* |
65
|
|
|
* @param Binding $binding The described binding. |
66
|
|
|
*/ |
67
|
116 |
|
public function __construct(Binding $binding) |
68
|
|
|
{ |
69
|
116 |
|
$this->binding = $binding; |
70
|
116 |
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* Loads the binding descriptor. |
74
|
|
|
* |
75
|
|
|
* @param Module $containingModule The module that |
76
|
|
|
* contains the |
77
|
|
|
* descriptor. |
78
|
|
|
* @param BindingTypeDescriptor|null $typeDescriptor The type descriptor. |
79
|
|
|
* |
80
|
|
|
* @throws AlreadyLoadedException If the descriptor is already loaded. |
81
|
|
|
*/ |
82
|
64 |
|
public function load(Module $containingModule, BindingTypeDescriptor $typeDescriptor = null) |
83
|
|
|
{ |
84
|
64 |
|
if (null !== $this->state) { |
85
|
|
|
throw new AlreadyLoadedException('The binding descriptor is already loaded.'); |
86
|
|
|
} |
87
|
|
|
|
88
|
64 |
|
$this->loadErrors = array(); |
89
|
|
|
|
90
|
64 |
|
if ($typeDescriptor && $typeDescriptor->isLoaded() && $typeDescriptor->isEnabled()) { |
91
|
|
|
try { |
92
|
49 |
|
$this->binding->initialize($typeDescriptor->getType()); |
93
|
6 |
|
} catch (Exception $e) { |
94
|
6 |
|
$this->loadErrors[] = $e; |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
|
98
|
64 |
|
$this->containingModule = $containingModule; |
99
|
64 |
|
$this->typeDescriptor = $typeDescriptor; |
100
|
|
|
|
101
|
64 |
|
$this->refreshState(); |
102
|
64 |
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Unloads the binding descriptor. |
106
|
|
|
* |
107
|
|
|
* All memory allocated during {@link load()} is freed. |
108
|
|
|
* |
109
|
|
|
* @throws NotLoadedException If the descriptor is not loaded. |
110
|
|
|
*/ |
111
|
20 |
|
public function unload() |
112
|
|
|
{ |
113
|
20 |
|
if (null === $this->state) { |
114
|
|
|
throw new NotLoadedException('The binding descriptor is not loaded.'); |
115
|
|
|
} |
116
|
|
|
|
117
|
20 |
|
$this->containingModule = null; |
118
|
20 |
|
$this->typeDescriptor = null; |
119
|
20 |
|
$this->loadErrors = array(); |
120
|
20 |
|
$this->state = null; |
121
|
20 |
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* Returns whether the descriptor is loaded. |
125
|
|
|
* |
126
|
|
|
* @return bool Returns `true` if the descriptor is loaded. |
127
|
|
|
*/ |
128
|
52 |
|
public function isLoaded() |
129
|
|
|
{ |
130
|
52 |
|
return null !== $this->state; |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* Returns the UUID of the described binding. |
135
|
|
|
* |
136
|
|
|
* @return Uuid The UUID. |
137
|
|
|
*/ |
138
|
67 |
|
public function getUuid() |
139
|
|
|
{ |
140
|
67 |
|
return $this->binding->getUuid(); |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* Returns the name of the bound type. |
145
|
|
|
* |
146
|
|
|
* @return string The type name. |
147
|
|
|
*/ |
148
|
62 |
|
public function getTypeName() |
149
|
|
|
{ |
150
|
62 |
|
return $this->binding->getTypeName(); |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* Returns the described binding. |
155
|
|
|
* |
156
|
|
|
* @return Binding The binding. |
157
|
|
|
*/ |
158
|
31 |
|
public function getBinding() |
159
|
|
|
{ |
160
|
31 |
|
return $this->binding; |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* Returns the errors that happened during loading. |
165
|
|
|
* |
166
|
|
|
* The method {@link load()} needs to be called before calling this method, |
167
|
|
|
* otherwise an exception is thrown. |
168
|
|
|
* |
169
|
|
|
* @return Exception[] The load errors. |
170
|
|
|
* |
171
|
|
|
* @throws NotLoadedException If the descriptor is not loaded. |
172
|
|
|
*/ |
173
|
11 |
|
public function getLoadErrors() |
174
|
|
|
{ |
175
|
11 |
|
if (null === $this->loadErrors) { |
176
|
|
|
throw new NotLoadedException('The binding descriptor is not loaded.'); |
177
|
|
|
} |
178
|
|
|
|
179
|
11 |
|
return $this->loadErrors; |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
/** |
183
|
|
|
* Returns the module that contains the descriptor. |
184
|
|
|
* |
185
|
|
|
* The method {@link load()} needs to be called before calling this method, |
186
|
|
|
* otherwise an exception is thrown. |
187
|
|
|
* |
188
|
|
|
* @return Module The containing module. |
189
|
|
|
* |
190
|
|
|
* @throws NotLoadedException If the descriptor is not loaded. |
191
|
|
|
*/ |
192
|
38 |
|
public function getContainingModule() |
193
|
|
|
{ |
194
|
38 |
|
if (null === $this->containingModule) { |
195
|
|
|
throw new NotLoadedException('The binding descriptor is not loaded.'); |
196
|
|
|
} |
197
|
|
|
|
198
|
38 |
|
return $this->containingModule; |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
/** |
202
|
|
|
* Returns the type descriptor. |
203
|
|
|
* |
204
|
|
|
* The method {@link load()} needs to be called before calling this method, |
205
|
|
|
* otherwise an exception is thrown. |
206
|
|
|
* |
207
|
|
|
* @return BindingTypeDescriptor|null The type descriptor or null, if no |
208
|
|
|
* type descriptor exists for the |
209
|
|
|
* binding's type name. |
210
|
|
|
* |
211
|
|
|
* @throws NotLoadedException If the binding descriptor is not loaded. |
212
|
|
|
*/ |
213
|
7 |
|
public function getTypeDescriptor() |
214
|
|
|
{ |
215
|
|
|
// Check containing module, as the type descriptor may be null |
216
|
7 |
|
if (null === $this->containingModule) { |
217
|
|
|
throw new NotLoadedException('The binding descriptor is not loaded.'); |
218
|
|
|
} |
219
|
|
|
|
220
|
7 |
|
return $this->typeDescriptor; |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
/** |
224
|
|
|
* Returns the state of the binding. |
225
|
|
|
* |
226
|
|
|
* The method {@link load()} needs to be called before calling this method, |
227
|
|
|
* otherwise an exception is thrown. |
228
|
|
|
* |
229
|
|
|
* @return int One of the {@link BindingState} constants. |
230
|
|
|
* |
231
|
|
|
* @throws NotLoadedException If the descriptor is not loaded. |
232
|
|
|
*/ |
233
|
8 |
|
public function getState() |
234
|
|
|
{ |
235
|
8 |
|
if (null === $this->state) { |
236
|
|
|
throw new NotLoadedException('The binding descriptor is not loaded.'); |
237
|
|
|
} |
238
|
|
|
|
239
|
8 |
|
return $this->state; |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
/** |
243
|
|
|
* Returns whether the binding is enabled. |
244
|
|
|
* |
245
|
|
|
* The method {@link load()} needs to be called before calling this method, |
246
|
|
|
* otherwise an exception is thrown. |
247
|
|
|
* |
248
|
|
|
* @return bool Returns `true` if the state is {@link BindingState::ENABLED}. |
249
|
|
|
* |
250
|
|
|
* @throws NotLoadedException If the descriptor is not loaded. |
251
|
|
|
* |
252
|
|
|
* @see BindingState::ENABLED |
253
|
|
|
*/ |
254
|
32 |
View Code Duplication |
public function isEnabled() |
|
|
|
|
255
|
|
|
{ |
256
|
32 |
|
if (null === $this->state) { |
257
|
|
|
throw new NotLoadedException('The binding descriptor is not loaded.'); |
258
|
|
|
} |
259
|
|
|
|
260
|
32 |
|
return BindingState::ENABLED === $this->state; |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
/** |
264
|
|
|
* Returns whether the binding is disabled. |
265
|
|
|
* |
266
|
|
|
* The method {@link load()} needs to be called before calling this method, |
267
|
|
|
* otherwise an exception is thrown. |
268
|
|
|
* |
269
|
|
|
* @return bool Returns `true` if the state is {@link BindingState::DISABLED}. |
270
|
|
|
* |
271
|
|
|
* @throws NotLoadedException If the descriptor is not loaded. |
272
|
|
|
* |
273
|
|
|
* @see BindingState::DISABLED |
274
|
|
|
*/ |
275
|
4 |
View Code Duplication |
public function isDisabled() |
|
|
|
|
276
|
|
|
{ |
277
|
4 |
|
if (null === $this->state) { |
278
|
|
|
throw new NotLoadedException('The binding descriptor is not loaded.'); |
279
|
|
|
} |
280
|
|
|
|
281
|
4 |
|
return BindingState::DISABLED === $this->state; |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
/** |
285
|
|
|
* Returns whether the type of the binding does not exist. |
286
|
|
|
* |
287
|
|
|
* The method {@link load()} needs to be called before calling this method, |
288
|
|
|
* otherwise an exception is thrown. |
289
|
|
|
* |
290
|
|
|
* @return bool Returns `true` if the state is {@link BindingState::TYPE_NOT_FOUND}. |
291
|
|
|
* |
292
|
|
|
* @throws NotLoadedException If the descriptor is not loaded. |
293
|
|
|
* |
294
|
|
|
* @see BindingState::TYPE_NOT_FOUND |
295
|
|
|
*/ |
296
|
19 |
View Code Duplication |
public function isTypeNotFound() |
|
|
|
|
297
|
|
|
{ |
298
|
19 |
|
if (null === $this->state) { |
299
|
|
|
throw new NotLoadedException('The binding descriptor is not loaded.'); |
300
|
|
|
} |
301
|
|
|
|
302
|
19 |
|
return BindingState::TYPE_NOT_FOUND === $this->state; |
303
|
|
|
} |
304
|
|
|
|
305
|
|
|
/** |
306
|
|
|
* Returns whether the type of the binding is not enabled. |
307
|
|
|
* |
308
|
|
|
* The method {@link load()} needs to be called before calling this method, |
309
|
|
|
* otherwise an exception is thrown. |
310
|
|
|
* |
311
|
|
|
* @return bool Returns `true` if the state is {@link BindingState::TYPE_NOT_ENABLED}. |
312
|
|
|
* |
313
|
|
|
* @throws NotLoadedException If the descriptor is not loaded. |
314
|
|
|
* |
315
|
|
|
* @see BindingState::TYPE_NOT_ENABLED |
316
|
|
|
*/ |
317
|
15 |
View Code Duplication |
public function isTypeNotEnabled() |
|
|
|
|
318
|
|
|
{ |
319
|
15 |
|
if (null === $this->state) { |
320
|
|
|
throw new NotLoadedException('The binding descriptor is not loaded.'); |
321
|
|
|
} |
322
|
|
|
|
323
|
15 |
|
return BindingState::TYPE_NOT_ENABLED === $this->state; |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
/** |
327
|
|
|
* Returns whether the binding is invalid. |
328
|
|
|
* |
329
|
|
|
* The method {@link load()} needs to be called before calling this method, |
330
|
|
|
* otherwise an exception is thrown. |
331
|
|
|
* |
332
|
|
|
* @return bool Returns `true` if the state is {@link BindingState::INVALID}. |
333
|
|
|
* |
334
|
|
|
* @throws NotLoadedException If the descriptor is not loaded. |
335
|
|
|
* |
336
|
|
|
* @see BindingState::INVALID |
337
|
|
|
*/ |
338
|
|
View Code Duplication |
public function isInvalid() |
|
|
|
|
339
|
|
|
{ |
340
|
|
|
if (null === $this->state) { |
341
|
|
|
throw new NotLoadedException('The binding descriptor is not loaded.'); |
342
|
|
|
} |
343
|
|
|
|
344
|
|
|
return BindingState::INVALID === $this->state; |
345
|
|
|
} |
346
|
|
|
|
347
|
64 |
|
private function refreshState() |
348
|
|
|
{ |
349
|
64 |
|
if (null === $this->typeDescriptor || !$this->typeDescriptor->isLoaded()) { |
350
|
13 |
|
$this->state = BindingState::TYPE_NOT_FOUND; |
351
|
56 |
|
} elseif (!$this->typeDescriptor->isEnabled()) { |
352
|
8 |
|
$this->state = BindingState::TYPE_NOT_ENABLED; |
353
|
49 |
|
} elseif (count($this->loadErrors) > 0) { |
354
|
6 |
|
$this->state = BindingState::INVALID; |
355
|
43 |
|
} elseif ($this->containingModule instanceof RootModule) { |
356
|
25 |
|
$this->state = BindingState::ENABLED; |
357
|
24 |
|
} elseif ($this->containingModule->getInstallInfo()->hasDisabledBindingUuid($this->binding->getUuid())) { |
358
|
12 |
|
$this->state = BindingState::DISABLED; |
359
|
|
|
} else { |
360
|
20 |
|
$this->state = BindingState::ENABLED; |
361
|
|
|
} |
362
|
64 |
|
} |
363
|
|
|
} |
364
|
|
|
|
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.