Completed
Push — master ( 5e843b...d6e977 )
by Alexey
39:04
created

SocketIoExtension   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 202
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
wmc 15
lcom 1
cbo 7
dl 0
loc 202
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A load() 0 32 2
A createDriver() 0 9 1
A createBroadcast() 0 33 5
A createEventManager() 0 10 1
A createProcess() 0 10 1
A createWorker() 0 14 2
A createHandlers() 0 18 1
A createCommands() 0 26 1
A getAlias() 0 4 1
1
<?php
2
3
namespace SfCod\SocketIoBundle\DependencyInjection;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use Psr\Log\LoggerInterface;
7
use SfCod\SocketIoBundle\Command\NodeJsServerCommand;
8
use SfCod\SocketIoBundle\Command\PhpServerCommand;
9
use SfCod\SocketIoBundle\Command\ProcessCommand;
10
use SfCod\SocketIoBundle\Events\EventInterface;
11
use SfCod\SocketIoBundle\Events\EventPublisherInterface;
12
use SfCod\SocketIoBundle\Events\EventSubscriberInterface;
13
use SfCod\SocketIoBundle\Middleware\Process\DoctrineReconnect;
14
use SfCod\SocketIoBundle\Service\Broadcast;
15
use SfCod\SocketIoBundle\Service\EventManager;
16
use SfCod\SocketIoBundle\Service\JoinHandler;
17
use SfCod\SocketIoBundle\Service\LeaveHandler;
18
use SfCod\SocketIoBundle\Service\Process;
19
use SfCod\SocketIoBundle\Service\RedisDriver;
20
use SfCod\SocketIoBundle\Service\Worker;
21
use Symfony\Component\DependencyInjection\ContainerBuilder;
22
use Symfony\Component\DependencyInjection\Definition;
23
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
24
use Symfony\Component\DependencyInjection\Extension\Extension;
25
use Symfony\Component\DependencyInjection\Reference;
26
27
/**
28
 * Class SocketIoExtension.
29
 *
30
 * @author Virchenko Maksim <[email protected]>
31
 *
32
 * @package SfCod\SocketIoBundle\DependencyInjection
33
 */
34
class SocketIoExtension extends Extension
35
{
36
    /**
37
     * Loads a specific configuration.
38
     *
39
     * @throws \Exception
40
     */
41
    public function load(array $configs, ContainerBuilder $container)
42
    {
43
        $configuration = new SocketIoConfiguration();
44
45
        $config = $this->processConfiguration($configuration, $configs);
46
47
        $container->registerForAutoconfiguration(EventPublisherInterface::class)
48
            ->addTag('socketio.publisher');
49
        $container->registerForAutoconfiguration(EventSubscriberInterface::class)
50
            ->addTag('socketio.subscriber');
51
        $container->registerForAutoconfiguration(EventInterface::class)
52
            ->addTag('socketio.events');
53
54
        $this->createDriver($config, $container);
55
        $this->createBroadcast($config, $container);
56
        $this->createEventManager($config, $container);
57
        $this->createProcess($config, $container);
58
        $this->createWorker($config, $container);
59
        $this->createCommands($config, $container);
60
        $this->createHandlers($config, $container);
61
62
        $eventManager = $container->get(EventManager::class);
63
64
        foreach ($eventManager->getList() as $name => $class) {
65
            $definition = new Definition($class);
66
            $definition
67
                ->setAutowired(true)
68
                ->setAutoconfigured(true)
69
                ->setPublic(false);
70
            $eventManager->addMethodCall('addEvent', [$definition]);
71
        }
72
    }
73
74
    /**
75
     * Create driver.
76
     */
77
    private function createDriver(array $config, ContainerBuilder $container)
0 ignored issues
show
Unused Code introduced by
The parameter $config 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...
78
    {
79
        $redis = new Definition(RedisDriver::class);
80
        $redis->setArguments([
81
            $container->getParameter('env(REDIS_URL)'),
82
        ]);
83
84
        $container->setDefinition(RedisDriver::class, $redis);
85
    }
86
87
    /**
88
     * Create broadcast.
89
     */
90
    private function createBroadcast(array $config, ContainerBuilder $container)
91
    {
92
        $broadcast = new Definition(Broadcast::class);
93
        $broadcast->setArguments([
94
            new Reference(RedisDriver::class),
95
            new Reference(EventManager::class),
96
            new Reference(LoggerInterface::class),
97
            new Reference(Process::class),
98
        ]);
99
100
        if ($container->getParameter('kernel.bundles')['DoctrineBundle'] ?? null) {
101
            $doctrineReconnect = new Definition(DoctrineReconnect::class);
102
            $doctrineReconnect->setArguments([
103
                new Reference(EntityManagerInterface::class),
104
            ]);
105
106
            $container->setDefinition(DoctrineReconnect::class, $doctrineReconnect);
107
        }
108
109
        if (isset($config['processMiddlewares'])) {
110
            $processMiddlewares = [];
111
            foreach ($config['processMiddlewares'] as $processMiddlewareId) {
112
                if (!$container->has($processMiddlewareId)) {
113
                    throw new RuntimeException(sprintf('Invalid middleware: service "%s" not found.', $processMiddlewareId));
114
                }
115
                $processMiddlewares[] = new Reference($processMiddlewareId);
116
            }
117
118
            $broadcast->addMethodCall('setProcessMiddlewares', [$processMiddlewares]);
119
        }
120
121
        $container->setDefinition(Broadcast::class, $broadcast);
122
    }
123
124
    /**
125
     * Create event manager.
126
     */
127
    private function createEventManager(array $config, ContainerBuilder $container)
128
    {
129
        $eventManager = new Definition(EventManager::class);
130
        $eventManager->setArguments([
131
            $container->getParameter('kernel.root_dir'),
132
            $config['namespaces'],
133
        ]);
134
135
        $container->setDefinition(EventManager::class, $eventManager);
136
    }
137
138
    /**
139
     * Create process.
140
     */
141
    private function createProcess(array $config, ContainerBuilder $container)
0 ignored issues
show
Unused Code introduced by
The parameter $config 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...
142
    {
143
        $jobProcess = new Definition(Process::class);
144
        $jobProcess->setArguments([
145
            'console',
146
            sprintf('%s/bin', $container->getParameter('kernel.project_dir')),
147
        ]);
148
149
        $container->setDefinition(Process::class, $jobProcess);
150
    }
151
152
    /**
153
     * Create worker.
154
     *
155
     * @throws \Exception
156
     */
157
    private function createWorker(array $config, ContainerBuilder $container)
0 ignored issues
show
Unused Code introduced by
The parameter $config 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...
158
    {
159
        $worker = new Definition(Worker::class);
160
        $worker->setArguments([
161
            new Reference(EventManager::class),
162
            new Reference(RedisDriver::class),
163
            new Reference(Broadcast::class),
164
            $container->hasParameter('kernel.logs_dir') ?
165
                $container->getParameter('kernel.logs_dir') . '/socketio' :
166
                $container->getParameter('kernel.root_dir') . '/../../var/log/socketio',
167
        ]);
168
169
        $container->setDefinition(Worker::class, $worker);
170
    }
171
172
    /**
173
     * Create handlers.
174
     *
175
     * @throws \Exception
176
     */
177
    private function createHandlers(array $config, ContainerBuilder $container)
0 ignored issues
show
Unused Code introduced by
The parameter $config 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...
178
    {
179
        $joinHandler = new Definition(JoinHandler::class);
180
        $joinHandler->setArguments([
181
            new Reference(Broadcast::class),
182
            new Reference(LoggerInterface::class),
183
        ]);
184
        $joinHandler->addTag('sfcod.socketio.event');
185
        $container->setDefinition(JoinHandler::class, $joinHandler);
186
187
        $leaveHandler = new Definition(LeaveHandler::class);
188
        $leaveHandler->setArguments([
189
            new Reference(Broadcast::class),
190
            new Reference(LoggerInterface::class),
191
        ]);
192
        $leaveHandler->addTag('sfcod.socketio.event');
193
        $container->setDefinition(LeaveHandler::class, $leaveHandler);
194
    }
195
196
    /**
197
     * Create command.
198
     */
199
    private function createCommands(array $config, ContainerBuilder $container)
0 ignored issues
show
Unused Code introduced by
The parameter $config 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...
200
    {
201
        $nodeJs = new Definition(NodeJsServerCommand::class);
202
        $nodeJs->setArguments([
203
            new Reference(Worker::class),
204
        ]);
205
        $nodeJs->addTag('console.command');
206
207
        $phpServer = new Definition(PhpServerCommand::class);
208
        $phpServer->setArguments([
209
            new Reference(Worker::class),
210
        ]);
211
        $phpServer->addTag('console.command');
212
213
        $process = new Definition(ProcessCommand::class);
214
        $process->setArguments([
215
            new Reference(Broadcast::class),
216
        ]);
217
        $process->addTag('console.command');
218
219
        $container->addDefinitions([
220
            PhpServerCommand::class => $phpServer,
221
            ProcessCommand::class => $process,
222
            NodeJsServerCommand::class => $nodeJs,
223
        ]);
224
    }
225
226
    /**
227
     * Get extension alias.
228
     *
229
     * @return string
230
     */
231
    public function getAlias()
232
    {
233
        return 'sfcod_socketio';
234
    }
235
}
236