Completed
Push — master ( d0194b...ae48f4 )
by Matthew
07:32
created

WorkerCompilerPass::setupAliases()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 6
cts 6
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 1
crap 1
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
        }
42 2
        $this->setupDoctrineManagers($container);
43 2
    }
44
45 3
    protected function setupAlias(ContainerBuilder $container, $defaultManagerType, $type)
46
    {
47 3
        $definitionName = 'dtc_queue.'.$type.'.'.$defaultManagerType;
48 3
        if (!$container->hasDefinition($definitionName) && !$container->hasAlias($definitionName)) {
49
            throw new \Exception("No job manager found for dtc_queue.'.$type.'.$defaultManagerType");
50
        }
51 3
        if ($container->hasDefinition($definitionName)) {
52 3
            $alias = new Alias('dtc_queue.'.$type.'.'.$defaultManagerType);
53 3
            $container->setAlias('dtc_queue.'.$type, $alias);
54
        } else {
55
            $container->setAlias('dtc_queue.'.$type, $container->getAlias($definitionName));
56
        }
57 3
    }
58
59 3
    protected function setupAliases(ContainerBuilder $container)
60
    {
61 3
        $defaultManagerType = $container->getParameter('dtc_queue.default_manager');
62 3
        $this->setupAlias($container, $defaultManagerType, 'job_manager');
63 3
        $defaultRunManagerType = $container->getParameter('dtc_queue.run_manager');
64 3
        $this->setupAlias($container, $defaultRunManagerType, 'run_manager');
65 3
    }
66
67
    /**
68
     * @param ContainerBuilder $container
69
     * @param Reference[]      $jobManagerRef
70
     * @param string           $jobClass
71
     */
72 3
    protected function setupTaggedServices(ContainerBuilder $container, Definition $definition, array $jobManagerRef, $jobClass)
73
    {
74
        // Add each worker to workerManager, make sure each worker has instance to work
75 3
        foreach ($container->findTaggedServiceIds('dtc_queue.worker') as $id => $attributes) {
76 2
            $worker = $container->getDefinition($id);
77 2
            $class = $container->getDefinition($id)->getClass();
78
79 2
            $refClass = new \ReflectionClass($class);
80 2
            $workerClass = 'Dtc\QueueBundle\Model\Worker';
81 2
            if (!$refClass->isSubclassOf($workerClass)) {
82 1
                throw new \InvalidArgumentException(sprintf('Service "%s" must extend class "%s".', $id, $workerClass));
83
            }
84
85
            // Give each worker access to job manager
86 1
            $worker->addMethodCall('setJobManager', $jobManagerRef);
87 1
            $worker->addMethodCall('setJobClass', array($jobClass));
88
89 1
            $definition->addMethodCall('addWorker', array(new Reference($id)));
90
        }
91 2
    }
92
93 2
    protected function setupDoctrineManagers(ContainerBuilder $container)
94
    {
95 2
        $documentManager = $container->getParameter('dtc_queue.document_manager');
96
97 2
        $odmManager = "doctrine_mongodb.odm.{$documentManager}_document_manager";
98 2
        if ($container->has($odmManager)) {
99
            $container->setAlias('dtc_queue.document_manager', $odmManager);
100
        }
101
102 2
        $entityManager = $container->getParameter('dtc_queue.entity_manager');
103
104 2
        $ormManager = "doctrine.orm.{$entityManager}_entity_manager";
105 2
        if ($container->has($ormManager)) {
106
            $container->setAlias('dtc_queue.entity_manager', $ormManager);
107
        }
108 2
    }
109
110
    /**
111
     * Determines the job class based on the queue manager type.
112
     *
113
     * @param ContainerBuilder $container
114
     *
115
     * @return mixed|string
116
     *
117
     * @throws \Exception
118
     */
119 3
    protected function getJobClass(ContainerBuilder $container)
120
    {
121 3
        $jobClass = $container->getParameter('dtc_queue.class_job');
122 3
        if (!$jobClass) {
123 3
            switch ($defaultType = $container->getParameter('dtc_queue.default_manager')) {
124 3
                case 'mongodb': // deprecated remove in 3.0
125 3
                case 'odm':
126 3
                    $jobClass = 'Dtc\\QueueBundle\\Document\\Job';
127 3
                    break;
128
                case 'beanstalkd':
129
                    $jobClass = 'Dtc\\QueueBundle\\Beanstalkd\\Job';
130
                    break;
131
                case 'rabbit_mq':
132
                    $jobClass = 'Dtc\\QueueBundle\\RabbitMQ\\Job';
133
                    break;
134
                case 'orm':
135
                    $jobClass = 'Dtc\\QueueBundle\\Entity\\Job';
136
                    break;
137
                default:
138
                    throw new \Exception('Unknown default_manager type '.$defaultType.' - please specify a Job class in the \'class\' configuration parameter');
139
            }
140
        }
141
142 3
        $this->testClass($jobClass, Job::class);
143
144 3
        return $jobClass;
145
    }
146
147 3
    protected function getClass(ContainerBuilder $container, $type, $className, $baseClass)
148
    {
149 3
        $runClass = $container->hasParameter('dtc_queue.class_'.$type) ? $container->getParameter('dtc_queue.class_'.$type) : null;
150 3
        if (!$runClass) {
151 3
            switch ($container->getParameter('dtc_queue.default_manager')) {
152 3
                case 'mongodb': // deprecated remove in 3.0
153 3
                case 'odm':
154 3
                    $runClass = 'Dtc\\QueueBundle\\Document\\'.$className;
155 3
                    break;
156
                case 'orm':
157
                    $runClass = 'Dtc\\QueueBundle\\Entity\\'.$className;
158
                    break;
159
                default:
160
                    $runClass = $baseClass;
161
            }
162
        }
163
164 3
        $this->testClass($runClass, $baseClass);
165
166 3
        return $runClass;
167
    }
168
169
    /**
170
     * @throws \Exception
171
     */
172 3
    protected function testClass($className, $parent)
173
    {
174 3
        if (!class_exists($className)) {
175
            throw new \Exception("Can't find class $className");
176
        }
177
178 3
        $test = new $className();
179 3
        if (!$test instanceof $className) {
180
            throw new \Exception("$className must be instance of (or derived from) $parent");
181
        }
182 3
    }
183
184
    /**
185
     * Determines the job class based on the queue manager type.
186
     *
187
     * @param ContainerBuilder $container
188
     *
189
     * @return mixed|string
190
     *
191
     * @throws \Exception
192
     */
193 3
    protected function getJobClassArchive(ContainerBuilder $container)
194
    {
195 3
        $jobArchiveClass = $container->getParameter('dtc_queue.class_job_archive');
196 3
        if (!$jobArchiveClass) {
197 3
            switch ($container->getParameter('dtc_queue.default_manager')) {
198 3
                case 'mongodb': // deprecated remove in 4.0
199 3
                case 'odm':
200 3
                    $jobArchiveClass = 'Dtc\\QueueBundle\\Document\\JobArchive';
201 3
                    break;
202
                case 'orm':
203
                    $jobArchiveClass = 'Dtc\\QueueBundle\\Entity\\JobArchive';
204
                    break;
205
            }
206
        }
207 3
        if (null !== $jobArchiveClass) {
208 3
            $this->testClass($jobArchiveClass, Job::class);
209
        }
210
211 3
        return $jobArchiveClass;
212
    }
213
}
214