NotificationExtension   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 136
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 9
dl 0
loc 136
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A setChannelAdapterMapping() 0 7 1
B load() 0 56 9
A createEventDrivenChannel() 0 12 2
A createChannelService() 0 6 1
A createBroadcaster() 0 5 1
A createNotificationManagerService() 0 12 1
A createChannelManagerService() 0 19 2
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
        $enabledChannels = [];
49
        if (!empty($config['channels'])) {
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
64
        $container->setParameter('notification.available_channels', $enabledChannels);
65
66
        // Create the channel service
67
        $this->createChannelManagerService($enabledChannels, $container);
68
69
        // Create the notification manager service
70
        $this->createNotificationManagerService($container);
71
72
        // Create broadcasters and broadcast channels
73
        if (!empty($config['broadcasters'])) {
74
            foreach ($config['broadcasters'] as $name => $config) {
75
                $this->createBroadcaster($name, $config, $container);
76
            }
77
        }
78
79
        // Create the Event driven channel service
80
        $this->createEventDrivenChannel($container);
81
82
        // @TODO: Check that required parameters are set.
83
        foreach ($this->defaultAdapters as $type) {
84
            if (!$container->hasParameter('notification.channel.' . $type . '.configuration')) {
85
                $container->setParameter('notification.channel.' . $type . '.configuration', []);
86
                $container->setParameter('notification.channel.' . $type . '.enabled', false);
87
            }
88
        }
89
    }
90
91
    private function createEventDrivenChannel(ContainerBuilder $container)
92
    {
93
        $definition = new Definition();
94
        $definition->setClass('IrishDan\NotificationBundle\Channel\EventChannel');
95
        $definition->setArguments([new Reference('event_dispatcher')]);
96
97
        foreach ($this->channelKeyAdapterMappings as $key => $channel) {
98
            $definition->addMethodCall('setAdapters', [$key, new Reference($channel['adapter']), $container->getParameter($channel['config'])]);
99
        }
100
101
        $container->setDefinition('notification.channel.event_channel', $definition);
102
    }
103
104
    private function createChannelService($channel, ContainerBuilder $container, array $config)
105
    {
106
        $factory = new ChannelFactory();
107
        $factory->create($container, $channel, $config);
108
        $this->setChannelAdapterMapping($factory->getChannelKeyAdapterMap());
109
    }
110
111
    private function createBroadcaster($name, $config, ContainerBuilder $container)
112
    {
113
        $broadcastFactory = new BroadcasterFactory();
114
        $broadcastFactory->create($container, $name, $config);
115
    }
116
117
    private function createNotificationManagerService(ContainerBuilder $container)
118
    {
119
        $definition = new Definition();
120
        $definition->setClass('IrishDan\NotificationBundle\NotificationManager');
121
        $definition->setArguments(
122
            [
123
                new Reference('notification.channel_manager'),
124
                new Reference('notification.database_notification_manager'),
125
            ]
126
        );
127
        $container->setDefinition('notification.manager', $definition);
128
    }
129
130
    private function createChannelManagerService(array $enabledChannels, ContainerBuilder $container)
131
    {
132
        $definition = new Definition();
133
        $definition->setClass('IrishDan\NotificationBundle\ChannelManager');
134
        $definition->setArguments(
135
            [
136
                new Reference('event_dispatcher'),
137
                $container->getParameter('notification.available_channels'),
138
            ]
139
        );
140
        $container->setDefinition('notification.channel_manager', $definition);
141
142
        foreach ($enabledChannels as $channel) {
143
            // Add the channel to the channel manager service
144
            $channelManager = $container->getDefinition('notification.channel_manager');
145
            $channelId = 'notification.channel.' . $channel;
146
            $channelManager->addMethodCall('setChannel', [$channel, new Reference($channelId)]);
147
        }
148
    }
149
}