Completed
Push — master ( bdcfe3...4b3dce )
by Alessandro
07:09 queued 03:29
created

CompilerPass   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 78
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 48.89%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 15
c 2
b 0
f 0
lcom 1
cbo 3
dl 0
loc 78
ccs 22
cts 45
cp 0.4889
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
C process() 0 49 14
1
<?php
2
3
namespace Paraunit\Lifecycle;
4
5
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
6
use Symfony\Component\DependencyInjection\ContainerBuilder;
7
8
/**
9
 * Class CompilerPass
10
 * @package Paraunit\Lifecycle
11
 */
12
class CompilerPass implements CompilerPassInterface
13
{
14
    /** @var string */
15
    protected $dispatcherService;
16
17
    /** @var string */
18
    protected $listenerTag;
19
20
    /** @var string */
21
    protected $subscriberTag;
22
23
    /**
24
     * Constructor.
25
     *
26
     * @param string $dispatcherService Service name of the event dispatcher in processed container
27
     * @param string $listenerTag Tag name used for listener
28
     * @param string $subscriberTag Tag name used for subscribers
29
     */
30 7
    public function __construct($dispatcherService = 'event_dispatcher', $listenerTag = 'kernel.event_listener', $subscriberTag = 'kernel.event_subscriber')
31
    {
32 7
        $this->dispatcherService = $dispatcherService;
33 7
        $this->listenerTag = $listenerTag;
34 7
        $this->subscriberTag = $subscriberTag;
35 7
    }
36
37
    /**
38
     * @param ContainerBuilder $container
39
     */
40 7
    public function process(ContainerBuilder $container)
41
    {
42 7
        if ( ! $container->hasDefinition($this->dispatcherService) && ! $container->hasAlias($this->dispatcherService)) {
43
            return;
44
        }
45 7
        $definition = $container->findDefinition($this->dispatcherService);
46 7
        foreach ($container->findTaggedServiceIds($this->listenerTag) as $id => $events) {
47 7
            $def = $container->getDefinition($id);
48 7
            if ( ! $def->isPublic()) {
49
                throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event listeners are lazy-loaded.', $id));
50
            }
51 7
            if ($def->isAbstract()) {
52
                throw new \InvalidArgumentException(sprintf('The service "%s" must not be abstract as event listeners are lazy-loaded.', $id));
53
            }
54 7
            foreach ($events as $event) {
55 7
                $priority = isset($event['priority']) ? $event['priority'] : 0;
56 7
                if ( ! isset($event['event'])) {
57
                    throw new \InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "%s" tags.', $id, $this->listenerTag));
58
                }
59 7
                if ( ! isset($event['method'])) {
60
                    $event['method'] = 'on' . preg_replace_callback(array(
61
                            '/(?<=\b)[a-z]/i',
62
                            '/[^a-z0-9]/i',
63
                        ), function ($matches) {
64
                            return strtoupper($matches[0]);
65
                        }, $event['event']);
66
                    $event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']);
67
                }
68 7
                $definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority));
69 7
            }
70 7
        }
71 7
        foreach ($container->findTaggedServiceIds($this->subscriberTag) as $id => $attributes) {
72
            $def = $container->getDefinition($id);
73
            if ( ! $def->isPublic()) {
74
                throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event subscribers are lazy-loaded.', $id));
75
            }
76
            if ($def->isAbstract()) {
77
                throw new \InvalidArgumentException(sprintf('The service "%s" must not be abstract as event subscribers are lazy-loaded.', $id));
78
            }
79
            // We must assume that the class value has been correctly filled, even if the service is created by a factory
80
            $class = $container->getParameterBag()->resolveValue($def->getClass());
81
            $refClass = new \ReflectionClass($class);
82
            $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface';
83
            if ( ! $refClass->implementsInterface($interface)) {
84
                throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
85
            }
86
            $definition->addMethodCall('addSubscriberService', array($id, $class));
87 7
        }
88 7
    }
89
}
90