Completed
Push — master ( c702e0...af42cc )
by Matthew
07:24
created

WorkerCompilerPass   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 197
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 69.11%

Importance

Changes 0
Metric Value
wmc 35
lcom 1
cbo 4
dl 0
loc 197
ccs 85
cts 123
cp 0.6911
rs 9
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A setupAliases() 0 18 4
A testClass() 0 11 3
B process() 0 28 3
A setupTaggedServices() 0 20 3
A setupDoctrineManagers() 0 16 3
C getJobClass() 0 27 7
B getClass() 0 21 6
B getJobClassArchive() 0 20 6
1
<?php
2
3
namespace Dtc\QueueBundle\DependencyInjection\Compiler;
4
5
use Dtc\QueueBundle\Model\Job;
6
use Dtc\QueueBundle\Model\JobTiming;
7
use Dtc\QueueBundle\Model\Run;
8
use Symfony\Component\DependencyInjection\Alias;
9
use Symfony\Component\DependencyInjection\ContainerBuilder;
10
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
11
use Symfony\Component\DependencyInjection\Definition;
12
use Symfony\Component\DependencyInjection\Reference;
13
14
class WorkerCompilerPass implements CompilerPassInterface
15
{
16 1
    public function process(ContainerBuilder $container)
17
    {
18 1
        if (false === $container->hasDefinition('dtc_queue.worker_manager')) {
19 1
            return;
20
        }
21
22 1
        $this->setupAliases($container);
23
24 1
        $definition = $container->getDefinition('dtc_queue.worker_manager');
25 1
        $jobManagerRef = array(new Reference('dtc_queue.job_manager'));
26
27 1
        $jobClass = $this->getJobClass($container);
28 1
        $jobArchiveClass = $this->getJobClassArchive($container);
29 1
        $container->setParameter('dtc_queue.class_job', $jobClass);
30 1
        $container->setParameter('dtc_queue.class_job_archive', $jobArchiveClass);
31 1
        $container->setParameter('dtc_queue.class_job_timing', $this->getClass($container, 'job_timing',
32 1
            'JobTiming', JobTiming::class));
33 1
        $container->setParameter('dtc_queue.class_run', $this->getClass($container, 'run', 'Run', Run::class));
34 1
        $container->setParameter('dtc_queue.class_run_archive', $this->getClass($container, 'run_archive', 'RunArchive', Run::class));
35
36 1
        $this->setupTaggedServices($container, $definition, $jobManagerRef, $jobClass);
37 1
        $eventDispatcher = $container->getDefinition('dtc_queue.event_dispatcher');
38 1
        foreach ($container->findTaggedServiceIds('dtc_queue.event_subscriber') as $id => $attributes) {
39
            $eventSubscriber = $container->getDefinition($id);
40
            $eventDispatcher->addMethodCall('addSubscriber', [$eventSubscriber]);
41 1
        }
42 1
        $this->setupDoctrineManagers($container);
43 1
    }
44
45 1
    protected function setupAliases(ContainerBuilder $container)
46
    {
47 1
        $defaultManagerType = $container->getParameter('dtc_queue.default_manager');
48 1
        if (!$container->hasDefinition('dtc_queue.job_manager.'.$defaultManagerType) && !$container->hasAlias('dtc_queue.job_manager.'.$defaultManagerType)) {
49
            throw new \Exception("No job manager found for dtc_queue.job_manager.$defaultManagerType");
50
        }
51
52 1
        $defaultRunManagerType = $container->getParameter('dtc_queue.run_manager');
53 1
        if (!$container->hasDefinition('dtc_queue.run_manager.'.$defaultRunManagerType)) {
54
            throw new \Exception("No run manager found for dtc_queue.run_manager.$defaultRunManagerType");
55
        }
56
57 1
        $alias = new Alias('dtc_queue.job_manager.'.$defaultManagerType);
58 1
        $container->setAlias('dtc_queue.job_manager', $alias);
59
60 1
        $alias = new Alias('dtc_queue.run_manager.'.$defaultRunManagerType);
61 1
        $container->setAlias('dtc_queue.run_manager', $alias);
62 1
    }
63
64
    /**
65
     * @param ContainerBuilder $container
66
     * @param Reference[]      $jobManagerRef
67
     * @param string           $jobClass
68
     */
69 1
    protected function setupTaggedServices(ContainerBuilder $container, Definition $definition, array $jobManagerRef, $jobClass)
70
    {
71
        // Add each worker to workerManager, make sure each worker has instance to work
72 1
        foreach ($container->findTaggedServiceIds('dtc_queue.worker') as $id => $attributes) {
73
            $worker = $container->getDefinition($id);
74
            $class = $container->getDefinition($id)->getClass();
75
76
            $refClass = new \ReflectionClass($class);
77
            $workerClass = 'Dtc\QueueBundle\Model\Worker';
78
            if (!$refClass->isSubclassOf($workerClass)) {
79
                throw new \InvalidArgumentException(sprintf('Service "%s" must extend class "%s".', $id, $workerClass));
80
            }
81
82
            // Give each worker access to job manager
83
            $worker->addMethodCall('setJobManager', $jobManagerRef);
84
            $worker->addMethodCall('setJobClass', array($jobClass));
85
86
            $definition->addMethodCall('addWorker', array(new Reference($id)));
87 1
        }
88 1
    }
89
90 1
    protected function setupDoctrineManagers(ContainerBuilder $container)
91
    {
92 1
        $documentManager = $container->getParameter('dtc_queue.document_manager');
93
94 1
        $odmManager = "doctrine_mongodb.odm.{$documentManager}_document_manager";
95 1
        if ($container->has($odmManager)) {
96
            $container->setAlias('dtc_queue.document_manager', $odmManager);
97
        }
98
99 1
        $entityManager = $container->getParameter('dtc_queue.entity_manager');
100
101 1
        $ormManager = "doctrine.orm.{$entityManager}_entity_manager";
102 1
        if ($container->has($ormManager)) {
103
            $container->setAlias('dtc_queue.entity_manager', $ormManager);
104
        }
105 1
    }
106
107
    /**
108
     * Determines the job class based on the queue manager type.
109
     *
110
     * @param ContainerBuilder $container
111
     *
112
     * @return mixed|string
113
     *
114
     * @throws \Exception
115
     */
116 1
    protected function getJobClass(ContainerBuilder $container)
117
    {
118 1
        $jobClass = $container->getParameter('dtc_queue.class_job');
119 1
        if (!$jobClass) {
120 1
            switch ($defaultType = $container->getParameter('dtc_queue.default_manager')) {
121 1
                case 'mongodb': // deprecated remove in 3.0
122 1
                case 'odm':
123 1
                    $jobClass = 'Dtc\\QueueBundle\\Document\\Job';
124 1
                    break;
125
                case 'beanstalkd':
126
                    $jobClass = 'Dtc\\QueueBundle\\Beanstalkd\\Job';
127
                    break;
128
                case 'rabbit_mq':
129
                    $jobClass = 'Dtc\\QueueBundle\\RabbitMQ\\Job';
130
                    break;
131
                case 'orm':
132
                    $jobClass = 'Dtc\\QueueBundle\\Entity\\Job';
133
                    break;
134
                default:
135
                    throw new \Exception('Unknown default_manager type '.$defaultType.' - please specify a Job class in the \'class\' configuration parameter');
136 1
            }
137 1
        }
138
139 1
        $this->testClass($jobClass, Job::class);
140
141 1
        return $jobClass;
142
    }
143
144 1
    protected function getClass(ContainerBuilder $container, $type, $className, $baseClass)
145
    {
146 1
        $runClass = $container->hasParameter('dtc_queue.class_'.$type) ? $container->getParameter('dtc_queue.class_'.$type) : null;
147 1
        if (!$runClass) {
148 1
            switch ($container->getParameter('dtc_queue.default_manager')) {
149 1
                case 'mongodb': // deprecated remove in 3.0
150 1
                case 'odm':
151 1
                    $runClass = 'Dtc\\QueueBundle\\Document\\'.$className;
152 1
                    break;
153
                case 'orm':
154
                    $runClass = 'Dtc\\QueueBundle\\Entity\\'.$className;
155
                    break;
156
                default:
157
                    $runClass = $baseClass;
158 1
            }
159 1
        }
160
161 1
        $this->testClass($runClass, $baseClass);
162
163 1
        return $runClass;
164
    }
165
166
    /**
167
     * @throws \Exception
168
     */
169 1
    protected function testClass($className, $parent)
170
    {
171 1
        if (!class_exists($className)) {
172
            throw new \Exception("Can't find class $className");
173
        }
174
175 1
        $test = new $className();
176 1
        if (!$test instanceof $className) {
177
            throw new \Exception("$className must be instance of (or derived from) $parent");
178
        }
179 1
    }
180
181
    /**
182
     * Determines the job class based on the queue manager type.
183
     *
184
     * @param ContainerBuilder $container
185
     *
186
     * @return mixed|string
187
     *
188
     * @throws \Exception
189
     */
190 1
    protected function getJobClassArchive(ContainerBuilder $container)
191
    {
192 1
        $jobArchiveClass = $container->getParameter('dtc_queue.class_job_archive');
193 1
        if (!$jobArchiveClass) {
194 1
            switch ($container->getParameter('dtc_queue.default_manager')) {
195 1
                case 'mongodb': // deprecated remove in 4.0
196 1
                case 'odm':
197 1
                    $jobArchiveClass = 'Dtc\\QueueBundle\\Document\\JobArchive';
198 1
                    break;
199
                case 'orm':
200
                    $jobArchiveClass = 'Dtc\\QueueBundle\\Entity\\JobArchive';
201
                    break;
202 1
            }
203 1
        }
204 1
        if (null !== $jobArchiveClass) {
205 1
            $this->testClass($jobArchiveClass, Job::class);
206 1
        }
207
208 1
        return $jobArchiveClass;
209
    }
210
}
211