Completed
Push — master ( 32a320...376923 )
by Jonathan
9s
created

CacheEncrypterCompilerPass::inflateServicesInTag()   A

Complexity

Conditions 4
Paths 1

Size

Total Lines 14
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 14
ccs 9
cts 9
cp 1
rs 9.2
cc 4
eloc 6
nc 1
nop 1
crap 4
1
<?php
2
namespace Jsq\Cache\DependencyInjection\Compiler;
3
4
use Jsq\Cache\EnvelopeEncryption\Decorator as EnvelopeEncryptionDecorator;
5
use Jsq\Cache\IronEncryption\Decorator as IronEncryptionDecorator;
6
use Jsq\Cache\PasswordEncryption\Decorator as PasswordEncryptionDecorator;
7
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
8
use Symfony\Component\DependencyInjection\ContainerBuilder;
9
use Symfony\Component\DependencyInjection\Definition;
10
use Symfony\Component\DependencyInjection\Reference;
11
12
class CacheEncrypterCompilerPass implements CompilerPassInterface
13
{
14 9
    public function process(ContainerBuilder $container)
15
    {
16 9
        $taggedServices = $container->findTaggedServiceIds('cache.encrypted');
17
18 9
        foreach ($taggedServices as $id => $tags) {
19 9
            $this->inflateServicesInTag($tags);
20
21 9
            foreach ($tags as $tag) {
22 9
                $container->setDefinition(
23 9
                    isset($tag['alias']) ? $tag['alias'] : "$id.encrypted",
24 9
                    $this->buildDecoratorDefinition($id, $tag)
25 9
                );
26 9
            }
27 9
        }
28 9
    }
29
30 12
    private function buildDecoratorDefinition($decorated, array $tag)
31
    {
32 12
        if ($this->arrayHasKeys($tag, ['certificate', 'key'])) {
33 9
            return $this->buildPkiDecoratorDefinition($decorated, $tag);
34 12
        } elseif ($this->arrayHasKeys($tag, ['iron', 'password'])
35 12
            && filter_var($tag['iron'], FILTER_VALIDATE_BOOLEAN)
36 12
        ) {
37 9
            return $this->buildIronDecoratorDefinition($decorated, $tag);
38
        }
39
40 12
        return $this->buildPasswordDecoratorDefinition($decorated, $tag);
41
    }
42
43 12
    private function buildPasswordDecoratorDefinition($decorated, array $tag)
44
    {
45 12
        if (empty($tag['password'])) {
46 3
            throw new \DomainException('Cannot encrypt a cache'
47 3
                . ' with an empty password.');
48
        }
49
50 9
        $args = [new Reference($decorated), $tag['password']];
51 9
        if (isset($tag['cipher'])) {
52 3
            $args []= $tag['cipher'];
53 3
        }
54
55 9
        return new Definition(PasswordEncryptionDecorator::class, $args);
56
    }
57
58 9
    private function buildIronDecoratorDefinition($decorated, array $tag)
59
    {
60 9
        $args = [new Reference($decorated), $tag['password']];
61 9
        if (isset($tag['cipher'])) {
62
            $args []= $tag['cipher'];
63
        }
64
65 9
        return new Definition(IronEncryptionDecorator::class, $args);
66
    }
67
68 9
    private function buildPkiDecoratorDefinition($decorated, array $tag)
69
    {
70 9
        $args = [new Reference($decorated), $tag['certificate'], $tag['key']];
71 9
        foreach (['password', 'cipher'] as $optionalParameter) {
72 9
            if (isset($tag[$optionalParameter])) {
73 3
                $args []= $tag[$optionalParameter];
74 3
            }
75 9
        }
76
77 9
        return new Definition(EnvelopeEncryptionDecorator::class, $args);
78
    }
79
80 12
    private function arrayHasKeys(array $array, array $keys)
81
    {
82 12
        foreach ($keys as $key) {
83 12
            if (!isset($array[$key])) {
84 12
                return false;
85
            }
86 9
        }
87
88 9
        return true;
89
    }
90
91
    private function inflateServicesInTag(array &$config)
92
    {
93 15
        array_walk_recursive($config, function (&$value) {
94 15
            if (is_string($value) && 0 === strpos($value, '@')) {
95
                // this is either a service reference or a string meant to
96
                // start with an '@' symbol. In any case, lop off the first '@'
97 15
                $value = substr($value, 1);
98 15
                if (0 !== strpos($value, '@')) {
99
                    // this is a service reference, not a string literal
100 12
                    $value = new Reference($value);
101 12
                }
102 15
            }
103 15
        });
104 15
    }
105
}
106