These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
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\Discovery; |
||
13 | |||
14 | use Exception; |
||
15 | use Psr\Log\LoggerInterface; |
||
16 | use Psr\Log\NullLogger; |
||
17 | use Puli\Discovery\Api\Binding\Binding; |
||
18 | use Puli\Discovery\Api\EditableDiscovery; |
||
19 | use Puli\Manager\Api\Context\ProjectContext; |
||
20 | use Puli\Manager\Api\Discovery\BindingDescriptor; |
||
21 | use Puli\Manager\Api\Discovery\BindingTypeDescriptor; |
||
22 | use Puli\Manager\Api\Discovery\DiscoveryManager; |
||
23 | use Puli\Manager\Api\Discovery\DiscoveryNotEmptyException; |
||
24 | use Puli\Manager\Api\Discovery\DuplicateBindingException; |
||
25 | use Puli\Manager\Api\Discovery\DuplicateTypeException; |
||
26 | use Puli\Manager\Api\Discovery\NoSuchBindingException; |
||
27 | use Puli\Manager\Api\Discovery\NoSuchTypeException; |
||
28 | use Puli\Manager\Api\Discovery\TypeNotEnabledException; |
||
29 | use Puli\Manager\Api\Module\InstallInfo; |
||
30 | use Puli\Manager\Api\Module\Module; |
||
31 | use Puli\Manager\Api\Module\ModuleList; |
||
32 | use Puli\Manager\Api\Module\RootModule; |
||
33 | use Puli\Manager\Api\Module\RootModuleFile; |
||
34 | use Puli\Manager\Api\NonRootModuleExpectedException; |
||
35 | use Puli\Manager\Assert\Assert; |
||
36 | use Puli\Manager\Discovery\Binding\AddBinding; |
||
37 | use Puli\Manager\Discovery\Binding\AddBindingDescriptorToModuleFile; |
||
38 | use Puli\Manager\Discovery\Binding\BindingDescriptorCollection; |
||
39 | use Puli\Manager\Discovery\Binding\DisableBindingUuid; |
||
40 | use Puli\Manager\Discovery\Binding\EnableBindingUuid; |
||
41 | use Puli\Manager\Discovery\Binding\LoadBindingDescriptor; |
||
42 | use Puli\Manager\Discovery\Binding\ReloadBindingDescriptorsByTypeName; |
||
43 | use Puli\Manager\Discovery\Binding\RemoveBindingDescriptorFromModuleFile; |
||
44 | use Puli\Manager\Discovery\Binding\SyncBinding; |
||
45 | use Puli\Manager\Discovery\Binding\UnloadBindingDescriptor; |
||
46 | use Puli\Manager\Discovery\Type\AddBindingType; |
||
47 | use Puli\Manager\Discovery\Type\AddTypeDescriptorToModuleFile; |
||
48 | use Puli\Manager\Discovery\Type\BindingTypeDescriptorCollection; |
||
49 | use Puli\Manager\Discovery\Type\LoadTypeDescriptor; |
||
50 | use Puli\Manager\Discovery\Type\RemoveTypeDescriptorFromModuleFile; |
||
51 | use Puli\Manager\Discovery\Type\SyncTypeName; |
||
52 | use Puli\Manager\Discovery\Type\UnloadTypeDescriptor; |
||
53 | use Puli\Manager\Discovery\Type\UpdateDuplicateMarksForTypeName; |
||
54 | use Puli\Manager\Json\JsonStorage; |
||
55 | use Puli\Manager\Transaction\InterceptedOperation; |
||
56 | use Puli\Manager\Transaction\Transaction; |
||
57 | use Rhumsaa\Uuid\Uuid; |
||
58 | use Webmozart\Expression\Expr; |
||
59 | use Webmozart\Expression\Expression; |
||
60 | |||
61 | /** |
||
62 | * @since 1.0 |
||
63 | * |
||
64 | * @author Bernhard Schussek <[email protected]> |
||
65 | */ |
||
66 | class DiscoveryManagerImpl implements DiscoveryManager |
||
67 | { |
||
68 | /** |
||
69 | * @var ProjectContext |
||
70 | */ |
||
71 | private $context; |
||
72 | |||
73 | /** |
||
74 | * @var LoggerInterface |
||
75 | */ |
||
76 | private $logger; |
||
77 | |||
78 | /** |
||
79 | * @var EditableDiscovery |
||
80 | */ |
||
81 | private $discovery; |
||
82 | |||
83 | /** |
||
84 | * @var ModuleList |
||
85 | */ |
||
86 | private $modules; |
||
87 | |||
88 | /** |
||
89 | * @var JsonStorage |
||
90 | */ |
||
91 | private $jsonStorage; |
||
92 | |||
93 | /** |
||
94 | * @var RootModule |
||
95 | */ |
||
96 | private $rootModule; |
||
97 | |||
98 | /** |
||
99 | * @var RootModuleFile |
||
100 | */ |
||
101 | private $rootModuleFile; |
||
102 | |||
103 | /** |
||
104 | * @var BindingTypeDescriptorCollection |
||
105 | */ |
||
106 | private $typeDescriptors; |
||
107 | |||
108 | /** |
||
109 | * @var BindingDescriptorCollection |
||
110 | */ |
||
111 | private $bindingDescriptors; |
||
112 | |||
113 | /** |
||
114 | * Creates a tag manager. |
||
115 | * |
||
116 | * @param ProjectContext $context |
||
117 | * @param EditableDiscovery $discovery |
||
118 | * @param ModuleList $modules |
||
119 | * @param JsonStorage $jsonStorage |
||
120 | * @param LoggerInterface|null $logger |
||
121 | */ |
||
122 | 98 | public function __construct( |
|
123 | ProjectContext $context, |
||
124 | EditableDiscovery $discovery, |
||
125 | ModuleList $modules, |
||
126 | JsonStorage $jsonStorage, |
||
127 | LoggerInterface $logger = null |
||
128 | ) { |
||
129 | 98 | $this->context = $context; |
|
130 | 98 | $this->discovery = $discovery; |
|
131 | 98 | $this->modules = $modules; |
|
132 | 98 | $this->jsonStorage = $jsonStorage; |
|
133 | 98 | $this->rootModule = $modules->getRootModule(); |
|
134 | 98 | $this->rootModuleFile = $context->getRootModuleFile(); |
|
135 | 98 | $this->logger = $logger ?: new NullLogger(); |
|
136 | 98 | } |
|
137 | |||
138 | /** |
||
139 | * {@inheritdoc} |
||
140 | */ |
||
141 | 1 | public function getContext() |
|
142 | { |
||
143 | 1 | return $this->context; |
|
144 | } |
||
145 | |||
146 | /** |
||
147 | * {@inheritdoc} |
||
148 | */ |
||
149 | 5 | public function addRootTypeDescriptor(BindingTypeDescriptor $typeDescriptor, $flags = 0) |
|
150 | { |
||
151 | 5 | Assert::integer($flags, 'The argument $flags must be a boolean.'); |
|
152 | |||
153 | 5 | $this->assertModulesLoaded(); |
|
154 | 5 | $this->emitWarningForDuplicateTypes(); |
|
155 | |||
156 | 5 | $typeName = $typeDescriptor->getTypeName(); |
|
157 | |||
158 | 5 | if (!($flags & self::OVERRIDE) && $this->typeDescriptors->contains($typeName)) { |
|
159 | 1 | throw DuplicateTypeException::forTypeName($typeName); |
|
160 | } |
||
161 | |||
162 | 4 | $tx = new Transaction(); |
|
163 | |||
164 | try { |
||
165 | 4 | $syncBindingOps = array(); |
|
166 | |||
167 | 4 | View Code Duplication | foreach ($this->getUuidsByTypeName($typeName) as $uuid) { |
0 ignored issues
–
show
|
|||
168 | $syncBindingOp = $this->syncBinding($uuid); |
||
169 | $syncBindingOp->takeSnapshot(); |
||
170 | $syncBindingOps[] = $syncBindingOp; |
||
171 | } |
||
172 | |||
173 | $syncOp = $this->syncTypeName($typeName); |
||
174 | $syncOp->takeSnapshot(); |
||
175 | |||
176 | $tx->execute($this->loadTypeDescriptor($typeDescriptor, $this->rootModule)); |
||
177 | $tx->execute($this->addTypeDescriptorToModuleFile($typeDescriptor)); |
||
178 | $tx->execute($syncOp); |
||
179 | |||
180 | foreach ($syncBindingOps as $syncBindingOp) { |
||
181 | $tx->execute($syncBindingOp); |
||
182 | } |
||
183 | |||
184 | $this->saveRootModuleFile(); |
||
185 | |||
186 | $tx->commit(); |
||
187 | 4 | } catch (Exception $e) { |
|
188 | $tx->rollback(); |
||
189 | |||
190 | throw $e; |
||
191 | } |
||
192 | } |
||
193 | |||
194 | /** |
||
195 | * {@inheritdoc} |
||
196 | */ |
||
197 | 11 | public function removeRootTypeDescriptor($typeName) |
|
198 | { |
||
199 | // Only check that this is a string. The error message "not found" is |
||
200 | // more helpful than e.g. "type name must contain /". |
||
201 | 11 | Assert::string($typeName, 'The type name must be a string'); |
|
202 | |||
203 | 11 | $this->assertModulesLoaded(); |
|
204 | |||
205 | 11 | if (!$this->typeDescriptors->contains($typeName, $this->rootModule->getName())) { |
|
206 | 2 | return; |
|
207 | } |
||
208 | |||
209 | 9 | $typeDescriptor = $this->typeDescriptors->get($typeName, $this->rootModule->getName()); |
|
210 | 9 | $tx = new Transaction(); |
|
211 | |||
212 | try { |
||
213 | 9 | $tx->execute($this->removeTypeDescriptorFromModuleFile($typeName)); |
|
214 | |||
215 | 9 | $syncBindingOps = array(); |
|
216 | |||
217 | 9 | View Code Duplication | foreach ($this->getUuidsByTypeName($typeName) as $uuid) { |
0 ignored issues
–
show
The method
getUuidsByTypeName() does not seem to exist on object<Puli\Manager\Disc...y\DiscoveryManagerImpl> .
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||
218 | $syncBindingOp = $this->syncBinding($uuid); |
||
219 | $syncBindingOp->takeSnapshot(); |
||
220 | $syncBindingOps[] = $syncBindingOp; |
||
221 | } |
||
222 | |||
223 | $syncOp = $this->syncTypeName($typeName); |
||
224 | $syncOp->takeSnapshot(); |
||
225 | |||
226 | $tx->execute($this->unloadTypeDescriptor($typeDescriptor)); |
||
227 | $tx->execute($syncOp); |
||
228 | |||
229 | foreach ($syncBindingOps as $syncBindingOp) { |
||
230 | $tx->execute($syncBindingOp); |
||
231 | } |
||
232 | |||
233 | $this->saveRootModuleFile(); |
||
234 | |||
235 | $tx->commit(); |
||
236 | 9 | } catch (Exception $e) { |
|
237 | $tx->rollback(); |
||
238 | |||
239 | throw $e; |
||
240 | } |
||
241 | |||
242 | $this->emitWarningForDuplicateTypes(); |
||
243 | } |
||
244 | |||
245 | /** |
||
246 | * {@inheritdoc} |
||
247 | */ |
||
248 | 4 | public function removeRootTypeDescriptors(Expression $expr) |
|
249 | { |
||
250 | 4 | $this->assertModulesLoaded(); |
|
251 | |||
252 | 4 | $tx = new Transaction(); |
|
253 | 4 | $syncBindingOps = array(); |
|
254 | |||
255 | try { |
||
256 | 4 | foreach ($this->getRootTypeDescriptors() as $typeDescriptor) { |
|
257 | 4 | if ($expr->evaluate($typeDescriptor)) { |
|
258 | 4 | $typeName = $typeDescriptor->getTypeName(); |
|
259 | |||
260 | 4 | $tx->execute($this->removeTypeDescriptorFromModuleFile($typeName)); |
|
261 | |||
262 | 4 | View Code Duplication | foreach ($this->getUuidsByTypeName($typeName) as $uuid) { |
0 ignored issues
–
show
The method
getUuidsByTypeName() does not seem to exist on object<Puli\Manager\Disc...y\DiscoveryManagerImpl> .
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||
263 | $syncBindingOp = $this->syncBinding($uuid); |
||
264 | $syncBindingOp->takeSnapshot(); |
||
265 | $syncBindingOps[] = $syncBindingOp; |
||
266 | } |
||
267 | |||
268 | $syncOp = $this->syncTypeName($typeName); |
||
269 | $syncOp->takeSnapshot(); |
||
270 | |||
271 | $tx->execute($this->unloadTypeDescriptor($typeDescriptor)); |
||
272 | $tx->execute($syncOp); |
||
273 | } |
||
274 | } |
||
275 | |||
276 | foreach ($syncBindingOps as $syncBindingOp) { |
||
277 | $tx->execute($syncBindingOp); |
||
278 | } |
||
279 | |||
280 | $this->saveRootModuleFile(); |
||
281 | |||
282 | $tx->commit(); |
||
283 | 4 | } catch (Exception $e) { |
|
284 | $tx->rollback(); |
||
285 | |||
286 | throw $e; |
||
287 | } |
||
288 | |||
289 | $this->emitWarningForDuplicateTypes(); |
||
290 | } |
||
291 | |||
292 | /** |
||
293 | * {@inheritdoc} |
||
294 | */ |
||
295 | 1 | public function clearRootTypeDescriptors() |
|
296 | { |
||
297 | 1 | $this->removeRootTypeDescriptors(Expr::true()); |
|
298 | } |
||
299 | |||
300 | /** |
||
301 | * {@inheritdoc} |
||
302 | */ |
||
303 | 2 | public function getRootTypeDescriptor($typeName) |
|
304 | { |
||
305 | 2 | return $this->getTypeDescriptor($typeName, $this->rootModule->getName()); |
|
306 | } |
||
307 | |||
308 | /** |
||
309 | * {@inheritdoc} |
||
310 | */ |
||
311 | 5 | View Code Duplication | public function getRootTypeDescriptors() |
312 | { |
||
313 | 5 | $this->assertModulesLoaded(); |
|
314 | |||
315 | 5 | $types = array(); |
|
316 | 5 | $rootModuleName = $this->rootModule->getName(); |
|
317 | |||
318 | 5 | foreach ($this->typeDescriptors->toArray() as $typeName => $typesByModule) { |
|
319 | 5 | if (isset($typesByModule[$rootModuleName])) { |
|
320 | 5 | $types[] = $typesByModule[$rootModuleName]; |
|
321 | } |
||
322 | } |
||
323 | |||
324 | 5 | return $types; |
|
325 | } |
||
326 | |||
327 | /** |
||
328 | * {@inheritdoc} |
||
329 | */ |
||
330 | 1 | View Code Duplication | public function findRootTypeDescriptors(Expression $expr) |
331 | { |
||
332 | 1 | $expr = Expr::method('getContainingModule', Expr::same($this->rootModule)) |
|
333 | 1 | ->andX($expr); |
|
334 | |||
335 | 1 | return $this->findTypeDescriptors($expr); |
|
336 | } |
||
337 | |||
338 | /** |
||
339 | * {@inheritdoc} |
||
340 | */ |
||
341 | 1 | public function hasRootTypeDescriptor($typeName) |
|
342 | { |
||
343 | 1 | return $this->hasTypeDescriptor($typeName, $this->rootModule->getName()); |
|
344 | } |
||
345 | |||
346 | /** |
||
347 | * {@inheritdoc} |
||
348 | */ |
||
349 | 1 | View Code Duplication | public function hasRootTypeDescriptors(Expression $expr = null) |
350 | { |
||
351 | 1 | $expr2 = Expr::method('getContainingModule', Expr::same($this->rootModule)); |
|
352 | |||
353 | 1 | if ($expr) { |
|
354 | 1 | $expr2 = $expr2->andX($expr); |
|
355 | } |
||
356 | |||
357 | 1 | return $this->hasTypeDescriptors($expr2); |
|
358 | } |
||
359 | |||
360 | /** |
||
361 | * {@inheritdoc} |
||
362 | */ |
||
363 | 6 | public function getTypeDescriptor($typeName, $moduleName) |
|
364 | { |
||
365 | 6 | Assert::string($typeName, 'The type name must be a string. Got: %s'); |
|
366 | 5 | Assert::string($moduleName, 'The module name must be a string. Got: %s'); |
|
367 | |||
368 | 4 | $this->assertModulesLoaded(); |
|
369 | |||
370 | 4 | if (!$this->typeDescriptors->contains($typeName, $moduleName)) { |
|
371 | 2 | throw NoSuchTypeException::forTypeName($typeName); |
|
372 | } |
||
373 | |||
374 | 2 | return $this->typeDescriptors->get($typeName, $moduleName); |
|
375 | } |
||
376 | |||
377 | /** |
||
378 | * {@inheritdoc} |
||
379 | */ |
||
380 | 2 | public function getTypeDescriptors() |
|
381 | { |
||
382 | 2 | $this->assertModulesLoaded(); |
|
383 | |||
384 | 2 | $types = array(); |
|
385 | |||
386 | 2 | foreach ($this->typeDescriptors->toArray() as $typeName => $typesByModule) { |
|
387 | 1 | foreach ($typesByModule as $type) { |
|
388 | 1 | $types[] = $type; |
|
389 | } |
||
390 | } |
||
391 | |||
392 | 2 | return $types; |
|
393 | } |
||
394 | |||
395 | /** |
||
396 | * {@inheritdoc} |
||
397 | */ |
||
398 | 2 | View Code Duplication | public function findTypeDescriptors(Expression $expr) |
399 | { |
||
400 | 2 | $this->assertModulesLoaded(); |
|
401 | |||
402 | 2 | $typeDescriptors = array(); |
|
403 | |||
404 | 2 | foreach ($this->typeDescriptors->toArray() as $typeName => $descriptorsByModule) { |
|
405 | 2 | foreach ($descriptorsByModule as $typeDescriptor) { |
|
406 | 2 | if ($expr->evaluate($typeDescriptor)) { |
|
407 | 2 | $typeDescriptors[] = $typeDescriptor; |
|
408 | } |
||
409 | } |
||
410 | } |
||
411 | |||
412 | 2 | return $typeDescriptors; |
|
413 | } |
||
414 | |||
415 | /** |
||
416 | * {@inheritdoc} |
||
417 | */ |
||
418 | 3 | public function hasTypeDescriptor($typeName, $moduleName = null) |
|
419 | { |
||
420 | 3 | Assert::nullOrString($moduleName, 'The module name must be a string or null. Got: %s'); |
|
421 | |||
422 | 2 | $this->assertModulesLoaded(); |
|
423 | |||
424 | 2 | return $this->typeDescriptors->contains($typeName, $moduleName); |
|
425 | } |
||
426 | |||
427 | /** |
||
428 | * {@inheritdoc} |
||
429 | */ |
||
430 | 3 | public function hasTypeDescriptors(Expression $expr = null) |
|
431 | { |
||
432 | 3 | $this->assertModulesLoaded(); |
|
433 | |||
434 | 3 | if (!$expr) { |
|
435 | 2 | return !$this->typeDescriptors->isEmpty(); |
|
436 | } |
||
437 | |||
438 | 2 | foreach ($this->typeDescriptors->toArray() as $typeName => $descriptorsByModule) { |
|
439 | 2 | foreach ($descriptorsByModule as $typeDescriptor) { |
|
440 | 2 | if ($expr->evaluate($typeDescriptor)) { |
|
441 | 2 | return true; |
|
442 | } |
||
443 | } |
||
444 | } |
||
445 | |||
446 | 2 | return false; |
|
447 | } |
||
448 | |||
449 | /** |
||
450 | * {@inheritdoc} |
||
451 | */ |
||
452 | 12 | public function addRootBindingDescriptor(BindingDescriptor $bindingDescriptor, $flags = 0) |
|
453 | { |
||
454 | 12 | $this->assertModulesLoaded(); |
|
455 | |||
456 | 12 | $typeName = $bindingDescriptor->getTypeName(); |
|
457 | 12 | $typeExists = $this->typeDescriptors->contains($typeName); |
|
458 | |||
459 | 12 | if (!($flags & self::IGNORE_TYPE_NOT_FOUND) && !$typeExists) { |
|
460 | 2 | throw NoSuchTypeException::forTypeName($typeName); |
|
461 | } |
||
462 | |||
463 | 10 | if (!($flags & self::IGNORE_TYPE_NOT_ENABLED) && $typeExists && !$this->typeDescriptors->getFirst($typeName)->isEnabled()) { |
|
464 | 2 | throw TypeNotEnabledException::forTypeName($typeName); |
|
465 | } |
||
466 | |||
467 | 8 | $binding = $bindingDescriptor->getBinding(); |
|
468 | 8 | $exists = $this->bindingDescriptors->contains($binding); |
|
469 | 8 | $existsInNonRoot = $exists |
|
470 | 3 | ? !$this->bindingDescriptors->contains($binding, $this->rootModule->getName()) |
|
471 | 8 | : false; |
|
472 | |||
473 | // We can only override bindings in the root module |
||
474 | 8 | if ($existsInNonRoot || ($exists && !($flags & self::OVERRIDE))) { |
|
475 | 2 | throw DuplicateBindingException::forUuid($binding); |
|
476 | } |
||
477 | |||
478 | 6 | $tx = new Transaction(); |
|
479 | |||
480 | try { |
||
481 | 6 | $syncOp = $this->syncBinding($binding); |
|
482 | 6 | $syncOp->takeSnapshot(); |
|
483 | |||
484 | 6 | $tx->execute($this->loadBindingDescriptor($bindingDescriptor, $this->rootModule)); |
|
485 | |||
486 | 6 | $this->assertBindingValid($bindingDescriptor); |
|
487 | |||
488 | 5 | $tx->execute($this->addBindingDescriptorToModuleFile($bindingDescriptor)); |
|
489 | 5 | $tx->execute($syncOp); |
|
490 | |||
491 | 5 | $this->saveRootModuleFile(); |
|
492 | |||
493 | 3 | $tx->commit(); |
|
494 | 3 | } catch (Exception $e) { |
|
495 | 3 | $tx->rollback(); |
|
496 | |||
497 | throw $e; |
||
498 | } |
||
499 | 3 | } |
|
500 | |||
501 | /** |
||
502 | * {@inheritdoc} |
||
503 | */ |
||
504 | 3 | View Code Duplication | public function removeRootBindingDescriptors(Expression $expr) |
505 | { |
||
506 | 3 | $this->assertModulesLoaded(); |
|
507 | |||
508 | 3 | $tx = new Transaction(); |
|
509 | |||
510 | try { |
||
511 | 3 | foreach ($this->getRootBindingDescriptors() as $bindingDescriptor) { |
|
512 | if ($expr->evaluate($bindingDescriptor)) { |
||
513 | $syncOp = $this->syncBinding($bindingDescriptor->getUuid()); |
||
0 ignored issues
–
show
The method
getUuid() does not seem to exist on object<Puli\Manager\Api\...very\BindingDescriptor> .
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||
514 | $syncOp->takeSnapshot(); |
||
515 | |||
516 | $tx->execute($this->unloadBindingDescriptor($bindingDescriptor)); |
||
517 | $tx->execute($syncOp); |
||
518 | $tx->execute($this->removeBindingDescriptorFromModuleFile($bindingDescriptor->getUuid())); |
||
0 ignored issues
–
show
The method
getUuid() does not seem to exist on object<Puli\Manager\Api\...very\BindingDescriptor> .
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||
519 | } |
||
520 | } |
||
521 | |||
522 | $this->saveRootModuleFile(); |
||
523 | |||
524 | $tx->commit(); |
||
525 | 3 | } catch (Exception $e) { |
|
526 | $tx->rollback(); |
||
527 | |||
528 | throw $e; |
||
529 | } |
||
530 | } |
||
531 | |||
532 | /** |
||
533 | * {@inheritdoc} |
||
534 | */ |
||
535 | 1 | public function clearRootBindingDescriptors() |
|
536 | { |
||
537 | 1 | $this->removeRootBindingDescriptors(Expr::true()); |
|
538 | } |
||
539 | |||
540 | /** |
||
541 | * {@inheritdoc} |
||
542 | */ |
||
543 | 3 | View Code Duplication | public function getRootBindingDescriptors() |
544 | { |
||
545 | 3 | $this->assertModulesLoaded(); |
|
546 | |||
547 | 3 | $bindings = array(); |
|
548 | |||
549 | 3 | foreach ($this->bindingDescriptors->toArray() as $binding) { |
|
550 | 3 | if ($binding->getContainingModule() instanceof RootModule) { |
|
0 ignored issues
–
show
|
|||
551 | $bindings[] = $binding; |
||
552 | } |
||
553 | } |
||
554 | |||
555 | return $bindings; |
||
556 | } |
||
557 | |||
558 | /** |
||
559 | * {@inheritdoc} |
||
560 | */ |
||
561 | 1 | View Code Duplication | public function findRootBindingDescriptors(Expression $expr) |
562 | { |
||
563 | 1 | $expr = Expr::method('getContainingModule', Expr::same($this->rootModule)) |
|
564 | 1 | ->andX($expr); |
|
565 | |||
566 | 1 | return $this->findBindingDescriptors($expr); |
|
567 | } |
||
568 | |||
569 | /** |
||
570 | * {@inheritdoc} |
||
571 | */ |
||
572 | 1 | View Code Duplication | public function hasRootBindingDescriptors(Expression $expr = null) |
573 | { |
||
574 | 1 | $expr2 = Expr::method('getContainingModule', Expr::same($this->rootModule)); |
|
575 | |||
576 | 1 | if ($expr) { |
|
577 | $expr2 = $expr2->andX($expr); |
||
578 | } |
||
579 | |||
580 | 1 | return $this->hasBindingDescriptors($expr2); |
|
581 | } |
||
582 | |||
583 | /** |
||
584 | * {@inheritdoc} |
||
585 | */ |
||
586 | 1 | public function getBindingDescriptors() |
|
587 | { |
||
588 | 1 | $this->assertModulesLoaded(); |
|
589 | |||
590 | 1 | return array_values($this->bindingDescriptors->toArray()); |
|
591 | } |
||
592 | |||
593 | /** |
||
594 | * {@inheritdoc} |
||
595 | */ |
||
596 | 2 | View Code Duplication | public function findBindingDescriptors(Expression $expr) |
597 | { |
||
598 | 2 | $this->assertModulesLoaded(); |
|
599 | |||
600 | 2 | $descriptors = array(); |
|
601 | |||
602 | 2 | foreach ($this->bindingDescriptors->toArray() as $descriptor) { |
|
603 | 2 | if ($expr->evaluate($descriptor)) { |
|
604 | 2 | $descriptors[] = $descriptor; |
|
605 | } |
||
606 | } |
||
607 | |||
608 | 2 | return $descriptors; |
|
609 | } |
||
610 | |||
611 | /** |
||
612 | * {@inheritdoc} |
||
613 | */ |
||
614 | 3 | View Code Duplication | public function hasBindingDescriptors(Expression $expr = null) |
615 | { |
||
616 | 3 | $this->assertModulesLoaded(); |
|
617 | |||
618 | 3 | if (!$expr) { |
|
619 | 2 | return !$this->bindingDescriptors->isEmpty(); |
|
620 | } |
||
621 | |||
622 | 2 | foreach ($this->bindingDescriptors->toArray() as $bindingDescriptor) { |
|
623 | 2 | if ($expr->evaluate($bindingDescriptor)) { |
|
624 | 2 | return true; |
|
625 | } |
||
626 | } |
||
627 | |||
628 | 2 | return false; |
|
629 | } |
||
630 | |||
631 | /** |
||
632 | * {@inheritdoc} |
||
633 | */ |
||
634 | 7 | public function buildDiscovery() |
|
635 | { |
||
636 | 7 | $this->assertModulesLoaded(); |
|
637 | 7 | $this->emitWarningForDuplicateTypes(); |
|
638 | 7 | $this->emitWarningForInvalidBindings(); |
|
639 | |||
640 | 3 | if ($this->discovery->hasBindings() || $this->discovery->hasBindingTypes()) { |
|
641 | 2 | throw new DiscoveryNotEmptyException('The discovery is not empty.'); |
|
642 | } |
||
643 | |||
644 | 1 | $tx = new Transaction(); |
|
645 | |||
646 | try { |
||
647 | 1 | foreach ($this->typeDescriptors->toArray() as $typeName => $descriptorsByModule) { |
|
648 | 1 | foreach ($descriptorsByModule as $typeDescriptor) { |
|
649 | 1 | if ($typeDescriptor->isEnabled()) { |
|
650 | 1 | $tx->execute($this->addBindingType($typeDescriptor)); |
|
651 | } |
||
652 | } |
||
653 | } |
||
654 | |||
655 | 1 | foreach ($this->bindingDescriptors->toArray() as $bindingDescriptor) { |
|
656 | if ($bindingDescriptor->isEnabled()) { |
||
0 ignored issues
–
show
|
|||
657 | $tx->execute($this->addBinding($bindingDescriptor)); |
||
658 | } |
||
659 | } |
||
660 | |||
661 | 1 | $tx->commit(); |
|
662 | } catch (Exception $e) { |
||
663 | $tx->rollback(); |
||
664 | |||
665 | throw $e; |
||
666 | } |
||
667 | 1 | } |
|
668 | |||
669 | /** |
||
670 | * {@inheritdoc} |
||
671 | */ |
||
672 | 1 | public function clearDiscovery() |
|
673 | { |
||
674 | 1 | $this->discovery->removeBindingTypes(); |
|
675 | 1 | } |
|
676 | |||
677 | 61 | private function assertModulesLoaded() |
|
678 | { |
||
679 | 61 | if (!$this->typeDescriptors) { |
|
680 | 61 | $this->loadModules(); |
|
681 | } |
||
682 | 61 | } |
|
683 | |||
684 | 6 | private function assertBindingValid(BindingDescriptor $bindingDescriptor) |
|
685 | { |
||
686 | 6 | if ($bindingDescriptor->isTypeNotFound() || $bindingDescriptor->isTypeNotEnabled()) { |
|
687 | 2 | return; |
|
688 | } |
||
689 | |||
690 | 4 | foreach ($bindingDescriptor->getLoadErrors() as $exception) { |
|
691 | 1 | throw $exception; |
|
692 | } |
||
693 | 3 | } |
|
694 | |||
695 | 61 | private function loadModules() |
|
696 | { |
||
697 | 61 | $this->typeDescriptors = new BindingTypeDescriptorCollection(); |
|
698 | 61 | $this->bindingDescriptors = new BindingDescriptorCollection(); |
|
699 | |||
700 | // First load all the types |
||
701 | 61 | View Code Duplication | foreach ($this->modules as $module) { |
702 | 61 | if (null === $module->getModuleFile()) { |
|
703 | 1 | continue; |
|
704 | } |
||
705 | |||
706 | 61 | foreach ($module->getModuleFile()->getTypeDescriptors() as $typeDescriptor) { |
|
707 | 61 | $this->loadTypeDescriptor($typeDescriptor, $module)->execute(); |
|
708 | } |
||
709 | } |
||
710 | |||
711 | // Then the bindings for the loaded types |
||
712 | 61 | foreach ($this->modules as $module) { |
|
713 | 61 | if (null === $module->getModuleFile()) { |
|
714 | 1 | continue; |
|
715 | } |
||
716 | |||
717 | 61 | foreach ($module->getModuleFile()->getBindingDescriptors() as $bindingDescriptor) { |
|
718 | 61 | $this->loadBindingDescriptor($bindingDescriptor, $module)->execute(); |
|
719 | } |
||
720 | } |
||
721 | 61 | } |
|
722 | |||
723 | 12 | private function emitWarningForDuplicateTypes() |
|
724 | { |
||
725 | 12 | foreach ($this->typeDescriptors->getTypeNames() as $typeName) { |
|
726 | 7 | $moduleNames = $this->typeDescriptors->getModuleNames($typeName); |
|
727 | |||
728 | 7 | if (count($moduleNames) > 1) { |
|
729 | 1 | $lastModuleName = array_pop($moduleNames); |
|
730 | |||
731 | 1 | $this->logger->warning(sprintf( |
|
732 | 'The modules "%s" and "%s" contain type definitions for '. |
||
733 | 1 | 'the same type "%s". The type has been disabled.', |
|
734 | 7 | implode('", "', $moduleNames), |
|
735 | $lastModuleName, |
||
736 | $typeName |
||
737 | )); |
||
738 | } |
||
739 | } |
||
740 | 12 | } |
|
741 | |||
742 | 7 | private function emitWarningForInvalidBindings() |
|
743 | { |
||
744 | 7 | foreach ($this->bindingDescriptors->toArray() as $binding) { |
|
745 | 4 | foreach ($binding->getLoadErrors() as $exception) { |
|
0 ignored issues
–
show
|
|||
746 | $this->logger->warning(sprintf( |
||
747 | 'The binding "%s" in module "%s" is invalid: %s', |
||
748 | $binding->getUuid()->toString(), |
||
0 ignored issues
–
show
|
|||
749 | $binding->getContainingModule()->getName(), |
||
0 ignored issues
–
show
|
|||
750 | $exception->getMessage() |
||
751 | )); |
||
752 | } |
||
753 | } |
||
754 | 3 | } |
|
755 | |||
756 | 5 | private function saveRootModuleFile() |
|
757 | { |
||
758 | 5 | $this->jsonStorage->saveRootModuleFile($this->rootModuleFile); |
|
759 | 3 | } |
|
760 | |||
761 | private function addTypeDescriptorToModuleFile(BindingTypeDescriptor $typeDescriptor) |
||
762 | { |
||
763 | return new AddTypeDescriptorToModuleFile($typeDescriptor, $this->rootModuleFile); |
||
764 | } |
||
765 | |||
766 | 13 | private function removeTypeDescriptorFromModuleFile($typeName) |
|
767 | { |
||
768 | 13 | return new RemoveTypeDescriptorFromModuleFile($typeName, $this->rootModuleFile); |
|
769 | } |
||
770 | |||
771 | 48 | View Code Duplication | private function loadTypeDescriptor(BindingTypeDescriptor $typeDescriptor, Module $module) |
772 | { |
||
773 | 48 | $typeName = $typeDescriptor->getTypeName(); |
|
774 | |||
775 | 48 | return new InterceptedOperation( |
|
776 | 48 | new LoadTypeDescriptor($typeDescriptor, $module, $this->typeDescriptors), |
|
777 | array( |
||
778 | 48 | new UpdateDuplicateMarksForTypeName($typeName, $this->typeDescriptors), |
|
779 | 48 | new ReloadBindingDescriptorsByTypeName($typeName, $this->bindingDescriptors, $this->typeDescriptors), |
|
780 | ) |
||
781 | ); |
||
782 | } |
||
783 | |||
784 | View Code Duplication | private function unloadTypeDescriptor(BindingTypeDescriptor $typeDescriptor) |
|
785 | { |
||
786 | $typeName = $typeDescriptor->getTypeName(); |
||
787 | |||
788 | return new InterceptedOperation( |
||
789 | new UnloadTypeDescriptor($typeDescriptor, $this->typeDescriptors), |
||
790 | array( |
||
791 | new UpdateDuplicateMarksForTypeName($typeName, $this->typeDescriptors), |
||
792 | new ReloadBindingDescriptorsByTypeName($typeName, $this->bindingDescriptors, $this->typeDescriptors), |
||
793 | ) |
||
794 | ); |
||
795 | } |
||
796 | |||
797 | private function addBindingType(BindingTypeDescriptor $typeDescriptor) |
||
798 | { |
||
799 | return new AddBindingType($typeDescriptor, $this->discovery); |
||
800 | } |
||
801 | |||
802 | private function syncTypeName($typeName) |
||
803 | { |
||
804 | return new SyncTypeName($typeName, $this->discovery, $this->typeDescriptors); |
||
805 | } |
||
806 | |||
807 | 5 | private function addBindingDescriptorToModuleFile(BindingDescriptor $bindingDescriptor) |
|
808 | { |
||
809 | 5 | return new AddBindingDescriptorToModuleFile($bindingDescriptor, $this->rootModuleFile); |
|
810 | } |
||
811 | |||
812 | private function removeBindingDescriptorFromModuleFile(Uuid $uuid) |
||
813 | { |
||
814 | return new RemoveBindingDescriptorFromModuleFile($uuid, $this->rootModuleFile); |
||
815 | } |
||
816 | |||
817 | 24 | private function loadBindingDescriptor(BindingDescriptor $bindingDescriptor, Module $module) |
|
818 | { |
||
819 | 24 | return new LoadBindingDescriptor($bindingDescriptor, $module, $this->bindingDescriptors, $this->typeDescriptors); |
|
820 | } |
||
821 | |||
822 | private function unloadBindingDescriptor(BindingDescriptor $bindingDescriptor) |
||
823 | { |
||
824 | return new UnloadBindingDescriptor($bindingDescriptor, $this->bindingDescriptors); |
||
825 | } |
||
826 | |||
827 | private function addBinding(BindingDescriptor $bindingDescriptor) |
||
828 | { |
||
829 | return new AddBinding($bindingDescriptor, $this->discovery); |
||
830 | } |
||
831 | |||
832 | 6 | private function syncBinding(Binding $binding) |
|
833 | { |
||
834 | 6 | return new SyncBinding($binding, $this->discovery, $this->bindingDescriptors); |
|
835 | } |
||
836 | } |
||
837 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.