Completed
Push — master ( 0a1ee7...79b8d3 )
by Beñat
04:38
created

TacticianEventsBusPass::addListeners()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 26
rs 8.439
c 1
b 0
f 0
cc 6
eloc 18
nc 6
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 $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,
78
                    new Definition(
79
                        TacticianEventSubscriber::class,
80
                        [new Reference($id)]
81
                    )
82
                )->addTag('tactician.event_listener', ['event' => $attributes['subscribes_to']]);
83
            }
84
        }
85
    }
86
87
    private function addListeners(ContainerBuilder $container) : void
88
    {
89
        $definition = $container->getDefinition('tactician_domain_events.dispatcher');
90
        $taggedServices = $container->findTaggedServiceIds('tactician.event_listener');
91
        foreach ($taggedServices as $id => $tags) {
92
            foreach ($tags as $attributes) {
93
                if (!isset($attributes['event'])) {
94
                    throw new \Exception('The "tactician.event_listener" tag must always have an event attribute');
95
                }
96
                if (!class_exists($attributes['event'])) {
97
                    throw new \Exception(sprintf(
98
                        'Class %s registered as an event class in %s does not exist',
99
                        $attributes['event'],
100
                        $id
101
                    ));
102
                }
103
                $listener = array_key_exists('method', $attributes)
104
                    ? [new Reference($id), $attributes['method']]
105
                    : new Reference($id);
106
                $definition->addMethodCall('addListener', [
107
                    $attributes['event'],
108
                    $listener,
109
                ]);
110
            }
111
        }
112
    }
113
}
114