Completed
Push — master ( fa7a2a...0b2176 )
by Matthew
08:03
created

WorkerCompilerPass::setupDoctrineManagers()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3.3332

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 8
cts 12
cp 0.6667
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 9
nc 4
nop 1
crap 3.3332
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 3
    public function process(ContainerBuilder $container)
17
    {
18 3
        if (false === $container->hasDefinition('dtc_queue.worker_manager')) {
19 3
            return;
20
        }
21
22 3
        $this->setupAliases($container);
23
24 3
        $definition = $container->getDefinition('dtc_queue.worker_manager');
25 3
        $jobManagerRef = array(new Reference('dtc_queue.job_manager'));
26
27 3
        $jobClass = $this->getJobClass($container);
28 3
        $jobArchiveClass = $this->getJobClassArchive($container);
29 3
        $container->setParameter('dtc_queue.class_job', $jobClass);
30 3
        $container->setParameter('dtc_queue.class_job_archive', $jobArchiveClass);
31 3
        $container->setParameter('dtc_queue.class_job_timing', $this->getClass($container, 'job_timing',
32 3
            'JobTiming', JobTiming::class));
33 3
        $container->setParameter('dtc_queue.class_run', $this->getClass($container, 'run', 'Run', Run::class));
34 3
        $container->setParameter('dtc_queue.class_run_archive', $this->getClass($container, 'run_archive', 'RunArchive', Run::class));
35
36 3
        $this->setupTaggedServices($container, $definition, $jobManagerRef, $jobClass);
37 2
        $eventDispatcher = $container->getDefinition('dtc_queue.event_dispatcher');
38 2
        foreach ($container->findTaggedServiceIds('dtc_queue.event_subscriber') as $id => $attributes) {
39
            $eventSubscriber = $container->getDefinition($id);
40
            $eventDispatcher->addMethodCall('addSubscriber', [$eventSubscriber]);
41 2
        }
42 2
        $this->setupDoctrineManagers($container);
43 2
    }
44
45 3
    protected function setupAliases(ContainerBuilder $container)
46
    {
47 3
        $defaultManagerType = $container->getParameter('dtc_queue.default_manager');
48 3
        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 3
        $defaultRunManagerType = $container->getParameter('dtc_queue.run_manager');
53 3
        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 3
        $alias = new Alias('dtc_queue.job_manager.'.$defaultManagerType);
58 3
        $container->setAlias('dtc_queue.job_manager', $alias);
59
60 3
        $alias = new Alias('dtc_queue.run_manager.'.$defaultRunManagerType);
61 3
        $container->setAlias('dtc_queue.run_manager', $alias);
62 3
    }
63
64
    /**
65
     * @param ContainerBuilder $container
66
     * @param Reference[]      $jobManagerRef
67
     * @param string           $jobClass
68
     */
69 3
    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 3
        foreach ($container->findTaggedServiceIds('dtc_queue.worker') as $id => $attributes) {
73 2
            $worker = $container->getDefinition($id);
74 2
            $class = $container->getDefinition($id)->getClass();
75
76 2
            $refClass = new \ReflectionClass($class);
77 2
            $workerClass = 'Dtc\QueueBundle\Model\Worker';
78 2
            if (!$refClass->isSubclassOf($workerClass)) {
79 1
                throw new \InvalidArgumentException(sprintf('Service "%s" must extend class "%s".', $id, $workerClass));
80
            }
81
82
            // Give each worker access to job manager
83 1
            $worker->addMethodCall('setJobManager', $jobManagerRef);
84 1
            $worker->addMethodCall('setJobClass', array($jobClass));
85
86 1
            $definition->addMethodCall('addWorker', array(new Reference($id)));
87 2
        }
88 2
    }
89
90 2
    protected function setupDoctrineManagers(ContainerBuilder $container)
91
    {
92 2
        $documentManager = $container->getParameter('dtc_queue.document_manager');
93
94 2
        $odmManager = "doctrine_mongodb.odm.{$documentManager}_document_manager";
95 2
        if ($container->has($odmManager)) {
96
            $container->setAlias('dtc_queue.document_manager', $odmManager);
97
        }
98
99 2
        $entityManager = $container->getParameter('dtc_queue.entity_manager');
100
101 2
        $ormManager = "doctrine.orm.{$entityManager}_entity_manager";
102 2
        if ($container->has($ormManager)) {
103
            $container->setAlias('dtc_queue.entity_manager', $ormManager);
104
        }
105 2
    }
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 3
    protected function getJobClass(ContainerBuilder $container)
117
    {
118 3
        $jobClass = $container->getParameter('dtc_queue.class_job');
119 3
        if (!$jobClass) {
120 3
            switch ($defaultType = $container->getParameter('dtc_queue.default_manager')) {
121 3
                case 'mongodb': // deprecated remove in 3.0
122 3
                case 'odm':
123 3
                    $jobClass = 'Dtc\\QueueBundle\\Document\\Job';
124 3
                    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 3
            }
137 3
        }
138
139 3
        $this->testClass($jobClass, Job::class);
140
141 3
        return $jobClass;
142
    }
143
144 3
    protected function getClass(ContainerBuilder $container, $type, $className, $baseClass)
145
    {
146 3
        $runClass = $container->hasParameter('dtc_queue.class_'.$type) ? $container->getParameter('dtc_queue.class_'.$type) : null;
147 3
        if (!$runClass) {
148 3
            switch ($container->getParameter('dtc_queue.default_manager')) {
149 3
                case 'mongodb': // deprecated remove in 3.0
150 3
                case 'odm':
151 3
                    $runClass = 'Dtc\\QueueBundle\\Document\\'.$className;
152 3
                    break;
153
                case 'orm':
154
                    $runClass = 'Dtc\\QueueBundle\\Entity\\'.$className;
155
                    break;
156
                default:
157
                    $runClass = $baseClass;
158 3
            }
159 3
        }
160
161 3
        $this->testClass($runClass, $baseClass);
162
163 3
        return $runClass;
164
    }
165
166
    /**
167
     * @throws \Exception
168
     */
169 3
    protected function testClass($className, $parent)
170
    {
171 3
        if (!class_exists($className)) {
172
            throw new \Exception("Can't find class $className");
173
        }
174
175 3
        $test = new $className();
176 3
        if (!$test instanceof $className) {
177
            throw new \Exception("$className must be instance of (or derived from) $parent");
178
        }
179 3
    }
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 3
    protected function getJobClassArchive(ContainerBuilder $container)
191
    {
192 3
        $jobArchiveClass = $container->getParameter('dtc_queue.class_job_archive');
193 3
        if (!$jobArchiveClass) {
194 3
            switch ($container->getParameter('dtc_queue.default_manager')) {
195 3
                case 'mongodb': // deprecated remove in 4.0
196 3
                case 'odm':
197 3
                    $jobArchiveClass = 'Dtc\\QueueBundle\\Document\\JobArchive';
198 3
                    break;
199
                case 'orm':
200
                    $jobArchiveClass = 'Dtc\\QueueBundle\\Entity\\JobArchive';
201
                    break;
202 3
            }
203 3
        }
204 3
        if (null !== $jobArchiveClass) {
205 3
            $this->testClass($jobArchiveClass, Job::class);
206 3
        }
207
208 3
        return $jobArchiveClass;
209
    }
210
}
211