PoolsPass::setupSingleQueueManager()   B
last analyzed

Complexity

Conditions 4
Paths 5

Size

Total Lines 22
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 17
cts 17
cp 1
rs 8.9197
c 0
b 0
f 0
cc 4
eloc 15
nc 5
nop 4
crap 4
1
<?php
2
3
/*
4
 * This file is part of the Symfony package.
5
 *
6
 * (c) Fabien Potencier <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Gendoria\CommandQueueBundle\DependencyInjection\Pass;
13
14
use Gendoria\CommandQueue\QueueManager\MultipleQueueManagerInterface;
15
use Gendoria\CommandQueue\QueueManager\SingleQueueManagerInterface;
16
use Gendoria\CommandQueue\SendDriver\SendDriverInterface;
17
use InvalidArgumentException;
18
use ReflectionClass;
19
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
20
use Symfony\Component\DependencyInjection\ContainerBuilder;
21
use Symfony\Component\DependencyInjection\Definition;
22
use Symfony\Component\DependencyInjection\Reference;
23
24
/**
25
 * Compiler pass to register tagged services for an event dispatcher.
26
 */
27
class PoolsPass implements CompilerPassInterface
28
{
29
30
    /**
31
     * Queue manager tag name.
32
     *
33
     * @var string
34
     */
35
    const QUEUE_MANAGER_TAG = 'gendoria_command_queue.send_manager';
36
37
    /**
38
     * Prepares command queue pools based on bundle configuration.
39
     *
40
     * Function also attaches specific pools to services tagged with {@link QUEUE_MANAGER_TAG} tag.
41
     *
42
     * @param ContainerBuilder $container
43
     *
44
     * @throws InvalidArgumentException
45
     */
46 14
    public function process(ContainerBuilder $container)
47
    {
48 14
        $this->setupPools($container);
49
        
50 11
        $pools = $container->getParameter('gendoria_command_queue.pools');
51
52 11
        foreach ($container->findTaggedServiceIds(self::QUEUE_MANAGER_TAG) as $id => $tags) {
53 11
            $def = $container->getDefinition($id);
54 11
            $reflection = new ReflectionClass($def->getClass());
55 11
            if ($reflection->implementsInterface(MultipleQueueManagerInterface::class)) {
56 6
                $this->setupMultipleQueueManager($id, $def, $tags, $pools);
57 10
            } elseif ($reflection->implementsInterface(SingleQueueManagerInterface::class)) {
58 6
                $this->setupSingleQueueManager($id, $def, $tags, $pools);
59 4
            } else {
60 1
                throw new InvalidArgumentException(sprintf('Service "%s" does not implement one of required interfaces.', $id));
61
            }
62 7
        }
63 7
    }
64
    
65
    /**
66
     * Setup pools.
67
     * 
68
     * @param ContainerBuilder $container
69
     * @throws InvalidArgumentException
70
     * @return void
71
     */
72 14
    private function setupPools(ContainerBuilder $container)
73
    {
74 14
        $pools = $container->getParameter('gendoria_command_queue.pools');
75 14
        $usedServiceIds = array();
76 14
        foreach ($pools as $poolData) {
77 14
            $sendServiceId = substr($poolData['send_driver'], 1);
78 14
            if (in_array($sendServiceId, $usedServiceIds)) {
79 1
                throw new InvalidArgumentException(sprintf(
80 1
                    'Each pool has to have unique send service - duplicate service id "%s" found.',
81
                    $sendServiceId
82 1
                ));
83
            }
84 14
            if (!$container->hasDefinition($sendServiceId)) {
85 1
                throw new InvalidArgumentException('Non existing send driver service provided: ' . $poolData['send_driver'].'.');
86
            }
87 13
            $sendDriverReflection = new ReflectionClass($container->getDefinition($sendServiceId)->getClass());
88 13
            if (!$sendDriverReflection->implementsInterface(SendDriverInterface::class)) {
89 1
                throw new InvalidArgumentException(sprintf(
90 1
                    'Service "%s" does not implement interface "%s".',
91 1
                    $sendServiceId,
92
                    SendDriverInterface::class
93 1
                ));
94
            }
95 12
            $usedServiceIds[] = $sendServiceId;
96 12
        }
97 11
    }
98
99 6
    private function setupSingleQueueManager($id, Definition $def, array $tags, array $pools)
100
    {
101 6
        if (count($tags) > 1) {
102 1
            throw new InvalidArgumentException('Only single ' . self::QUEUE_MANAGER_TAG . ' tag possible on service ' . $id.'.');
103
        }
104 5
        if (!empty($tags[0]['pool'])) {
105 4
            $poolName = $tags[0]['pool'];
106 4
        } else {
107 1
            $poolName = 'default';
108
        }
109 5
        if (empty($pools[$poolName])) {
110 1
            throw new InvalidArgumentException(sprintf(
111 1
                'Service "%s" requests non existing queue pool "%s".',
112 1
                $id,
113
                $poolName
114 1
            ));
115
        }
116 4
        $def->addMethodCall(
117 4
            'setSendDriver',
118 4
            array(new Reference(substr($pools[$poolName]['send_driver'], 1)))
119 4
        );
120 4
    }
121
122 6
    private function setupMultipleQueueManager($id, Definition $def, array $tags, array $pools)
123
    {
124 6
        foreach ($tags as $tag) {
125 6
            if (!empty($tag['pool'])) {
126 5
                $poolName = $tag['pool'];
127 5
            } else {
128 4
                $poolName = 'default';
129
            }
130 6
            $isDefault = !empty($tag['default']);
131 6
            if (empty($pools[$poolName])) {
132 1
                throw new InvalidArgumentException(sprintf(
133 1
                    'Service "%s" requests non existing queue pool "%s".',
134 1
                    $id,
135
                    $poolName
136 1
                ));
137
            }
138 6
            $def->addMethodCall(
139 6
                'addSendDriver',
140 6
                array($poolName, new Reference(substr($pools[$poolName]['send_driver'], 1)), $isDefault)
141 6
            );
142 6
        }
143 5
    }
144
}
145