LamodaCleanerExtension::process()   A
last analyzed

Complexity

Conditions 6
Paths 6

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 6.0073

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 16
c 1
b 0
f 0
dl 0
loc 27
ccs 16
cts 17
cp 0.9412
rs 9.1111
cc 6
nc 6
nop 1
crap 6.0073
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Lamoda\CleanerBundle\DependencyInjection;
6
7
use Lamoda\Cleaner\CleanerCollection;
8
use Lamoda\Cleaner\DB\Config\DBCleanerConfigFactory;
9
use Lamoda\Cleaner\DB\DoctrineDBALCleaner;
10
use Symfony\Component\Config\FileLocator;
11
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
12
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
13
use Symfony\Component\DependencyInjection\ContainerBuilder;
14
use Symfony\Component\DependencyInjection\Definition;
15
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
16
use Symfony\Component\DependencyInjection\Reference;
17
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;
18
19
class LamodaCleanerExtension extends ConfigurableExtension implements CompilerPassInterface
20
{
21
    private $supportedStorages = [
22
        'db' => [
23
            'configFactory' => DBCleanerConfigFactory::class,
24
        ],
25
    ];
26
27 2
    protected function loadInternal(array $mergedConfig, ContainerBuilder $container)
28
    {
29 2
        $locator = new FileLocator(__DIR__ . '/../Resources/config');
30 2
        $loader = new YamlFileLoader($container, $locator);
31 2
        $loader->load('services.yml');
32
33 2
        $this->registerCleaners($mergedConfig, $container);
34 2
    }
35
36 2
    private function registerCleaners(array $config, ContainerBuilder $container): void
37
    {
38 2
        foreach ($config as $storageType => $cleanerList) {
39 2
            $storageCollectionId = $this->getStorageCleanerServiceId($storageType);
40 2
            $collectionDefinition = (new Definition(CleanerCollection::class))
41 2
                ->setPublic(false);
42 2
            $container->setDefinition($storageCollectionId, $collectionDefinition);
43
44 2
            foreach ($cleanerList as $name => $cleanerConfig) {
45 1
                $cleanerServiceId = $this->getCleanerServiceId($storageType, $name);
46 1
                $configName = $cleanerServiceId . '.config';
47
48 1
                $configFactoryClass = $this->supportedStorages[$storageType]['configFactory'];
49 1
                $configDefinition = (new Definition($configFactoryClass, [$cleanerConfig]))
50 1
                    ->setFactory([$configFactoryClass, 'create'])
51 1
                    ->setPublic(false);
52 1
                $container->setDefinition($configName, $configDefinition);
53
54 1
                $class = $cleanerConfig['class'];
55 1
                $definition = (new Definition($class))
56 1
                    ->setPublic(false)
57 1
                    ->setAutowired(true)
58 1
                    ->setArgument('$config', new Reference($configName))
59 1
                    ->addTag($storageCollectionId, ['alias' => $name]);
60
61 1
                if (is_a($class, DoctrineDBALCleaner::class, true)) {
62 1
                    $definition->setArgument('$connection', new Reference($cleanerConfig['dbal_connection']));
63
                }
64
65 2
                $container->setDefinition($cleanerServiceId, $definition);
66
            }
67
        }
68 2
    }
69
70 2
    public function process(ContainerBuilder $container)
71
    {
72 2
        $locateableServices = [];
73
74 2
        foreach ($this->supportedStorages as $storageType => $storageOptions) {
75 2
            $storageCollectionId = $this->getStorageCleanerServiceId($storageType);
76 2
            if (!$container->has($storageCollectionId)) {
77
                continue;
78
            }
79
80 2
            $locateableServices[$storageCollectionId] = new Reference($storageCollectionId);
81 2
            $collectionDefinition = $container->getDefinition($storageCollectionId);
82
83 2
            foreach ($container->findTaggedServiceIds($storageCollectionId) as $id => $tags) {
84 2
                $collectionDefinition->addMethodCall('addCleaner', [new Reference($id)]);
85 2
                foreach ($tags as $tag) {
86 2
                    $cleanerServiceId = $this->getCleanerServiceId($storageType, $tag['alias'] ?? '');
87 2
                    if (!$container->has($cleanerServiceId)) {
88 1
                        $container->setAlias($cleanerServiceId, $id);
89
                    }
90 2
                    $locateableServices[$cleanerServiceId] = new Reference($cleanerServiceId);
91
                }
92
            }
93
        }
94
95 2
        $locator = ServiceLocatorTagPass::register($container, $locateableServices);
96 2
        $container->setAlias('lamoda_cleaner.cleaner_locator', (string) $locator);
97 2
    }
98
99 2
    private function getStorageCleanerServiceId(string $storageType): string
100
    {
101 2
        return sprintf('lamoda_cleaner.%s', $storageType);
102
    }
103
104 2
    private function getCleanerServiceId(string $storageType, string $name): string
105
    {
106 2
        return sprintf('lamoda_cleaner.%s.%s', $storageType, $name);
107
    }
108
}
109