Completed
Push — master ( e9aa87...4d1ca6 )
by Tomasz
08:27
created

PoolsPass::setupSingleQueueManager()   B

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\QueueManagerInterface;
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 12
    public function process(ContainerBuilder $container)
47
    {
48 12
        $pools = $container->getParameter('gendoria_command_queue.pools');
49 12
        $usedServiceIds = array();
50
51 12
        foreach ($pools as $poolData) {
52 12
            $sendServiceId = substr($poolData['send_driver'], 1);
53 12
            if (in_array($sendServiceId, $usedServiceIds)) {
54 1
                throw new InvalidArgumentException(sprintf(
55 1
                    'Each pool has to have unique send service - duplicate service id "%s" found.',
56
                    $sendServiceId
57 1
                ));
58
            }
59 12
            if (!$container->hasDefinition($sendServiceId)) {
60 1
                throw new InvalidArgumentException('Non existing send driver service provided: ' . $poolData['send_driver'].'.');
61
            }
62 11
            $sendDriverReflection = new ReflectionClass($container->getDefinition($sendServiceId)->getClass());
63 11
            if (!$sendDriverReflection->implementsInterface(SendDriverInterface::class)) {
64 1
                throw new InvalidArgumentException(sprintf(
65 1
                    'Service "%s" does not implement interface "%s".',
66 1
                    $sendServiceId,
67
                    SendDriverInterface::class
68 1
                ));
69
            }
70 10
            $usedServiceIds[] = $sendServiceId;
71 10
        }
72
73 9
        foreach ($container->findTaggedServiceIds(self::QUEUE_MANAGER_TAG) as $id => $tags) {
74 9
            $def = $container->getDefinition($id);
75 9
            $reflection = new ReflectionClass($def->getClass());
76 9
            if ($reflection->implementsInterface(QueueManagerInterface::class)) {
77 8
                $this->setupSingleQueueManager($id, $def, $tags, $pools);
78 7
            } elseif ($reflection->implementsInterface(MultipleQueueManagerInterface::class)) {
79 6
                $this->setupMultipleQueueManager($id, $def, $tags, $pools);
80 6
            } else {
81 1
                throw new InvalidArgumentException(sprintf('Service "%s" does not implement one of required interfaces.', $id));
82
            }
83 6
        }
84 6
    }
85
86 8
    private function setupSingleQueueManager($id, Definition $def, array $tags, array $pools)
87
    {
88 8
        if (count($tags) > 1) {
89 1
            throw new InvalidArgumentException('Only single ' . self::QUEUE_MANAGER_TAG . ' tag possible on service ' . $id.'.');
90
        }
91 7
        if (!empty($tags[0]['pool'])) {
92 7
            $poolName = $tags[0]['pool'];
93 7
        } else {
94 1
            $poolName = 'default';
95
        }
96 7
        if (empty($pools[$poolName])) {
97 1
            throw new InvalidArgumentException(sprintf(
98 1
                'Service "%s" requests non existing queue pool "%s".',
99 1
                $id,
100
                $poolName
101 1
            ));
102
        }
103 6
        $def->addMethodCall(
104 6
            'setSendDriver',
105 6
            array(new Reference(substr($pools[$poolName]['send_driver'], 1)))
106 6
        );
107 6
    }
108
109 6
    private function setupMultipleQueueManager($id, Definition $def, array $tags, array $pools)
110
    {
111 6
        foreach ($tags as $tag) {
112 6
            if (!empty($tag['pool'])) {
113 6
                $poolName = $tag['pool'];
114 6
            } else {
115 3
                $poolName = 'default';
116
            }
117 6
            $isDefault = !empty($tag['default']);
118 6
            if (empty($pools[$poolName])) {
119
                throw new InvalidArgumentException(sprintf(
120
                    'Service "%s" requests non existing queue pool "%s".',
121
                    $id,
122
                    $poolName
123
                ));
124
            }
125 6
            $def->addMethodCall(
126 6
                'addSendDriver',
127 6
                array($poolName, new Reference(substr($pools[$poolName]['send_driver'], 1)), $isDefault)
128 6
            );
129 6
        }
130 6
    }
131
}
132