Passed
Push — master ( a64086...4ccfae )
by Thomas
06:32
created

addListener()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 13
nc 3
nop 1
dl 0
loc 20
ccs 13
cts 13
cp 1
crap 3
rs 9.8333
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the ekino Drupal Debug project.
7
 *
8
 * (c) ekino
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Ekino\Drupal\Debug\Action\WatchModulesHooksImplementations;
15
16
use Drupal\Core\DrupalKernelInterface;
17
use Drupal\Core\Extension\ModuleHandler;
18
use Ekino\Drupal\Debug\Action\ActionWithOptionsInterface;
19
use Ekino\Drupal\Debug\Action\CompilerPassActionInterface;
20
use Ekino\Drupal\Debug\Action\EventSubscriberActionInterface;
21
use Ekino\Drupal\Debug\Action\ValidateContainerDefinitionTrait;
22
use Ekino\Drupal\Debug\Cache\Event\FileBackendEvents;
23
use Ekino\Drupal\Debug\Cache\FileBackend;
24
use Ekino\Drupal\Debug\Cache\FileCache;
25
use Ekino\Drupal\Debug\Exception\NotSupportedException;
26
use Ekino\Drupal\Debug\Kernel\Event\AfterAttachSyntheticEvent;
27
use Ekino\Drupal\Debug\Kernel\Event\DebugKernelEvents;
28
use Symfony\Component\DependencyInjection\ContainerBuilder;
29
use Symfony\Component\DependencyInjection\Definition;
30
use Symfony\Component\DependencyInjection\Reference;
31
use Symfony\Component\EventDispatcher\EventDispatcher;
32
33
class WatchModulesHooksImplementationsAction implements CompilerPassActionInterface, EventSubscriberActionInterface, ActionWithOptionsInterface
34
{
35
    use ValidateContainerDefinitionTrait;
36
37
    /**
38
     * @var string
39
     */
40
    private const RESOURCES_SERVICE_ID = 'ekino.drupal.debug.action.watch_modules_hooks_implementations.resources';
41
42
    /**
43
     * @var string
44
     */
45
    private const EVENT_DISPATCHER_SERVICE_ID = 'ekino.drupal.debug.action.watch_modules_hooks_implementations.event_dispatcher';
46
47
    /**
48
     * @var WatchModulesHooksImplementationsOptions
49
     */
50
    private $options;
51
52
    /**
53
     * {@inheritdoc}
54
     */
55 1
    public static function getSubscribedEvents(): array
56
    {
57
        return array(
58 1
            DebugKernelEvents::AFTER_ATTACH_SYNTHETIC => array(array('setResources'), array('addListener')),
59
        );
60
    }
61
62
    /**
63
     * @param WatchModulesHooksImplementationsOptions $options
64
     */
65 10
    public function __construct(WatchModulesHooksImplementationsOptions $options)
66
    {
67 10
        $this->options = $options;
68 10
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73 3
    public function process(ContainerBuilder $container): void
74
    {
75 3
        $moduleHandlerDefinition = $this->validateContainerDefinitionClassIs($container, 'module_handler', ModuleHandler::class);
76
77 1
        $resourcesDefinition = new Definition();
78 1
        $resourcesDefinition->setSynthetic(true);
79 1
        $container->setDefinition(self::RESOURCES_SERVICE_ID, $resourcesDefinition);
80
81 1
        $fileBackendDefinition = new Definition(FileBackend::class, array(
82 1
            new Definition(FileCache::class, array(
83 1
                $this->options->getCacheFilePath(),
84 1
                new Reference(self::RESOURCES_SERVICE_ID),
85
            )),
86
        ));
87
88 1
        $eventDispatcherDefinition = new Definition();
89 1
        $eventDispatcherDefinition->setSynthetic(true);
90 1
        $container->setDefinition(self::EVENT_DISPATCHER_SERVICE_ID, $eventDispatcherDefinition);
91
92 1
        $fileBackendDefinition->addMethodCall('setEventDispatcher', array(
93 1
            new Reference(self::EVENT_DISPATCHER_SERVICE_ID),
94
        ));
95
96 1
        $moduleHandlerDefinition->replaceArgument(2, $fileBackendDefinition);
97 1
    }
98
99
    /**
100
     * @param AfterAttachSyntheticEvent $event
101
     */
102
    public function setResources(AfterAttachSyntheticEvent $event): void
103
    {
104
        $event->getContainer()->set(self::RESOURCES_SERVICE_ID, $this->options->getFilteredResourcesCollection($event->getEnabledModules(), $event->getEnabledThemes()));
105
    }
106
107
    /**
108
     * @param AfterAttachSyntheticEvent $event
109
     *
110
     * @throws NotSupportedException
111
     */
112 3
    public function addListener(AfterAttachSyntheticEvent $event): void
113
    {
114 3
        $eventDispatcher = new EventDispatcher();
115 3
        $event->getContainer()->set(self::EVENT_DISPATCHER_SERVICE_ID, $eventDispatcher);
116
117 3
        $moduleHandler = $event->getContainer()->get('module_handler');
118 3
        if (!$moduleHandler instanceof ModuleHandler) {
119 1
            throw new NotSupportedException(\sprintf('The "module_handler" service class should be "%s".', ModuleHandler::class));
120
        }
121
122 2
        $kernel = $event->getContainer()->get('kernel');
123 2
        if (!$kernel instanceof DrupalKernelInterface) {
124 1
            throw new NotSupportedException(\sprintf('The "kernel" service class should implement the "%s" interface.', DrupalKernelInterface::class));
125
        }
126
127 1
        $eventDispatcher->addListener(
128 1
            FileBackendEvents::ON_CACHE_NOT_FRESH,
129 1
            new LoadNewModuleFile(
130 1
                $moduleHandler,
131
                $kernel
132
            )
133
        );
134 1
    }
135
136
    /**
137
     * {@inheritdoc}
138
     */
139 3
    public static function getOptionsClass(): string
140
    {
141 3
        return WatchModulesHooksImplementationsOptions::class;
142
    }
143
}
144