TacticianEventsBusPass::process()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 9.536
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Shared Kernel library.
5
 *
6
 * Copyright (c) 2016-present LIN3S <[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
declare(strict_types=1);
13
14
namespace LIN3S\SharedKernel\Infrastructure\Symfony\Bundle\DependencyInjection\Compiler;
15
16
use BornFree\TacticianDomainEvent\EventDispatcher\EventDispatcher;
17
use BornFree\TacticianDomainEventBundle\TacticianDomainEventBundle;
18
use LIN3S\SharedKernel\Infrastructure\Application\Tactician\TacticianEventBus;
19
use LIN3S\SharedKernel\Infrastructure\Application\Tactician\TacticianEventSubscriber;
20
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
21
use Symfony\Component\DependencyInjection\ContainerBuilder;
22
use Symfony\Component\DependencyInjection\Definition;
23
use Symfony\Component\DependencyInjection\Reference;
24
25
/**
26
 * @author Beñat Espiña <[email protected]>
27
 */
28
class TacticianEventsBusPass implements CompilerPassInterface
29
{
30
    private $subscriberTag;
31
32
    public function __construct($subscriberTag = 'event_subscriber')
33
    {
34
        $this->subscriberTag = $subscriberTag;
35
    }
36
37
    public function process(ContainerBuilder $container) : void
38
    {
39
        if (!class_exists(TacticianDomainEventBundle::class)) {
40
            return;
41
        }
42
43
        $container->setDefinition(
44
            'tactician_domain_events.dispatcher',
45
            new Definition(EventDispatcher::class)
46
        )
47
            ->setPublic(false)
48
            ->setLazy(true);
49
50
        $container->setDefinition(
51
            'lin3s.application.tactician_event_bus',
52
            new Definition(TacticianEventBus::class, [
53
                new Reference('tactician_domain_events.dispatcher'),
54
            ])
55
        );
56
        $container->setAlias('lin3s.event_bus', 'lin3s.application.tactician_event_bus');
57
58
        $this->loadAllSubscribers($container);
59
        $this->addListeners($container);
60
    }
61
62
    private function loadAllSubscribers(ContainerBuilder $container) : void
63
    {
64
        $taggedServices = $container->findTaggedServiceIds($this->subscriberTag);
65
66
        foreach ($taggedServices as $id => $tags) {
67
            foreach ($tags as $key => $attributes) {
68
                if (!isset($attributes['subscribes_to'])) {
69
                    throw new \Exception(sprintf(
70
                        '"subscribes_to" parameter not found in %s service definition tagged with "%s"',
71
                        $id,
72
                        $this->subscriberTag
73
                    ));
74
                }
75
76
                $container->setDefinition(
77
                    'tactician_event_subscriber.' . $id . '_' . $key,
78
                    new Definition(
79
                        TacticianEventSubscriber::class,
80
                        [new Reference($id)]
81
                    )
82
                )
83
                    ->setPublic(true)		
84
                    ->addTag('tactician.event_listener', ['event' => $attributes['subscribes_to']]);
85
            }
86
        }
87
    }
88
89
    private function addListeners(ContainerBuilder $container) : void
90
    {
91
        $definition = $container->getDefinition('tactician_domain_events.dispatcher');
92
        $taggedServices = $container->findTaggedServiceIds('tactician.event_listener');
93
        foreach ($taggedServices as $id => $tags) {
94
            foreach ($tags as $attributes) {
95
                if (!isset($attributes['event'])) {
96
                    throw new \Exception('The "tactician.event_listener" tag must always have an event attribute');
97
                }
98
                if (!class_exists($attributes['event'])) {
99
                    throw new \Exception(sprintf(
100
                        'Class %s registered as an event class in %s does not exist',
101
                        $attributes['event'],
102
                        $id
103
                    ));
104
                }
105
                $listener = array_key_exists('method', $attributes)
106
                    ? [new Reference($id), $attributes['method']]
107
                    : new Reference($id);
108
                $definition->addMethodCall('addListener', [
109
                    $attributes['event'],
110
                    $listener,
111
                ]);
112
            }
113
        }
114
    }
115
}
116