Completed
Push — master ( e7a3c7...2372b5 )
by dan
02:03
created

NotificationExtension::createEventDrivenChannel()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 1
1
<?php
2
3
namespace IrishDan\NotificationBundle\DependencyInjection;
4
5
use IrishDan\NotificationBundle\DependencyInjection\Factory\BroadcasterFactory;
6
use IrishDan\NotificationBundle\DependencyInjection\Factory\ChannelFactory;
7
use Symfony\Component\Config\FileLocator;
8
use Symfony\Component\DependencyInjection\Definition;
9
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
10
use Symfony\Component\DependencyInjection\Reference;
11
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
12
use Symfony\Component\DependencyInjection\ContainerBuilder;
13
14
class NotificationExtension extends Extension
15
{
16
    protected $channelKeyAdapterMappings = [];
17
    protected $defaultAdapters = [
18
        'mail',
19
        'logger',
20
        'database',
21
        'nexmo',
22
        'pusher',
23
        'slack',
24
    ];
25
26
    protected function setChannelAdapterMapping(array $maps)
27
    {
28
        $this->channelKeyAdapterMappings[$maps['channel']] = [
29
            'adapter' => $maps['adapter'],
30
            'config' => $maps['config'],
31
        ];
32
    }
33
34
    public function load(array $configs, ContainerBuilder $container)
35
    {
36
        // Load our YAML resources
37
        $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
38
        $loader->load('services.yml');
39
40
        // @TODO: Broadcasters array should dynamic
41
        $configuration = new Configuration($this->defaultAdapters, ['slack', 'pusher']);
42
        $config = $this->processConfiguration($configuration, $configs);
43
44
        foreach ($configs as $subConfig) {
45
            $config = array_merge($config, $subConfig);
46
        }
47
48
49
        $enabledChannels = [];
50
        foreach ($config['channels'] as $channel => $channelConfig) {
51
            $enabledChannels[] = $channel;
52
            $container->setParameter('notification.channel.' . $channel . '.enabled', true);
53
54
            // Set a configuration parameter for each channel also.
55
            $parameters = empty($channelConfig) ? [] : $channelConfig;
56
            $parameterName = 'notification.channel.' . $channel . '.configuration';
57
            $container->setParameter($parameterName, $parameters);
58
59
            // Create a service for this channel.
60
            $this->createChannelService($channel, $container, $parameters);
61
        }
62
63
        $container->setParameter('notification.available_channels', $enabledChannels);
64
65
        // Create the channel service
66
        $this->createChannelManagerService($enabledChannels, $container);
67
68
        // Create the notification manager service
69
        $this->createNotificationManagerService($container);
70
71
        // Create broadcasters and broadcast channels
72
        if (!empty($config['broadcasters'])) {
73
            foreach ($config['broadcasters'] as $name => $config) {
74
                $this->createBroadcaster($name, $config, $container);
75
            }
76
        }
77
78
        // Create the Event driven channel service
79
        $this->createEventDrivenChannel($container);
80
    }
81
82
    private function createEventDrivenChannel(ContainerBuilder $container)
83
    {
84
        $definition = new Definition();
85
        $definition->setClass('IrishDan\NotificationBundle\Channel\EventChannel');
86
        $definition->setArguments([new Reference('event_dispatcher')]);
87
88
        foreach ($this->channelKeyAdapterMappings as $key => $channel) {
89
            $definition->addMethodCall('setAdapters', [$key, new Reference($channel['adapter']), $container->getParameter($channel['config'])]);
90
        }
91
92
        $container->setDefinition('notification.channel.event_channel', $definition);
93
    }
94
95
    private function createChannelService($channel, ContainerBuilder $container, array $config)
96
    {
97
        $factory = new ChannelFactory();
98
        $factory->create($container, $channel, $config);
99
        $this->setChannelAdapterMapping($factory->getChannelKeyAdapterMap());
100
    }
101
102
    private function createBroadcaster($name, $config, ContainerBuilder $container)
103
    {
104
        $broadcastFactory = new BroadcasterFactory();
105
        $broadcastFactory->create($container, $name, $config);
106
    }
107
108
    private function createNotificationManagerService(ContainerBuilder $container)
109
    {
110
        $definition = new Definition();
111
        $definition->setClass('IrishDan\NotificationBundle\NotificationManager');
112
        $definition->setArguments(
113
            [
114
                new Reference('notification.channel_manager'),
115
                new Reference('notification.database_notification_manager'),
116
            ]
117
        );
118
        $container->setDefinition('notification.manager', $definition);
119
    }
120
121
    private function createChannelManagerService(array $enabledChannels, ContainerBuilder $container)
122
    {
123
        $definition = new Definition();
124
        $definition->setClass('IrishDan\NotificationBundle\ChannelManager');
125
        $definition->setArguments(
126
            [
127
                new Reference('event_dispatcher'),
128
                $container->getParameter('notification.available_channels'),
129
            ]
130
        );
131
        $container->setDefinition('notification.channel_manager', $definition);
132
133
        foreach ($enabledChannels as $channel) {
134
            // Add the channel to the channel manager service
135
            $channelManager = $container->getDefinition('notification.channel_manager');
136
            $channelId = 'notification.channel.' . $channel;
137
            $channelManager->addMethodCall('setChannel', [$channel, new Reference($channelId)]);
138
        }
139
    }
140
}