Completed
Pull Request — master (#4)
by dan
14:39
created

NotificationExtension::load()   C

Complexity

Conditions 10
Paths 56

Size

Total Lines 68

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 68
rs 6.8315
c 0
b 0
f 0
cc 10
nc 56
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Compiler\PassConfig;
9
use Symfony\Component\DependencyInjection\Definition;
10
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
11
use Symfony\Component\DependencyInjection\Reference;
12
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
13
use Symfony\Component\DependencyInjection\ContainerBuilder;
14
15
class NotificationExtension extends Extension
16
{
17
    protected $channelKeyAdapterMappings = [];
18
    protected $defaultAdapters = [
19
        'mail',
20
        'logger',
21
        'database',
22
        'nexmo',
23
        'pusher',
24
        'slack',
25
    ];
26
27
    protected function setChannelAdapterMapping(array $maps)
28
    {
29
        $this->channelKeyAdapterMappings[$maps['channel']] = [
30
            'adapter' => $maps['adapter'],
31
            'config_id' => $maps['config_id'],
32
            'config' => $maps['config'],
33
        ];
34
    }
35
36
    public function load(array $configs, ContainerBuilder $container)
37
    {
38
        // Load our YAML resources
39
        $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
40
        $loader->load('services.yml');
41
42
        // @TODO: Broadcasters array should dynamic
43
        $configuration = new Configuration($this->defaultAdapters, ['slack', 'pusher']);
44
        $config = $this->processConfiguration($configuration, $configs);
45
46
        foreach ($configs as $subConfig) {
47
            $config = array_merge($config, $subConfig);
48
        }
49
50
        // Create the adapterless channel
51
        $this->createChannel($container, 'notification.channel');
52
53
54
        $enabledChannels = [];
55
56
        // For each enabled channel build a channel service..
57
        if (!empty($config['channels'])) {
58
            foreach ($config['channels'] as $channel => $channelConfig) {
59
                $enabledChannels[] = $channel;
60
                $container->setParameter('notification.channel.' . $channel . '.enabled', true);
61
62
                // Set a configuration parameter for each channel also.
63
                $parameters = empty($channelConfig) ? [] : $channelConfig;
64
                $parameterName = 'notification.channel.' . $channel . '.configuration';
65
                $container->setParameter($parameterName, $parameters);
66
67
                // Create a service for this channel.
68
                $this->createChannelService($channel, $container, $parameters);
69
            }
70
        }
71
72
        $container->setParameter('notification.available_channels', $enabledChannels);
73
74
        // Create the channel service
75
        $this->createChannelManagerService($enabledChannels, $container);
76
77
        // Create the notification manager service
78
        $this->createNotificationManagerService($container);
79
80
        // Create broadcasters and broadcast channels
81
        if (!empty($config['broadcasters'])) {
82
            foreach ($config['broadcasters'] as $name => $config) {
83
                $this->createBroadcaster($name, $config, $container);
84
            }
85
        }
86
87
        // Create the Event driven channel service
88
        // $this->createEventDrivenChannel($container);
89
90
        // @TODO: Check that required parameters are set.
91
        foreach ($this->defaultAdapters as $type) {
92
            if (!$container->hasParameter('notification.channel.' . $type . '.configuration')) {
93
                $container->setParameter('notification.channel.' . $type . '.configuration', []);
94
                $container->setParameter('notification.channel.' . $type . '.enabled', false);
95
            }
96
        }
97
98
        // Build the message crud listener unless its set to false
99
        // @TODO: Add this to documentation
100
        if ($config['use_default_message_subscriber']) {
101
            $this->createNotificationChannelSubscriber($container);
102
        }
103
    }
104
105
    private function createNotificationChannelSubscriber(ContainerBuilder $container) {
106
        $definition = new Definition();
107
        $definition->setClass('IrishDan\NotificationBundle\Subscriber\NotificationChannelSubscriber');
108
109
        // $config = [];
110
        // foreach ($this->channelKeyAdapterMappings as $channel => $data) {
111
        //     $config[$channel] = $data['config'];
112
        // }
113
        // create a paramater with all of the channel data.
114
        $container->setParameter('notification.channel_adapter_map', $this->channelKeyAdapterMappings);
115
116
        $definition->setArguments([new Reference('event_dispatcher'), new Reference('notification.channel'), '%notification.channel_adapter_map%']);
117
        $definition->addTag('kernel.event_subscriber');
118
119
        $container->setDefinition('notification.channel_subscriber', $definition);
120
    }
121
122 View Code Duplication
    private function createChannel(ContainerBuilder $container, string $id, $adapter = null)
0 ignored issues
show
Unused Code introduced by
The parameter $adapter is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
123
    {
124
        $definition = new Definition();
125
        $definition->setClass('IrishDan\NotificationBundle\Channel\Channel');
126
        $definition->addMethodCall('setEventDispatcher', [new Reference('event_dispatcher')]);
127
128
        $container->setDefinition($id, $definition);
129
    }
130
131
    private function createChannelService($channel, ContainerBuilder $container, array $config)
132
    {
133
        $factory = new ChannelFactory();
134
        $factory->create($container, $channel, $config);
135
        $this->setChannelAdapterMapping($factory->getChannelKeyAdapterMap());
136
    }
137
138
    private function createBroadcaster($name, $config, ContainerBuilder $container)
139
    {
140
        $broadcastFactory = new BroadcasterFactory();
141
        $broadcastFactory->create($container, $name, $config);
142
    }
143
144 View Code Duplication
    private function createNotificationManagerService(ContainerBuilder $container)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
145
    {
146
        $definition = new Definition();
147
        $definition->setClass('IrishDan\NotificationBundle\NotificationManager');
148
        $definition->setArguments(
149
            [
150
                new Reference('notification.channel_manager'),
151
                new Reference('notification.database_notification_manager'),
152
            ]
153
        );
154
        $definition->setPublic(true);
155
156
        $container->setDefinition('notification.manager', $definition);
157
    }
158
159
    private function createChannelManagerService(array $enabledChannels, ContainerBuilder $container)
160
    {
161
        $definition = new Definition();
162
        $definition->setClass('IrishDan\NotificationBundle\ChannelManager');
163
        $definition->setArguments(
164
            [
165
                new Reference('event_dispatcher'),
166
                $container->getParameter('notification.available_channels'),
167
            ]
168
        );
169
        $container->setDefinition('notification.channel_manager', $definition);
170
171
        foreach ($enabledChannels as $channel) {
172
            // Add the channel to the channel manager service
173
            $channelManager = $container->getDefinition('notification.channel_manager');
174
            $channelId = 'notification.channel.' . $channel;
175
            $channelManager->addMethodCall('setChannel', [$channel, new Reference($channelId)]);
176
        }
177
    }
178
}