ServiceConfiguratorPass::process()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 28
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 22
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 28
rs 9.568
1
<?php
2
3
/*
4
 * This file is part of the ModularBundle project.
5
 *
6
 * (c) Anthonius Munthi <https://itstoni.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Doyo\Bundle\Modular\Compiler;
15
16
use Doyo\Bundle\Modular\Application\ModuleInterface;
17
use Doyo\Bundle\Modular\Modules;
18
use ReflectionClass;
19
use ReflectionException;
20
use Symfony\Component\Config\Builder\ConfigBuilderGenerator;
21
use Symfony\Component\Config\FileLocator;
22
use Symfony\Component\Config\Loader\DelegatingLoader;
23
use Symfony\Component\Config\Loader\LoaderInterface;
24
use Symfony\Component\Config\Loader\LoaderResolver;
25
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
26
use Symfony\Component\DependencyInjection\ContainerBuilder;
27
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
28
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
29
use Symfony\Component\DependencyInjection\Loader\DirectoryLoader;
30
use Symfony\Component\DependencyInjection\Loader\GlobFileLoader;
31
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
32
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
33
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
34
35
class ServiceConfiguratorPass implements CompilerPassInterface
36
{
37
    /**
38
     * @psalm-suppress PossiblyInvalidCast
39
     *
40
     * @throws \Exception
41
     */
42
    public function process(ContainerBuilder $container): void
43
    {
44
        $env              = (string) $container->getParameter('kernel.environment');
45
        $projectDir       = (string) $container->getParameter('kernel.project_dir');
46
        $locator          = new FileLocator($projectDir);
47
        $cacheDir         = (string) $container->getParameter('kernel.cache_dir');
48
        $builderGenerator =new ConfigBuilderGenerator($cacheDir);
49
        $resolver         = new LoaderResolver([
50
            new XmlFileLoader($container, $locator, $env),
51
            new YamlFileLoader($container, $locator, $env),
52
            new PhpFileLoader(
53
                $container,
54
                $locator,
55
                $env,
56
                $builderGenerator
57
            ),
58
            new GlobFileLoader($container, $locator, $env),
59
            new DirectoryLoader($container, $locator, $env),
60
            new ClosureLoader($container, $env),
61
        ]);
62
        $loader = new DelegatingLoader($resolver);
63
64
        $loader->load(function (ContainerBuilder $container) use ($loader) {
65
            /** @var Modules $modules */
66
            $modules = $container->get('doyo.modules');
67
            $configurator = $this->createConfigurator($container, $loader);
68
            foreach ($modules->getModules() as $module) {
69
                $this->configureService($container, $configurator, $module);
70
            }
71
        });
72
    }
73
74
    /**
75
     * @psalm-suppress PossiblyInvalidCast
76
     * @psalm-suppress MissingClosureReturnType
77
     * @psalm-suppress PossiblyNullOperand
78
     */
79
    private function configureService(ContainerBuilder $container, ContainerConfigurator $configurator, ModuleInterface $module): void
80
    {
81
        $env          = $container->getParameter('kernel.environment');
82
        $paths        = ['config', 'services'];
83
        foreach ($paths as $path) {
84
            if (is_dir($dir=$module->getBasePath().'/Resources/'.$path)) {
85
                $configurator->import($dir.'/*.yaml');
86
                $configurator->import($dir.'/*.xml');
87
                $configurator->import($dir.'/{'.$env.'}/*.yaml');
88
                $configurator->import($dir.'/{'.$env.'}/*.xml');
89
            }
90
        }
91
    }
92
93
    /**
94
     * @throws ReflectionException
95
     * @psalm-suppress MixedArgument
96
     * @psalm-suppress MixedAssignment
97
     * @psalm-suppress PossiblyInvalidCast
98
     * @psalm-suppress UndefinedThisPropertyFetch
99
     * @psalm-suppress PossiblyInvalidFunctionCall
100
     * @psalm-suppress MissingClosureReturnType
101
     */
102
    private function createConfigurator(ContainerBuilder $container, LoaderInterface $loader): ContainerConfigurator
103
    {
104
        $env        = (string) $container->getParameter('kernel.environment');
105
        $class      = $container->getDefinition('kernel')->getClass();
106
        /** @var ReflectionClass $r */
107
        $r      = $container->getReflectionClass($class, true);
108
        $file   = $r->getFileName();
109
110
        /** @var PhpFileLoader $kernelLoader */
111
        $kernelLoader = $loader->getResolver()->resolve($file);
112
        $kernelLoader->setCurrentDir(\dirname($file));
113
        $instanceof   = &\Closure::bind(function &() { return $this->instanceof; }, $kernelLoader, $kernelLoader)();
0 ignored issues
show
Bug Best Practice introduced by
The property instanceof does not exist on Doyo\Bundle\Modular\Comp...ServiceConfiguratorPass. Did you maybe forget to declare it?
Loading history...
114
115
        return new ContainerConfigurator($container, $kernelLoader, $instanceof, $file, $file, $env);
116
    }
117
}
118