Completed
Pull Request — master (#951)
by David
01:53
created

EntityListenerPass::process()   D

Complexity

Conditions 18
Paths 140

Size

Total Lines 68

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 68
rs 4.5333
c 0
b 0
f 0
cc 18
nc 140
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;
4
5
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
6
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
7
use Symfony\Component\DependencyInjection\ContainerBuilder;
8
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
9
use Symfony\Component\DependencyInjection\Reference;
10
11
/**
12
 * Class for Symfony bundles to register entity listeners
13
 */
14
class EntityListenerPass implements CompilerPassInterface
15
{
16
    /**
17
     * {@inheritDoc}
18
     */
19
    public function process(ContainerBuilder $container)
20
    {
21
        $resolvers = $container->findTaggedServiceIds('doctrine.orm.entity_listener');
22
23
        $lazyServiceReferencesByResolver = array();
24
25
        foreach ($resolvers as $id => $tagAttributes) {
26
27
            foreach ($tagAttributes as $attributes) {
28
                $name          = isset($attributes['entity_manager']) ? $attributes['entity_manager'] : $container->getParameter('doctrine.default_entity_manager');
29
                $entityManager = sprintf('doctrine.orm.%s_entity_manager', $name);
30
31
                if (! $container->hasDefinition($entityManager)) {
32
                    continue;
33
                }
34
35
                $resolverId = sprintf('doctrine.orm.%s_entity_listener_resolver', $name);
36
37
                if (! $container->has($resolverId)) {
38
                    continue;
39
                }
40
41
                $resolver = $container->findDefinition($resolverId);
42
                $resolver->setPublic(true);
43
44
                if (isset($attributes['entity']) && isset($attributes['event'])) {
45
                    $this->attachToListener($container, $name, $id, $attributes);
46
                }
47
48
                $interface = 'Doctrine\\Bundle\\DoctrineBundle\\Mapping\\EntityListenerServiceResolver';
49
                $class     = $resolver->getClass();
50
51
                if (substr($class, 0, 1) === '%') {
52
                    // resolve container parameter first
53
                    $class = $container->getParameterBag()->resolveValue($resolver->getClass());
54
                }
55
                $resolverSupportsLazyListeners = is_a($class, $interface, true);
56
57
                $lazyByAttribute = isset($attributes['lazy']) && $attributes['lazy'];
58
                if ($lazyByAttribute && !$resolverSupportsLazyListeners) {
59
                    throw new InvalidArgumentException(
60
                        sprintf('Lazy-loaded entity listeners can only be resolved by a resolver implementing %s.', $interface)
61
                    );
62
                }
63
64
                if (!isset($attributes['lazy']) && $resolverSupportsLazyListeners || $lazyByAttribute) {
65
                    $listener = $container->findDefinition($id);
66
67
                    if ($listener->isAbstract()) {
68
                        throw new InvalidArgumentException(sprintf('The service "%s" must not be abstract as this entity listener is lazy-loaded.', $id));
69
                    }
70
71
                    $resolver->addMethodCall('registerService', [$listener->getClass(), $id]);
72
73
                    if(!isset($lazyServiceReferencesByResolver[$resolverId])) {
74
                        $lazyServiceReferencesByResolver[$resolverId] = array();
75
                    }
76
                    $lazyServiceReferencesByResolver[$resolverId][$id] = new Reference($id);
77
                } else {
78
                    $resolver->addMethodCall('register', [new Reference($id)]);
79
                }
80
            }
81
        }
82
83
        foreach ($lazyServiceReferencesByResolver as $resolverId => $listenerReferences) {
84
            $container->findDefinition($resolverId)->replaceArgument(0, ServiceLocatorTagPass::register($container, $listenerReferences));
85
        }
86
    }
87
88
    private function attachToListener(ContainerBuilder $container, $name, $id, array $attributes)
89
    {
90
        $listenerId = sprintf('doctrine.orm.%s_listeners.attach_entity_listeners', $name);
91
92
        if (! $container->has($listenerId)) {
93
            return;
94
        }
95
96
        $serviceDef = $container->getDefinition($id);
97
98
        $args = [
99
            $attributes['entity'],
100
            $serviceDef->getClass(),
101
            $attributes['event'],
102
        ];
103
104
        if (isset($attributes['method'])) {
105
            $args[] = $attributes['method'];
106
        }
107
108
        $container->findDefinition($listenerId)->addMethodCall('addEntityListener', $args);
109
    }
110
}
111