Completed
Push — master ( 930f1d...b58b30 )
by Matthew
06:42
created

WorkerCompilerPass::process()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 30
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 3.0067

Importance

Changes 0
Metric Value
dl 0
loc 30
ccs 20
cts 22
cp 0.9091
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 21
nc 3
nop 1
crap 3.0067
1
<?php
2
3
namespace Dtc\QueueBundle\DependencyInjection\Compiler;
4
5
use Dtc\GridBundle\DependencyInjection\Compiler\GridSourceCompilerPass;
6
use Dtc\QueueBundle\Model\Job;
7
use Dtc\QueueBundle\Model\JobTiming;
8
use Dtc\QueueBundle\Model\Run;
9
use Dtc\QueueBundle\Exception\ClassNotFoundException;
10
use Dtc\QueueBundle\Exception\ClassNotSubclassException;
11
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
12
use Symfony\Component\DependencyInjection\Alias;
13
use Symfony\Component\DependencyInjection\ContainerBuilder;
14
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
15
use Symfony\Component\DependencyInjection\Definition;
16
use Symfony\Component\DependencyInjection\Reference;
17
18
class WorkerCompilerPass implements CompilerPassInterface
19
{
20 3
    public function process(ContainerBuilder $container)
21
    {
22 3
        if (false === $container->hasDefinition('dtc_queue.worker_manager')) {
23 3
            return;
24
        }
25
26 3
        $this->setupAliases($container);
27
28 3
        $definition = $container->getDefinition('dtc_queue.worker_manager');
29
30 3
        $jobClass = $this->getJobClass($container);
31 3
        $jobArchiveClass = $this->getJobClassArchive($container);
32 3
        $container->setParameter('dtc_queue.class_job', $jobClass);
33 3
        $container->setParameter('dtc_queue.class_job_archive', $jobArchiveClass);
34
35 3
        $managerType = $this->getRunManagerType($container);
36 3
        $jobTimingManagerType = $this->getJobTimingManagerType($container);
37 3
        $container->setParameter('dtc_queue.class_job_timing', $this->getClass($container, $jobTimingManagerType, 'job_timing',
38 3
            'JobTiming', JobTiming::class));
39 3
        $container->setParameter('dtc_queue.class_run', $this->getClass($container, $managerType, 'run', 'Run', Run::class));
40 3
        $container->setParameter('dtc_queue.class_run_archive', $this->getClass($container, $managerType, 'run_archive', 'RunArchive', Run::class));
41
42 3
        $this->setupTaggedServices($container, $definition, $jobClass);
43 2
        $eventDispatcher = $container->getDefinition('dtc_queue.event_dispatcher');
44 2
        foreach ($container->findTaggedServiceIds('dtc_queue.event_subscriber') as $id => $attributes) {
45
            $eventSubscriber = $container->getDefinition($id);
46
            $eventDispatcher->addMethodCall('addSubscriber', [$eventSubscriber]);
47
        }
48 2
        $this->setupDoctrineManagers($container);
49 2
    }
50
51 3
    protected function setupAlias(ContainerBuilder $container, $defaultManagerType, $type)
52
    {
53 3
        $definitionName = 'dtc_queue.'.$type.'.'.$defaultManagerType;
54 3
        if (!$container->hasDefinition($definitionName) && !$container->hasAlias($definitionName)) {
55
            throw new InvalidConfigurationException("No $type manager found for dtc_queue.$type.$defaultManagerType");
56
        }
57 3
        if ($container->hasDefinition($definitionName)) {
58 3
            $alias = new Alias('dtc_queue.'.$type.'.'.$defaultManagerType);
59 3
            $alias->setPublic(true);
60 3
            $container->setAlias('dtc_queue.'.$type, $alias);
61
62 3
            return;
63
        }
64
65
        $container->getAlias($definitionName)->setPublic(true);
66
        $container->setAlias('dtc_queue.'.$type, $container->getAlias($definitionName));
67
    }
68
69 3
    protected function setupAliases(ContainerBuilder $container)
70
    {
71 3
        $defaultManagerType = $container->getParameter('dtc_queue.default_manager');
72 3
        $this->setupAlias($container, $defaultManagerType, 'job_manager');
73 3
        $runManagerType = $container->getParameter($this->getRunManagerType($container));
74 3
        $this->setupAlias($container, $runManagerType, 'run_manager');
75 3
        $jobTimingManagerType = $container->getParameter($this->getJobTimingManagerType($container));
76 3
        $this->setupAlias($container, $jobTimingManagerType, 'job_timing_manager');
77 3
    }
78
79
    /**
80
     * @param ContainerBuilder $container
81
     * @param Reference[]      $jobManagerRef
0 ignored issues
show
Bug introduced by
There is no parameter named $jobManagerRef. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
82
     * @param string           $jobClass
83
     */
84 3
    protected function setupTaggedServices(ContainerBuilder $container, Definition $definition, $jobClass)
85
    {
86 3
        $jobManagerRef = array(new Reference('dtc_queue.job_manager'));
87
        // Add each worker to workerManager, make sure each worker has instance to work
88 3
        foreach ($container->findTaggedServiceIds('dtc_queue.worker') as $id => $attributes) {
89 2
            $worker = $container->getDefinition($id);
90 2
            $class = $container->getDefinition($id)->getClass();
91
92 2
            $refClass = new \ReflectionClass($class);
93 2
            $workerClass = 'Dtc\QueueBundle\Model\Worker';
94 2
            if (!$refClass->isSubclassOf($workerClass)) {
95 1
                throw new \InvalidArgumentException(sprintf('Service "%s" must extend class "%s".', $id, $workerClass));
96
            }
97
98
            // Give each worker access to job manager
99 1
            $worker->addMethodCall('setJobManager', $jobManagerRef);
100 1
            $worker->addMethodCall('setJobClass', array($jobClass));
101
102 1
            $definition->addMethodCall('addWorker', array(new Reference($id)));
103
        }
104 2
    }
105
106 2
    protected function setupDoctrineManagers(ContainerBuilder $container)
107
    {
108 2
        $documentManager = $container->getParameter('dtc_queue.document_manager');
109
110 2
        $odmManager = "doctrine_mongodb.odm.{$documentManager}_document_manager";
111 2
        if ($container->has($odmManager)) {
112
            $container->setAlias('dtc_queue.document_manager', $odmManager);
113
            GridSourceCompilerPass::addGridSource($container, 'dtc_queue.grid_source.live_jobs.odm');
114
        }
115
116 2
        $entityManager = $container->getParameter('dtc_queue.entity_manager');
117
118 2
        $ormManager = "doctrine.orm.{$entityManager}_entity_manager";
119 2
        if ($container->has($ormManager)) {
120
            $container->setAlias('dtc_queue.entity_manager', $ormManager);
121
            GridSourceCompilerPass::addGridSource($container, 'dtc_queue.grid_source.live_jobs.orm');
122
        }
123 2
    }
124
125
    /**
126
     * @param $managerType
127
     *
128
     * @return null|string
129
     */
130 3
    protected function getDirectory($managerType)
131
    {
132
        switch ($managerType) {
133 3
            case 'mongodb': // deprecated remove in 3.0
134 3
            case 'odm':
135 3
                return 'Document';
136
            case 'beanstalkd':
137
                return 'Beanstalkd';
138
            case 'rabbit_mq':
139
                return 'RabbitMQ';
140
            case 'orm':
141
                return 'Entity';
142
        }
143
144
        return null;
145
    }
146
147
    /**
148
     * Determines the job class based on the queue manager type.
149
     *
150
     * @param ContainerBuilder $container
151
     *
152
     * @return mixed|string
153
     *
154
     * @throws InvalidConfigurationException
155
     */
156 3
    protected function getJobClass(ContainerBuilder $container)
157
    {
158 3
        $jobClass = $container->getParameter('dtc_queue.class_job');
159 3
        if (!$jobClass) {
160 3
            if ($directory = $this->getDirectory($managerType = $container->getParameter('dtc_queue.default_manager'))) {
161 3
                $jobClass = 'Dtc\QueueBundle\\'.$directory.'\Job';
162
            } else {
163
                throw new InvalidConfigurationException('Unknown default_manager type '.$managerType.' - please specify a Job class in the \'class\' configuration parameter');
164
            }
165
        }
166
167 3
        $this->testClass($jobClass, Job::class);
168
169 3
        return $jobClass;
170
    }
171
172 3
    protected function getRunManagerType(ContainerBuilder $container)
173
    {
174 3
        $managerType = 'dtc_queue.default_manager';
175 3
        if ($container->hasParameter('dtc_queue.run_manager')) {
176 3
            $managerType = 'dtc_queue.run_manager';
177
        }
178
179 3
        return $managerType;
180
    }
181
182 3
    protected function getJobTimingManagerType(ContainerBuilder $container)
183
    {
184 3
        $managerType = $this->getRunManagerType($container);
185 3
        if ($container->hasParameter('dtc_queue.job_timing_manager')) {
186
            $managerType = 'dtc_queue.job_timing_manager';
187
        }
188
189 3
        return $managerType;
190
    }
191
192 3
    protected function getClass(ContainerBuilder $container, $managerType, $type, $className, $baseClass)
193
    {
194 3
        $runClass = $container->hasParameter('dtc_queue.class_'.$type) ? $container->getParameter('dtc_queue.class_'.$type) : null;
195 3
        if (!$runClass) {
196 3
            switch ($container->getParameter($managerType)) {
197 3
                case 'mongodb': // deprecated remove in 3.0
198 3
                case 'odm':
199 3
                    $runClass = 'Dtc\\QueueBundle\\Document\\'.$className;
200 3
                    break;
201
                case 'orm':
202
                    $runClass = 'Dtc\\QueueBundle\\Entity\\'.$className;
203
                    break;
204
                default:
205
                    $runClass = $baseClass;
206
            }
207
        }
208
209 3
        $this->testClass($runClass, $baseClass);
210
211 3
        return $runClass;
212
    }
213
214
    /**
215
     * @throws ClassNotFoundException
216
     * @throws ClassNotSubclassException
217
     */
218 3
    protected function testClass($className, $parent)
219
    {
220 3
        if (!class_exists($className)) {
221
            throw new ClassNotFoundException("Can't find class $className");
222
        }
223
224 3
        $test = new $className();
225 3
        if (!$test instanceof $className) {
226
            throw new ClassNotSubclassException("$className must be instance of (or derived from) $parent");
227
        }
228 3
    }
229
230
    /**
231
     * Determines the job class based on the queue manager type.
232
     *
233
     * @param ContainerBuilder $container
234
     *
235
     * @return mixed|string
236
     *
237
     * @throws ClassNotFoundException
238
     * @throws ClassNotSubclassException
239
     */
240 3
    protected function getJobClassArchive(ContainerBuilder $container)
241
    {
242 3
        $jobArchiveClass = $container->getParameter('dtc_queue.class_job_archive');
243 3
        if (!$jobArchiveClass) {
244 3
            switch ($container->getParameter('dtc_queue.default_manager')) {
245 3
                case 'mongodb': // deprecated remove in 4.0
246 3
                case 'odm':
247 3
                    $jobArchiveClass = 'Dtc\\QueueBundle\\Document\\JobArchive';
248 3
                    break;
249
                case 'orm':
250
                    $jobArchiveClass = 'Dtc\\QueueBundle\\Entity\\JobArchive';
251
                    break;
252
            }
253
        }
254 3
        if (null !== $jobArchiveClass) {
255 3
            $this->testClass($jobArchiveClass, Job::class);
256
        }
257
258 3
        return $jobArchiveClass;
259
    }
260
}
261