Completed
Push — master ( 657761...4271e2 )
by Tomasz
05:00
created

WorkerRunnersPass::addManagerCalls()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 4
crap 2
1
<?php
2
3
namespace Gendoria\CommandQueueBundle\DependencyInjection\Pass;
4
5
use Gendoria\CommandQueueBundle\Worker\WorkerRunnerInterface;
6
use InvalidArgumentException;
7
use ReflectionClass;
8
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
9
use Symfony\Component\DependencyInjection\ContainerBuilder;
10
use Symfony\Component\DependencyInjection\Definition;
11
12
/**
13
 * Description of WorkersPass
14
 *
15
 * @author Tomasz Struczyński <[email protected]>
16
 */
17
class WorkerRunnersPass implements CompilerPassInterface
18
{
19
20
    const WORKER_RUNNER_TAG = 'gendoria_command_queue.worker';
21
    const MANAGER_ID = 'gendoria_command_queue.runner_manager';
22
23
    /**
24
     * Process all services tagged as worker runners and add them to runner manager service.
25
     * 
26
     * @param ContainerBuilder $container
27
     * @throws InvalidArgumentException Thrown, if service initialization failed.
28
     */
29 5
    public function process(ContainerBuilder $container)
30
    {
31 5
        $manager = $container->findDefinition(self::MANAGER_ID);
32
33 5
        $serviceIds = $container->findTaggedServiceIds(self::WORKER_RUNNER_TAG);
34 5
        foreach ($serviceIds as $serviceId => $tags) {
35 4
            $this->addManagerCalls($container, $manager, $serviceId, $tags);
36 2
        }
37 2
    }
38
39
    /**
40
     * Parse single tagged service.
41
     * 
42
     * @param ContainerBuilder $container
43
     * @param Definition $manager
44
     * @param string $serviceId
45
     * @param array $tags
46
     * @throws InvalidArgumentException Thrown, if service initialization failed.
47
     */
48 4
    private function addManagerCalls(ContainerBuilder $container, Definition $manager, $serviceId, array $tags)
49
    {
50 4
        foreach ($tags as $tag) {
51 4
            $this->addManagerCall($container, $manager, $serviceId, $tag);
52 1
        }
53 1
    }
54
55
    /**
56
     * Parse single tagged service tag.
57
     * 
58
     * @param ContainerBuilder $container
59
     * @param Definition $manager
60
     * @param string $serviceId
61
     * @param array $tag
62
     * @throws InvalidArgumentException Thrown, if service initialization failed.
63
     */
64 4
    private function addManagerCall(ContainerBuilder $container, Definition $manager, $serviceId, array $tag)
65
    {
66 4
        $this->assertCorrectName($tag);
67 3
        $this->assertCorrectService($container, $serviceId);
68 2
        $options = !empty($tag['options']) ? json_decode($tag['options'], true) : array();
69 2
        $this->assertCorrectOptions($options);
70 1
        $manager->addMethodCall('addRunner', array($tag['name'], $serviceId, $options));
71 1
    }
72
    
73
    /**
74
     * Assert correct tag structure.
75
     * 
76
     * @param array $tag
77
     * @throws InvalidArgumentException Thrown, if tag does not contain correct fields.
78
     */
79 4
    private function assertCorrectName(array $tag)
80
    {
81 4
        if (empty($tag['name'])) {
82 1
            throw new InvalidArgumentException('Tag '.self::WORKER_RUNNER_TAG.' has to contain "name" parameter.');
83
        }
84 3
    }
85
    
86
    /**
87
     * Assert correct options structure.
88
     * 
89
     * @param moxed $options
90
     * @throws InvalidArgumentException Thrown, if options are invalid (not an array).
91
     */
92 2
    private function assertCorrectOptions($options)
93
    {
94 2
        if (!is_array($options)) {
95 1
            throw new InvalidArgumentException('Options parameter has to be a valid JSON.');
96
        }
97 1
    }
98
    
99
    /**
100
     * Assert valid tagged service.
101
     * 
102
     * @param ContainerBuilder $container
103
     * @param string $serviceId
104
     * @throws InvalidArgumentException Thrown, if tagged service does not implement correct interfaces.
105
     */
106 3
    private function assertCorrectService(ContainerBuilder $container, $serviceId)
107
    {
108 3
        $definition = $container->findDefinition($serviceId);
109 3
        $reflection = new ReflectionClass($definition->getClass());
110 3
        if (!$reflection->implementsInterface(WorkerRunnerInterface::class)) {
111 1
            throw new InvalidArgumentException('Runner service has to implement WorkerRunnerInterface.');
112
        }
113 2
    }
114
}
115