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\DependencyInjection; |
||
15 | |||
16 | use Doyo\Bundle\Modular\Application\ModuleInterface; |
||
17 | use Doyo\Bundle\Modular\Modules; |
||
18 | use Symfony\Component\Config\FileLocator; |
||
19 | use Symfony\Component\DependencyInjection\ContainerBuilder; |
||
20 | use Symfony\Component\DependencyInjection\Extension\Extension; |
||
21 | use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; |
||
22 | use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; |
||
23 | |||
24 | class DoyoModularExtension extends Extension implements PrependExtensionInterface |
||
25 | { |
||
26 | /** |
||
27 | * @psalm-suppress MixedArgument |
||
28 | * @psalm-suppress MixedAssignment |
||
29 | */ |
||
30 | public function prepend(ContainerBuilder $container): void |
||
31 | { |
||
32 | $configs = $container->getExtensionConfig($this->getAlias()); |
||
33 | $resolvingBag = $container->getParameterBag(); |
||
34 | $configs = $resolvingBag->resolveValue($configs); |
||
35 | /** @var array<array-key,array<array-key,string|bool|scalar>> $configs */ |
||
36 | $configs = $this->processConfiguration(new Configuration(), $configs); |
||
37 | $modules = new Modules(); |
||
38 | $modules->buildModules($container); |
||
39 | $container->set('doyo.modules', $modules); |
||
40 | foreach ($modules->getModules() as $module) { |
||
41 | $this->configureModule($configs, $container, $module); |
||
42 | } |
||
43 | } |
||
44 | |||
45 | /** |
||
46 | * @psalm-suppress MixedArgumentTypeCoercion |
||
47 | */ |
||
48 | public function load(array $configs, ContainerBuilder $container): void |
||
49 | { |
||
50 | $configuration = new Configuration(); |
||
51 | $config = $this->processConfiguration($configuration, $configs); |
||
52 | |||
53 | $this->configureParams($container, $config); |
||
54 | $locator = new FileLocator(__DIR__.'/../Resources/services'); |
||
55 | $loader = new XmlFileLoader($container, $locator); |
||
56 | $loader->load('services.xml'); |
||
57 | } |
||
58 | |||
59 | /** |
||
60 | * @psalm-suppress MixedArgument |
||
61 | * @psalm-suppress MixedArrayAccess |
||
62 | * @psalm-suppress PossiblyInvalidArrayOffset |
||
63 | * @psalm-suppress PossiblyInvalidArgument |
||
64 | * @psalm-param array<array-key,string|array<array-key,string>> $config |
||
65 | */ |
||
66 | private function configureParams(ContainerBuilder $container, array $config): void |
||
67 | { |
||
68 | $container->setParameter('doyo.modular.use_annotation', $config['use_annotation']); |
||
69 | $container->setParameter('doyo.modular.module_dir', $config['module_root_dir']); |
||
70 | $container->setParameter('doyo.modular.paths.api_platform', $config['config_paths']['api_platform']); |
||
71 | $container->setParameter('doyo.modular.paths.validation', $config['config_paths']['validation']); |
||
72 | $container->setParameter('doyo.modular.paths.serialization', $config['config_paths']['serialization']); |
||
73 | |||
74 | $this->configureDoctrineParams($container, $config['doctrine']); |
||
75 | } |
||
76 | |||
77 | /** |
||
78 | * @param array<array-key,string> $config |
||
0 ignored issues
–
show
Documentation
Bug
introduced
by
![]() |
|||
79 | */ |
||
80 | private function configureDoctrineParams(ContainerBuilder $container, array $config): void |
||
81 | { |
||
82 | $ns = 'doyo.modular.doctrine'; |
||
83 | |||
84 | foreach ($config as $key => $val) { |
||
85 | $container->setParameter($ns.'.'.$key, $val); |
||
86 | } |
||
87 | } |
||
88 | |||
89 | /** |
||
90 | * @param array<array-key,array<array-key,string|bool|scalar>> $configs |
||
0 ignored issues
–
show
|
|||
91 | */ |
||
92 | private function configureModule(array $configs, ContainerBuilder $container, ModuleInterface $module): void |
||
93 | { |
||
94 | $this->prependSerialization($configs, $container, $module); |
||
95 | // $this->configureValidation($container, $module); |
||
96 | |||
97 | if ($container->hasExtension('doctrine')) { |
||
98 | $this->prependOrm($configs, $container, $module); |
||
99 | } |
||
100 | |||
101 | if ($container->hasExtension('doctrine_mongodb')) { |
||
102 | $this->prependMongoDB($configs, $container, $module); |
||
103 | } |
||
104 | |||
105 | if ($container->hasExtension('api_platform')) { |
||
106 | $this->prependApiPlatform($configs, $container, $module); |
||
107 | } |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * @param array<array-key,array<array-key,string|bool|scalar>> $configs |
||
0 ignored issues
–
show
|
|||
112 | */ |
||
113 | private function prependSerialization(array $configs, ContainerBuilder $container, ModuleInterface $module): void |
||
114 | { |
||
115 | //$configPath = (string) $container->getParameter('doyo.modular.paths.serialization'); |
||
116 | $configPath = $configs['config_paths']['serialization']; |
||
117 | $path = $module->getBasePath().'/'.$configPath; |
||
118 | if (is_dir($path)) { |
||
119 | $container->prependExtensionConfig('framework', [ |
||
120 | 'serializer' => [ |
||
121 | 'mapping' => [ |
||
122 | 'paths' => [ |
||
123 | $path, |
||
124 | ], |
||
125 | ], |
||
126 | ], |
||
127 | ]); |
||
128 | } |
||
129 | } |
||
130 | |||
131 | /** |
||
132 | * @param array<array-key,array<array-key,string|bool|scalar>> $configs |
||
0 ignored issues
–
show
|
|||
133 | * @psalm-suppress PossiblyInvalidCast |
||
134 | * @psalm-suppress MixedAssignment |
||
135 | * @psalm-suppress MixedArrayAccess |
||
136 | */ |
||
137 | private function prependOrm(array $configs, ContainerBuilder $container, ModuleInterface $module): void |
||
138 | { |
||
139 | $basePath = $module->getBasePath(); |
||
140 | $config = $configs['doctrine']; |
||
141 | $useAnnotation = $configs['use_annotation']; |
||
142 | $nsSuffix = $config['entity_dir']; |
||
143 | $entityDir = $basePath.\DIRECTORY_SEPARATOR.$nsSuffix; |
||
144 | $mappingDir = $basePath.\DIRECTORY_SEPARATOR.$config['mapping_dir']; |
||
145 | $mappingNS = $module->getNamespace().'\\'.$nsSuffix; |
||
146 | |||
147 | if ( ! is_dir($entityDir)) { |
||
148 | return; |
||
149 | } |
||
150 | |||
151 | $extensionConfig = [ |
||
152 | 'orm' => [ |
||
153 | 'mappings' => [ |
||
154 | $module->getName() => [ |
||
155 | 'is_bundle' => false, |
||
156 | 'type' => $useAnnotation ? 'annotation' : 'xml', |
||
157 | 'dir' => $useAnnotation ? $entityDir : $mappingDir, |
||
158 | 'prefix' => $mappingNS, |
||
159 | 'alias' => $module->getName(), |
||
160 | ], |
||
161 | ], |
||
162 | ], |
||
163 | ]; |
||
164 | |||
165 | if (\count($resolved = $module->getResolveTargetEntities()) > 0) { |
||
166 | $extensionConfig['orm']['resolve_target_entities'] = $resolved; |
||
167 | } |
||
168 | |||
169 | $container->prependExtensionConfig('doctrine', $extensionConfig); |
||
170 | } |
||
171 | |||
172 | /** |
||
173 | * @param array<array-key,array<array-key,string|bool|scalar>> $configs |
||
0 ignored issues
–
show
|
|||
174 | * @psalm-suppress PossiblyInvalidCast |
||
175 | * @psalm-suppress MixedAssignment |
||
176 | * @psalm-suppress MixedArrayAccess |
||
177 | */ |
||
178 | private function prependMongoDB(array $configs, ContainerBuilder $container, ModuleInterface $module): void |
||
179 | { |
||
180 | $basePath = $module->getBasePath(); |
||
181 | $config = $configs['doctrine']; |
||
182 | $useAnnotation = $configs['use_annotation']; |
||
183 | $nsSuffix = $config['document_dir']; |
||
184 | $documentDir = $basePath.\DIRECTORY_SEPARATOR.$nsSuffix; |
||
185 | $mappingDir = $basePath.\DIRECTORY_SEPARATOR.$config['mapping_dir']; |
||
186 | $mappingNS = $module->getNamespace().'\\'.$nsSuffix; |
||
187 | |||
188 | if ( ! is_dir($documentDir)) { |
||
189 | return; |
||
190 | } |
||
191 | $extensionConfig = [ |
||
192 | 'document_managers' => [ |
||
193 | 'default' => [ |
||
194 | 'mappings' => [ |
||
195 | $module->getName() => [ |
||
196 | 'is_bundle' => false, |
||
197 | 'type' => $useAnnotation ? 'annotation' : 'xml', |
||
198 | 'dir' => $useAnnotation ? $documentDir : $mappingDir, |
||
199 | 'prefix' => $mappingNS, |
||
200 | 'alias' => $module->getName(), |
||
201 | ], |
||
202 | ], |
||
203 | ], |
||
204 | ], |
||
205 | ]; |
||
206 | |||
207 | if (\count($resolved = $module->getResolveTargetEntities()) > 0) { |
||
208 | $extensionConfig['resolve_target_documents'] = $resolved; |
||
209 | } |
||
210 | $container->prependExtensionConfig('doctrine_mongodb', $extensionConfig); |
||
211 | } |
||
212 | |||
213 | /** |
||
214 | * @param array<array-key,array<array-key,string|bool|scalar>> $configs |
||
0 ignored issues
–
show
|
|||
215 | */ |
||
216 | private function prependApiPlatform(array $configs, ContainerBuilder $container, ModuleInterface $module): void |
||
217 | { |
||
218 | $useAnnotation = $configs['use_annotation']; |
||
219 | $basePath = $module->getBasePath(); |
||
220 | $apiConfig = $basePath.\DIRECTORY_SEPARATOR.$configs['config_paths']['api_platform']; |
||
221 | $doctrine = $configs['doctrine']; |
||
222 | $modelSuffix = $doctrine['use_orm'] ? $doctrine['entity_dir'] : $doctrine['document_dir']; |
||
223 | $modelDir = $basePath.\DIRECTORY_SEPARATOR.$modelSuffix; |
||
224 | $dir = $useAnnotation ? $modelDir : $apiConfig; |
||
225 | |||
226 | if (is_dir($dir)) { |
||
227 | $container->prependExtensionConfig('api_platform', [ |
||
228 | 'mapping' => [ |
||
229 | 'paths' => [$dir], |
||
230 | ], |
||
231 | ]); |
||
232 | } |
||
233 | } |
||
234 | } |
||
235 |