Completed
Push — master ( 139fb8...7c9eb0 )
by Thomas
10s
created

WatchHooksImplementationsAction::setResources()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
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\WatchHooksImplementations;
15
16
use Drupal\Core\Extension\ModuleHandler;
17
use Ekino\Drupal\Debug\Action\ActionWithOptionsInterface;
18
use Ekino\Drupal\Debug\Action\CompilerPassActionInterface;
19
use Ekino\Drupal\Debug\Action\EventSubscriberActionInterface;
20
use Ekino\Drupal\Debug\Cache\FileBackend;
21
use Ekino\Drupal\Debug\Cache\FileCache;
22
use Ekino\Drupal\Debug\Exception\NotSupportedException;
23
use Ekino\Drupal\Debug\Kernel\Event\AfterAttachSyntheticEvent;
24
use Ekino\Drupal\Debug\Kernel\Event\DebugKernelEvents;
25
use Symfony\Component\DependencyInjection\ContainerBuilder;
26
use Symfony\Component\DependencyInjection\Definition;
27
use Symfony\Component\DependencyInjection\Reference;
28
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
29
30
class WatchHooksImplementationsAction implements CompilerPassActionInterface, EventSubscriberActionInterface, ActionWithOptionsInterface
31
{
32
    /**
33
     * @var string
34
     */
35
    const RESOURCES_SERVICE_ID = 'ekino.drupal.debug.action.watch_hooks_implementations.resources';
36
37
    /**
38
     * @var WatchHooksImplementationsOptions
39
     */
40
    private $options;
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    public static function getSubscribedEvents(): array
46
    {
47
        return array(
48
            DebugKernelEvents::AFTER_ATTACH_SYNTHETIC => 'setResources',
49
        );
50
    }
51
52
    /**
53
     * @param WatchHooksImplementationsOptions $options
54
     */
55 2
    public function __construct(WatchHooksImplementationsOptions $options)
56
    {
57 2
        $this->options = $options;
58 2
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63
    public function process(ContainerBuilder $container): void
64
    {
65
        if (!$container->has('module_handler')) {
66
            throw new NotSupportedException('The "module_handler" service should already be set in the container.');
67
        }
68
69
        $moduleHandlerDefinition = $container->getDefinition('module_handler');
70
        if (ModuleHandler::class !== $moduleHandlerDefinition->getClass()) {
71
            throw new NotSupportedException(\sprintf('The "module_handler" service class should be "%s".', ModuleHandler::class));
72
        }
73
74
        if (!$container->has('event_dispatcher')) {
75
            throw new NotSupportedException('The "event_dispatcher" service should already be set in the container.');
76
        }
77
78
        $eventDispatcherDefinition = $container->getDefinition('event_dispatcher');
79
        $eventDispatcherClass = $eventDispatcherDefinition->getClass();
80
        if (!\is_string($eventDispatcherClass)) {
81
            throw new NotSupportedException('The "event_dispatcher" service class should be a string.');
82
        }
83
84
        if (!(new \ReflectionClass($eventDispatcherClass))->implementsInterface(EventDispatcherInterface::class)) {
85
            throw new NotSupportedException(\sprintf('The "event_dispatcher" service class should implement the "%s" interface', EventDispatcherInterface::class));
86
        }
87
88
        $resourcesDefinition = new Definition();
89
        $resourcesDefinition->setSynthetic(true);
90
        $container->setDefinition(self::RESOURCES_SERVICE_ID, $resourcesDefinition);
91
92
        $fileBackendDefinition = new Definition(FileBackend::class, array(
93
            new Definition(FileCache::class, array(
94
                $this->options->getCacheFilePath(),
95
                new Reference(self::RESOURCES_SERVICE_ID),
96
            )),
97
        ));
98
        $fileBackendDefinition->addMethodCall('setEventDispatcher', array(
99
            new Reference('event_dispatcher'),
100
        ));
101
102
        $moduleHandlerDefinition->replaceArgument(2, $fileBackendDefinition);
103
    }
104
105
    /**
106
     * @param AfterAttachSyntheticEvent $event
107
     */
108
    public function setResources(AfterAttachSyntheticEvent $event): void
109
    {
110
        $event->getContainer()->set(self::RESOURCES_SERVICE_ID, $this->options->getFilteredResourcesCollection($event->getEnabledModules(), $event->getEnabledThemes()));
111
    }
112
113
    /**
114
     * {@inheritdoc}
115
     */
116 2
    public static function getOptionsClass(): string
117
    {
118 2
        return WatchHooksImplementationsOptions::class;
119
    }
120
}
121