Passed
Pull Request — master (#970)
by butschster
10:11
created

EventsBootloader::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 0
c 1
b 0
f 0
dl 0
loc 3
ccs 1
cts 1
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Events\Bootloader;
6
7
use Psr\Container\ContainerInterface;
8
use Psr\EventDispatcher\EventDispatcherInterface;
9
use Spiral\Boot\AbstractKernel;
10
use Spiral\Boot\Bootloader\Bootloader;
11
use Spiral\Boot\FinalizerInterface;
12
use Spiral\Bootloader\Attributes\AttributesBootloader;
13
use Spiral\Config\ConfiguratorInterface;
14
use Spiral\Config\Patch\Append;
15
use Spiral\Core\Container;
16
use Spiral\Core\Container\Autowire;
17
use Spiral\Core\CoreInterceptorInterface;
18
use Spiral\Core\FactoryInterface;
19
use Spiral\Core\InterceptableCore;
20
use Spiral\Events\AutowireListenerFactory;
21
use Spiral\Events\Config\EventsConfig;
22
use Spiral\Events\EventDispatcher;
23
use Spiral\Events\EventDispatcherAwareInterface;
24
use Spiral\Events\Interceptor\Core;
25
use Spiral\Events\ListenerFactoryInterface;
26
use Spiral\Events\ListenerProcessorRegistry;
27
use Spiral\Events\Processor\AttributeProcessor;
28
use Spiral\Events\Processor\ConfigProcessor;
29
use Spiral\Events\Processor\ProcessorInterface;
30
use Spiral\Tokenizer\Bootloader\TokenizerListenerBootloader;
31
32
/**
33
 * @psalm-import-type TInterceptor from EventsConfig
34
 */
35
final class EventsBootloader extends Bootloader
36
{
37
    protected const DEPENDENCIES = [
38
        TokenizerListenerBootloader::class,
39
        AttributesBootloader::class,
40
    ];
41
42
    protected const SINGLETONS = [
43
        ListenerFactoryInterface::class => AutowireListenerFactory::class,
44
        ListenerProcessorRegistry::class => ListenerProcessorRegistry::class,
45
    ];
46
47 304
    public function __construct(
48
        private readonly ConfiguratorInterface $configs
49
    ) {
50 304
    }
51
52 304
    public function init(): void
53
    {
54 304
        $this->configs->setDefaults(EventsConfig::CONFIG, [
55 304
            'listeners' => [],
56 304
            'processors' => [
57 304
                AttributeProcessor::class,
58 304
                ConfigProcessor::class,
59 304
            ],
60 304
            'interceptors' => [],
61 304
        ]);
62
    }
63
64 304
    public function boot(
65
        Container $container,
66
        FactoryInterface $factory,
67
        EventsConfig $config,
68
        AbstractKernel $kernel,
69
        ListenerProcessorRegistry $registry,
70
        FinalizerInterface $finalizer,
71
        ?EventDispatcherInterface $eventDispatcher = null
72
    ): void {
73 304
        if ($eventDispatcher !== null) {
74 6
            $this->initEventDispatcher(new Core($eventDispatcher), $config, $container, $factory);
75
        }
76
77 304
        foreach ($config->getProcessors() as $processor) {
78 304
            $processor = $this->autowire($processor, $container, $factory);
79
80 304
            \assert($processor instanceof ProcessorInterface);
81 304
            $registry->addProcessor($processor);
82
        }
83
84 304
        $kernel->bootstrapped(static function () use ($registry): void {
85 304
            $registry->process();
86 304
        });
87
88 304
        if ($finalizer instanceof EventDispatcherAwareInterface && $eventDispatcher !== null) {
89 2
            $finalizer->setEventDispatcher($eventDispatcher);
90
        }
91
    }
92
93
    /**
94
     * @param TInterceptor $interceptor
0 ignored issues
show
Bug introduced by
The type Spiral\Events\Bootloader\TInterceptor was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
95
     */
96 1
    public function addInterceptor(string|CoreInterceptorInterface|Container\Autowire $interceptor): void
97
    {
98 1
        $this->configs->modify(EventsConfig::CONFIG, new Append('interceptors', null, $interceptor));
99
    }
100
101 6
    private function initEventDispatcher(
102
        Core $core,
103
        EventsConfig $config,
104
        Container $container,
105
        FactoryInterface $factory
106
    ): void {
107 6
        $core = new InterceptableCore($core);
108
109 6
        foreach ($config->getInterceptors() as $interceptor) {
110
            $interceptor = $this->autowire($interceptor, $container, $factory);
111
112
            \assert($interceptor instanceof CoreInterceptorInterface);
113
            $core->addInterceptor($interceptor);
114
        }
115
116 6
        $container->removeBinding(EventDispatcherInterface::class);
117 6
        $container->bindSingleton(EventDispatcherInterface::class, new EventDispatcher($core));
118
    }
119
120 304
    private function autowire(string|object $id, ContainerInterface $container, FactoryInterface $factory): object
121
    {
122 304
        if (\is_string($id)) {
123 304
            $id = $container->get($id);
124 2
        } elseif ($id instanceof Autowire) {
125 1
            $id = $id->resolve($factory);
126
        }
127
128 304
        return $id;
129
    }
130
}
131