Completed
Pull Request — master (#443)
by Peter
05:01
created

EntityListenerPass   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 89
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 3

Importance

Changes 0
Metric Value
wmc 18
lcom 0
cbo 3
dl 0
loc 89
rs 10
c 0
b 0
f 0

2 Methods

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