Completed
Push — master ( a625ec...5f07d4 )
by Nikola
03:04
created

CompilerPass::processInjection()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 29
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 7

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 29
ccs 17
cts 17
cp 1
rs 6.7272
cc 7
eloc 12
nc 6
nop 2
crap 7
1
<?php
2
/*
3
 * This file is part of the  TraitorBundle, an RunOpenCode project.
4
 *
5
 * (c) 2016 RunOpenCode
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace RunOpenCode\Bundle\Traitor\DependencyInjection;
11
12
use RunOpenCode\Bundle\Traitor\Utils\ClassUtils;
13
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
14
use Symfony\Component\DependencyInjection\ContainerBuilder;
15
use Symfony\Component\DependencyInjection\Definition;
16
use Symfony\Component\DependencyInjection\Reference;
17
18
class CompilerPass implements CompilerPassInterface
19
{
20
    /**
21
     * {@inheritdoc}
22
     */
23 8
    public function process(ContainerBuilder $container)
24
    {
25 8
        if (!$container->hasParameter('roc.traitor.injection_map') || count($container->getParameter('roc.traitor.injection_map')) === 0) {
26 2
            return;
27
        }
28
29 6
        if ($container->hasParameter('roc.traitor.filter.tags') || $container->hasParameter('roc.traitor.filter.namespaces')) {
30
31 4
            $definitions = array_merge(
32 4
                $container->hasParameter('roc.traitor.filter.tags') ? $this->getDefinitionsFromTags($container, $container->getParameter('roc.traitor.filter.tags')) : array(),
33 4
                $container->hasParameter('roc.traitor.filter.namespaces') ? $this->getDefinitionsFromClassNamespaces($container, $container->getParameter('roc.traitor.filter.namespaces')) : array()
34 2
            );
35
36 2
        } else {
37
38 2
            $definitions = $this->getDefinitionsFromClassNamespaces($container);
39
        }
40
41 6
        $this->processInjection($definitions, $container->getParameter('roc.traitor.injection_map'));
42 6
    }
43
44
    /**
45
     * Get definitions from container based on namespace filter
46
     *
47
     * @param ContainerBuilder $container
48
     * @param array|null $filters Namespace prefixes
49
     * @return Definition[] Definitions indexed by service ID
50
     */
51 4
    protected function getDefinitionsFromClassNamespaces(ContainerBuilder $container, array $filters = null)
52
    {
53 4
        $result = array();
54
55
        /**
56
         * @var Definition $definition
57
         */
58 4
        foreach ($container->getDefinitions() as $id => $definition) {
59
60 4
            $class = $definition->getClass();
61
62 4
            if (null !== $filters && count($filters) > 0) {
63
64 2
                $found = false;
65
66 2
                foreach ($filters as $namespace) {
67
68 2
                    if (ClassUtils::isWithinNamespace($class, $namespace)) {
69 2
                        $found = true;
70 2
                        break;
71
                    }
72 1
                }
73
74 2
                if (!$found) {
75 2
                    continue; // Go to next definition
76
                }
77 1
            }
78
79 4
            $result[$id] = $definition;
80 2
        }
81
82 4
        return $result;
83
    }
84
85
    /**
86
     * Get definitions from container based on service tag filter
87
     *
88
     * @param ContainerBuilder $container
89
     * @param array|null $tags Tag names
90
     * @return Definition[] Definitions indexed by service ID
91
     */
92 2
    protected function getDefinitionsFromTags(ContainerBuilder $container, array $tags = null)
93
    {
94 2
        $result = array();
95
96 2
        if (null !== $tags && count($tags) > 0) {
97
98 2
            foreach ($tags as $tag) {
99
100 2
                foreach (array_keys($container->findTaggedServiceIds($tag)) as $id) {
101
102 2
                    $result[$id] = $container->getDefinition($id);
103 1
                }
104 1
            }
105 1
        }
106
107 2
        return $result;
108
    }
109
110
    /**
111
     * Process injection of services via traits for given definitions.
112
     *
113
     * @param Definition[] $definitions Definitions to process.
114
     * @param array $injectionMap Injection map.
115
     */
116 6
    protected function processInjection(array $definitions, array $injectionMap)
117
    {
118
        /**
119
         * @var Definition $definition
120
         */
121 6
        foreach ($definitions as $definition) {
122
123 6
            $class = $definition->getClass();
124
125 6
            foreach ($injectionMap as $trait => $injectionDefinition) {
126
127 6
                if (class_exists($class) && ClassUtils::usesTrait($class, $trait)) {
128
129 6
                    $arguments = array();
130
131 6
                    foreach ($injectionDefinition[1] as $argument) {
132
133 6
                        if ('@' === $argument[0]) {
134 6
                            $arguments[] = new Reference(ltrim($argument, '@'));
135 3
                        } else {
136 3
                            $arguments[] = $argument;
137
                        }
138 3
                    }
139
140 6
                    $definition->addMethodCall($injectionDefinition['0'], $arguments);
141 3
                }
142 3
            }
143 3
        }
144 6
    }
145
}
146