NetteAdapterForSymfonyBundlesExtension   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 134
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 13

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 13
dl 0
loc 134
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A loadConfiguration() 0 8 1
A beforeCompile() 0 15 1
A afterCompile() 0 9 1
A initialize() 0 13 2
A loadBundlesToSymfonyContainerBuilder() 0 11 3
A determineParameters() 0 4 1
A addSymfonyContainerAdapter() 0 7 1
A getSymfonyToNetteServiceAliases() 0 9 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Symplify.
7
 * Copyright (c) 2016 Tomas Votruba (http://tomasvotruba.cz).
8
 */
9
10
namespace Symplify\NetteAdapterForSymfonyBundles\DI;
11
12
use Nette\DI\CompilerExtension;
13
use Nette\PhpGenerator\ClassType;
14
use Symfony\Component\DependencyInjection\ContainerBuilder as SymfonyContainerBuilder;
15
use Symfony\Component\HttpKernel\Bundle\Bundle;
16
use Symplify\NetteAdapterForSymfonyBundles\SymfonyContainerAdapter;
17
use Symplify\NetteAdapterForSymfonyBundles\Transformer\ContainerBuilderTransformer;
18
use Symplify\NetteAdapterForSymfonyBundles\Transformer\DI\TransformerFactory;
19
use Symplify\NetteAdapterForSymfonyBundles\Transformer\ParametersTransformer;
20
21
final class NetteAdapterForSymfonyBundlesExtension extends CompilerExtension
22
{
23
    /**
24
     * @var string
25
     */
26
    const SYMFONY_CONTAINER_SERVICE_NAME = 'service_container';
27
28
    /**
29
     * @var array[]
30
     */
31
    private $defaults = [
32
        'bundles' => [],
33
        'parameters' => [],
34
    ];
35
36
    /**
37
     * @var Bundle[]
38
     */
39
    private $bundles = [];
40
41
    /**
42
     * @var SymfonyContainerBuilder
43
     */
44
    private $symfonyContainerBuilder;
45
46
    /**
47
     * @var ContainerBuilderTransformer
48
     */
49
    private $containerBuilderTransformer;
50
51
    /**
52
     * @var ParametersTransformer
53
     */
54
    private $parametersTransformer;
55
56
    /**
57
     * Mirror to compiler passes.
58
     */
59
    public function loadConfiguration()
60
    {
61
        $config = $this->getConfig($this->defaults);
62
        $this->initialize($config['bundles']);
63
64
        $this->parametersTransformer->transformFromNetteToSymfony($this->compiler, $config);
0 ignored issues
show
Bug introduced by
It seems like $config defined by $this->getConfig($this->defaults) on line 61 can also be of type string; however, Symplify\NetteAdapterFor...ormFromNetteToSymfony() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
65
        $this->loadBundlesToSymfonyContainerBuilder($config['parameters']);
66
    }
67
68
    /**
69
     * Mirror to $bundle->compile().
70
     */
71
    public function beforeCompile()
72
    {
73
        $this->containerBuilderTransformer->transformFromNetteToSymfony(
74
            $this->getContainerBuilder(),
75
            $this->symfonyContainerBuilder
76
        );
77
78
        $this->addSymfonyContainerAdapter();
79
        $this->symfonyContainerBuilder->compile();
80
81
        $this->containerBuilderTransformer->transformFromSymfonyToNette(
82
            $this->symfonyContainerBuilder,
83
            $this->getContainerBuilder()
84
        );
85
    }
86
87
    /**
88
     * Mirror to $bundle->boot().
89
     */
90
    public function afterCompile(ClassType $class)
91
    {
92
        $initializerMethod = $class->getMethod('initialize');
93
        $initializerMethod->addBody('
94
			foreach (? as $bundle) {
95
				$bundle->setContainer($this->getService(?));
96
				$bundle->boot();
97
			}', [$this->bundles, self::SYMFONY_CONTAINER_SERVICE_NAME]);
98
    }
99
100
    /**
101
     * @param string[] $bundles
102
     */
103
    private function initialize(array $bundles)
104
    {
105
        $tempDir = $this->compiler->getConfig()['parameters']['tempDir'];
106
        $transformer = (new TransformerFactory($this->getContainerBuilder(), $tempDir))->create();
107
108
        $this->symfonyContainerBuilder = $transformer->getByType(SymfonyContainerBuilder::class);
109
        $this->containerBuilderTransformer = $transformer->getByType(ContainerBuilderTransformer::class);
110
        $this->parametersTransformer = $transformer->getByType(ParametersTransformer::class);
111
112
        foreach ($bundles as $name => $class) {
113
            $this->bundles[$name] = new $class();
114
        }
115
    }
116
117
    private function loadBundlesToSymfonyContainerBuilder(array $parameters)
118
    {
119
        foreach ($this->bundles as $name => $bundle) {
120
            if ($extension = $bundle->getContainerExtension()) {
121
                $this->symfonyContainerBuilder->registerExtension($extension);
122
                $extensionParameters = $this->determineParameters($parameters, (string) $name);
123
                $this->symfonyContainerBuilder->loadFromExtension($extension->getAlias(), $extensionParameters);
124
            }
125
            $bundle->build($this->symfonyContainerBuilder);
126
        }
127
    }
128
129
    private function determineParameters(array $parameters, string $name) : array
130
    {
131
        return $parameters[$name] ?? [];
132
    }
133
134
    private function addSymfonyContainerAdapter()
135
    {
136
        $this->getContainerBuilder()
137
            ->addDefinition(self::SYMFONY_CONTAINER_SERVICE_NAME)
138
            ->setClass(SymfonyContainerAdapter::class)
139
            ->setArguments([$this->getSymfonyToNetteServiceAliases()]);
140
    }
141
142
    /**
143
     * @return string[] {[ Symfony name => Nette name ]}
144
     */
145
    private function getSymfonyToNetteServiceAliases() : array
146
    {
147
        $names = [];
148
        foreach ($this->getContainerBuilder()->getDefinitions() as $name => $definition) {
149
            $names[strtolower((string) $name)] = $name;
150
        }
151
152
        return $names;
153
    }
154
}
155