Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
86.11% covered (warning)
86.11%
62 / 72
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApieExtension
86.11% covered (warning)
86.11%
62 / 72
0.00% covered (danger)
0.00%
0 / 1
16.69
0.00% covered (danger)
0.00%
0 / 1
 load
86.11% covered (warning)
86.11%
62 / 72
0.00% covered (danger)
0.00%
0 / 1
16.69
1<?php
2namespace Apie\ApieBundle\DependencyInjection;
3
4use Apie\ApieBundle\Interfaces\ApieContextService;
5use Apie\CmsApiDropdownOption\DropdownOptionProvider\DropdownOptionProviderInterface;
6use Apie\Common\DependencyInjection\ApieConfigFileLocator;
7use Apie\Common\Interfaces\RouteDefinitionProviderInterface;
8use Apie\Core\ContextBuilders\ContextBuilderInterface;
9use Apie\Core\Datalayers\ApieDatalayer;
10use Apie\Core\FileStorage\InlineStorage;
11use Apie\DoctrineEntityDatalayer\Commands\ApieUpdateIdfCommand;
12use Apie\DoctrineEntityDatalayer\EntityReindexer;
13use Apie\DoctrineEntityDatalayer\IndexStrategy\BackgroundIndexStrategy;
14use Apie\DoctrineEntityDatalayer\IndexStrategy\DirectIndexStrategy;
15use Apie\DoctrineEntityDatalayer\IndexStrategy\IndexAfterResponseIsSentStrategy;
16use Apie\DoctrineEntityDatalayer\IndexStrategy\IndexStrategyInterface;
17use Apie\DoctrineEntityDatalayer\OrmBuilder;
18use Apie\Faker\Interfaces\ApieClassFaker;
19use Apie\HtmlBuilders\Interfaces\FormComponentProviderInterface;
20use Symfony\Component\DependencyInjection\ContainerBuilder;
21use Symfony\Component\DependencyInjection\Definition;
22use Symfony\Component\DependencyInjection\Extension\Extension;
23use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
24use Symfony\Component\DependencyInjection\Reference;
25
26/**
27 * Loads all services into symfony. Which services depend on the apie configuration set up.
28 */
29final class ApieExtension extends Extension
30{
31    /**
32     * @var array<string, array<int, string>>
33     */
34    private array $dependencies = [
35        'enable_basic_auth' => [
36            'add_basic_auth.yaml',
37        ],
38        'enable_ai_instructor' => [
39            'ai_instructor.yaml'
40        ],
41        'enable_exchangerate' => [
42            'exchangerate.yaml',
43        ],
44        'enable_common_plugin' => [
45            'apie_common_plugin.yaml',
46        ],
47        'enable_cms' => [
48            'common.yaml',
49            'cms.yaml',
50            'html_builders.yaml',
51            'serializer.yaml',
52            'sf_cms.yaml',
53        ],
54        'enable_cms_dropdown' => [
55             'common.yaml',
56             'cms_dropdown.yaml',
57        ],
58        'enable_core' => [
59            'core.yaml',
60            'sf_core.yaml',
61        ],
62        'enable_doctrine_entity_converter' => [
63            'core.yaml',
64            'doctrine_entity_converter.yaml',
65        ],
66        'enable_doctrine_entity_datalayer' => [
67            'core.yaml',
68            'doctrine_entity_converter.yaml',
69            'doctrine_entity_datalayer.yaml',
70        ],
71        'enable_doctrine_bundle_connection' => [
72            'core.yaml',
73            'doctrine_entity_converter.yaml',
74            'doctrine_entity_datalayer.yaml',
75            'sf_doctrine.yaml',
76        ],
77        'enable_export' => [
78            'html_builders.yaml',
79            'serializer.yaml',
80            'export.yaml',
81        ],
82        'enable_ftp' => [
83            'apie_file_system.yaml',
84            'ftp.yaml',
85        ],
86        'enable_graphql' => [
87            'common.yaml',
88            'graphql.yaml',
89            'serializer.yaml',
90        ],
91        'enable_console' => [
92            'common.yaml',
93            'console.yaml',
94            'serializer.yaml',
95        ],
96        'enable_maker' => [
97            'maker.yaml',
98            "sf_maker.yaml",
99        ],
100        'enable_mcp_server' => [
101            'common.yaml',
102            'mcp_server.yaml',
103            'schema_generator.yaml',
104            'serializer.yaml',
105        ],
106        'enable_messenger' => [
107            'sf_messenger.yaml',
108        ],
109        'enable_profiler' => [
110            'sf_profiler.yaml',
111        ],
112        'enable_security' => [
113            'common.yaml',
114            'serializer.yaml',
115            'security.yaml',
116        ],
117        'enable_rest_api' => [
118            'common.yaml',
119            'rest_api.yaml',
120            'schema_generator.yaml',
121            'serializer.yaml',
122        ],
123        'enable_faker' => [
124            'faker.yaml',
125        ],
126        'enable_twig_template_layout_renderer' => [
127            'twig_template_layout_renderer.yaml',
128        ],
129        'enable_typescript_client_builder' => [
130            'typescript_client_builder.yaml',
131        ],
132        'enable_webdav' => [
133            'apie_file_system.yaml',
134            'webdav.yaml',
135        ],
136    ];
137
138    /**
139     * @param array<string, mixed> $configs
140     */
141    public function load(array $configs, ContainerBuilder $container): void
142    {
143        $loader = new YamlFileLoader($container, new ApieConfigFileLocator(__DIR__.'/../../resources/config'));
144        $loader->load('services.yaml');
145        $loader->load('psr7.yaml');
146        $configuration = $this->getConfiguration($configs, $container);
147        $config = $this->processConfiguration($configuration, $configs);
148        $container->setParameter('apie.encryption_key', $config['encryption_key'] ?? null);
149        $container->setParameter('apie.enable_cms_dropdown', $config['enable_cms_dropdown']);
150        $container->setParameter('apie.bounded_contexts', $config['bounded_contexts']);
151        $container->setParameter('apie.scan_bounded_contexts', $config['scan_bounded_contexts'] ?? []);
152        $container->setParameter('apie.storage', $config['storage'] ? : [['class' => InlineStorage::class]]);
153        $container->setParameter('apie.datalayers', $config['datalayers'] ?? []);
154        $container->setParameter('apie.ai.base_url', $config['ai']['base_url'] ?? 'http://ollama:11434');
155        $container->setParameter('apie.ai.api_key', $config['ai']['api_key'] ?? 'No key');
156        $container->setParameter('apie.cms.asset_folders', $config['cms']['asset_folders'] ?? []);
157        $container->setParameter('apie.cms.dashboard_template', $config['cms']['dashboard_template'] ?? '@Apie/dashboard.html.twig');
158        $container->setParameter('apie.cms.error_template', $config['cms']['error_template'] ?? '@Apie/error.html.twig');
159        $container->setParameter('apie.cms.base_url', rtrim($config['cms']['base_url'] ?? '/cms', '/'));
160        $container->setParameter('apie.doctrine.build_once', $config['doctrine']['build_once'] ?? false);
161        $container->setParameter('apie.doctrine.connection_params', $config['doctrine']['connection_params'] ?? []);
162        $container->setParameter('apie.doctrine.run_migrations', $config['doctrine']['run_migrations'] ?? false);
163        $container->setParameter('apie.rest_api.base_url', rtrim($config['rest_api']['base_url'] ?? '/api', '/'));
164        $container->setParameter('apie.remote_mcp_path', $config['remote_mcp_path'] ?? null);
165        $container->setParameter('apie.ftp_server.public_ip', $config['ftp_server']['public_ip'] ?? '127.0.0.1');
166        $container->setParameter('apie.ftp_server.passive_min_port', $config['ftp_server']['passive_min_port'] ?? '127.0.0.1');
167        $container->setParameter('apie.ftp_server.passive_max_port', $config['ftp_server']['passive_max_port'] ?? '127.0.0.1');
168        $container->setParameter('apie.graphql.base_url', rtrim($config['graphql']['base_url'] ?? 'graphql', '/'));
169        $container->setParameter('apie.open_api.max_enum_size', $config['open_api']['max_enum_size'] ?? 100);
170        $container->setParameter('apie.language_typehint', $config['language_typehint'] ?? null);
171
172        if (($config['enable_maker'] ?? false) && is_array($config['maker'] ?? null)) {
173            $container->setParameter('apie.maker', $config['maker']);
174        } else {
175            $container->setParameter('apie.maker', null);
176        }
177        if ($config['enable_doctrine_entity_datalayer']) {
178            $type = $config['doctrine']['indexing']['type'] ?? 'direct';
179            $container->addAliases([
180                IndexStrategyInterface::class => match($type) {
181                    'direct' => DirectIndexStrategy::class,
182                    'late' => IndexAfterResponseIsSentStrategy::class,
183                    'background' => BackgroundIndexStrategy::class,
184                    default => $config['doctrine']['indexing']['service'] ?? DirectIndexStrategy::class,
185                },
186            ]);
187            if ($type === 'background') {
188                $definition = new Definition(ApieUpdateIdfCommand::class);
189                $definition->setArguments([
190                    new Reference(EntityReindexer::class),
191                    new Reference(OrmBuilder::class)
192                ]);
193                $definition->addTag('console.command');
194                $container->addDefinitions([ApieUpdateIdfCommand::class => $definition]);
195            }
196        }
197        $loaded = [];
198        foreach ($this->dependencies as $configName => $dependencyList) {
199            if ($config[$configName]) {
200                foreach ($dependencyList as $dependency) {
201                    if (!isset($loaded[$dependency])) {
202                        $loaded[$dependency] = true;
203                        $loader->load($dependency);
204                    }
205                }
206            }
207        }
208
209        $container->registerForAutoconfiguration(ContextBuilderInterface::class)
210            ->addTag('apie.core.context_builder');
211        $container->registerForAutoconfiguration(ApieContextService::class)
212            ->addTag('apie.context');
213        $container->registerForAutoconfiguration(RouteDefinitionProviderInterface::class)
214            ->addTag('apie.common.route_definition');
215        $container->registerForAutoconfiguration(ApieDatalayer::class)
216            ->addTag('apie.datalayer');
217        $container->registerForAutoconfiguration(ApieClassFaker::class)
218            ->addTag('apie.faker');
219        if ($config['enable_cms']) {
220            $container->registerForAutoconfiguration(FormComponentProviderInterface::class)
221                ->addTag(FormComponentProviderInterface::class);
222        }
223        if ($config['enable_cms_dropdown']) {
224            $container->registerForAutoconfiguration(DropdownOptionProviderInterface::class)
225                ->addTag(DropdownOptionProviderInterface::class);
226        }
227    }
228}