Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
96.71% covered (success)
96.71%
206 / 213
80.00% covered (warning)
80.00%
4 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
EngineServiceProvider
96.70% covered (success)
96.70%
205 / 212
80.00% covered (warning)
80.00%
4 / 5
8
0.00% covered (danger)
0.00%
0 / 1
 getDefinitions
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 getCoreEngineDefinitions
94.53% covered (success)
94.53%
121 / 128
0.00% covered (danger)
0.00%
0 / 1
4.00
 getControllerAndServiceDefinitions
100.00% covered (success)
100.00%
55 / 55
100.00% covered (success)
100.00%
1 / 1
1
 getInventoryDefinitions
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
1 / 1
1
 getExtensions
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5/** @license For full copyright and license information, please see the LICENSE.md file. */
6
7namespace App\Core\Bootstrap\Provider;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use App\Core\Engine\Application\Navigation\RecordNavigationService;
12use App\Core\Engine\Application\Persistence\UniversalPersistenceManager;
13use App\Core\Engine\Application\Query\RelationResolver;
14use App\Core\Engine\Application\Query\UniversalQueryBuilder;
15use App\Core\Engine\Application\Security\PermissionGuard;
16use App\Core\Engine\Application\Service\HierarchyService;
17use App\Core\Engine\Application\Service\PrefixGeneratorService;
18use App\Core\Engine\Application\Service\RecordFavoriteService;
19use App\Core\Engine\Application\Service\RecordPinService;
20use App\Core\Engine\Application\Service\RelationMmManager;
21use App\Core\Engine\Application\Service\UniversalCrudService;
22use App\Core\Engine\Application\Transformer\DefaultTransformersFactory;
23use App\Core\Engine\Application\Transformer\UiTypeTransformerPipeline;
24use App\Core\Engine\Application\Validator\UniversalValidationEngine;
25use App\Core\Engine\Domain\DataSource\DynamicDataProviderRegistry;
26use App\Core\Engine\Domain\Repository\AuditRepositoryInterface;
27use App\Core\Engine\Domain\Repository\MetadataRepositoryInterface;
28use App\Core\Engine\Domain\Service\WorkflowEngineInterface;
29use App\Core\Engine\Domain\Repository\InventoryFieldRepositoryInterface;
30use App\Core\Engine\Infrastructure\Repository\SqlInventoryFieldRepository;
31use App\Core\Engine\Application\Service\InventorySchemaEngine;
32use App\Core\Engine\Application\Service\InventoryApplicationService;
33use App\Modules\Map\Application\Service\MapGeocodingService;
34use App\Core\Engine\Infrastructure\Cache\PersistentMetadataCache;
35use App\Core\Engine\Infrastructure\Cache\RequestScopedMetadataCache;
36use App\Core\Engine\Infrastructure\Repository\SqlAuditRepository;
37use App\Core\Engine\Infrastructure\Repository\SqlMetadataRepository;
38use App\Core\Engine\Infrastructure\Repository\SqlPrefixRepository;
39use App\Core\Engine\Infrastructure\Settings\EngineSettings;
40use App\Core\Engine\Presentation\Api\CentralEngineApiController;
41use App\Core\Engine\Presentation\Api\GridWidgetApiController;
42use App\Core\Engine\Presentation\Api\ModuleFieldsApiController;
43use App\Core\Engine\Presentation\Api\ModuleRelationsApiController;
44use App\Core\Engine\Presentation\Api\PicklistValuesApiController;
45use App\Core\Engine\Presentation\Api\RelationMmApiController;
46use App\Core\Translation\Presentation\Api\LanguageTranslationsApiController;
47use App\Core\Engine\Presentation\Web\CentralEngineWebController;
48use App\Core\Event\SystemEventDispatcher;
49use App\Modules\Dav\Application\Listener\DavSyncRecordListener;
50use App\Modules\Dav\Application\Service\DavQueueDispatcher;
51use App\Core\Grid\Widget\DiagnosticsWidgetRenderer;
52use App\Core\Grid\Widget\PhysicalTableWidgetRenderer;
53use App\Core\Grid\Widget\VirtualTableWidgetRenderer;
54use App\Core\Grid\Widget\WidgetRegistry;
55use App\Core\Instance\Application\Service\InstanceContextManager;
56use App\Core\Instance\Application\Service\InstanceContextManagerInterface;
57use App\Core\Instance\Application\Service\RemoteInstanceEngineGateway;
58use App\Core\Instance\Application\Service\RemoteInstanceEngineGatewayInterface;
59use App\Core\Instance\Infrastructure\Client\RemoteInstanceApiClient;
60use App\Core\Instance\Infrastructure\Repository\SqlClientInstanceRepository;
61use App\Core\ModuleBuilder\Presentation\Web\BuildersHubWebController;
62use App\Modules\About\Application\Service\SystemDiagnosticsServiceInterface;
63use App\Modules\Calendar\Application\Listener\CalendarInvitationRecordListener;
64use App\Modules\Calendar\Application\Service\CalendarIcsGenerator;
65use App\Modules\Calendar\Application\Service\CalendarInvitationService;
66use App\Modules\Calendar\Application\Service\CalendarInvitationServiceInterface;
67use App\Modules\Calendar\Application\Service\CalendarRsvpTokenService;
68use App\Modules\Calendar\Application\Service\InboundCalendarReplyProcessor;
69use App\Modules\Calendar\Presentation\Web\CalendarRsvpWebController;
70use App\Modules\Mail\Domain\Repository\MailRepositoryInterface;
71use Nyholm\Psr7\Factory\Psr17Factory;
72use PDO;
73use Psr\Container\ContainerInterface;
74use Psr\EventDispatcher\EventDispatcherInterface;
75use Twig\Environment as TwigEnvironment;
76use Yiisoft\Aliases\Aliases;
77use Yiisoft\Cache\CacheInterface;
78use Yiisoft\Di\ServiceProviderInterface;
79
80/**
81 * EngineServiceProvider.
82 *
83 * Configures and registers Central Engine domain, persistence, metadata, and CRUD services.
84 *
85 * @package App\Core\Bootstrap\Provider
86 */
87final class EngineServiceProvider implements ServiceProviderInterface
88{
89    /**
90     * @return array<string, mixed> Definitions mapping for PSR-11 container.
91     */
92    public function getDefinitions(): array
93    {
94        return array_merge(
95            $this->getCoreEngineDefinitions(),
96            $this->getControllerAndServiceDefinitions(),
97            $this->getInventoryDefinitions()
98        );
99    }
100
101    /**
102     * @return array<string, mixed> Core database, engine, and crud definitions.
103     */
104    private function getCoreEngineDefinitions(): array
105    {
106        return [
107            SqlAuditRepository::class => static fn(PDO $pdo): SqlAuditRepository => new SqlAuditRepository($pdo),
108            AuditRepositoryInterface::class => static fn(SqlAuditRepository $r): AuditRepositoryInterface => $r,
109
110            EngineSettings::class => static fn(PDO $pdo): EngineSettings => new EngineSettings($pdo),
111
112            DavQueueDispatcher::class => static fn(PDO $pdo): DavQueueDispatcher => new DavQueueDispatcher($pdo),
113
114            DavSyncRecordListener::class => static fn(
115                DavQueueDispatcher $dispatcher
116            ): DavSyncRecordListener => new DavSyncRecordListener($dispatcher),
117
118            CalendarIcsGenerator::class => static fn(): CalendarIcsGenerator => new CalendarIcsGenerator(),
119            CalendarRsvpTokenService::class => static fn(): CalendarRsvpTokenService => new CalendarRsvpTokenService(),
120
121            CalendarInvitationService::class => static fn(
122                ContainerInterface $c
123            ): CalendarInvitationService => new CalendarInvitationService(
124                $c->get(CalendarIcsGenerator::class),
125                $c->get(CalendarRsvpTokenService::class),
126                $c->get(TwigEnvironment::class),
127                $c->get(MailRepositoryInterface::class),
128                $c->get(PDO::class)
129            ),
130            CalendarInvitationServiceInterface::class => static fn(
131                CalendarInvitationService $service
132            ): CalendarInvitationServiceInterface => $service,
133
134            CalendarInvitationRecordListener::class => static fn(
135                CalendarInvitationServiceInterface $service
136            ): CalendarInvitationRecordListener => new CalendarInvitationRecordListener($service),
137
138            InboundCalendarReplyProcessor::class => static fn(
139                CalendarInvitationServiceInterface $service,
140                PDO $pdo
141            ): InboundCalendarReplyProcessor => new InboundCalendarReplyProcessor($service, $pdo),
142
143            CalendarRsvpWebController::class => static fn(
144                Psr17Factory $psr17,
145                CalendarRsvpTokenService $tokenService,
146                CalendarInvitationServiceInterface $invitationService,
147                CalendarIcsGenerator $icsGenerator,
148                TwigEnvironment $twig
149            ): CalendarRsvpWebController => new CalendarRsvpWebController(
150                $psr17,
151                $tokenService,
152                $invitationService,
153                $icsGenerator,
154                $twig
155            ),
156
157            BuildersHubWebController::class => static fn(
158                TwigEnvironment $twig,
159                Psr17Factory $psr17
160            ): BuildersHubWebController => new BuildersHubWebController(
161                $twig,
162                $psr17
163            ),
164
165            SystemEventDispatcher::class => static fn(
166                SqlAuditRepository $audit,
167                EngineSettings $settings,
168                DavSyncRecordListener $davListener,
169                CalendarInvitationRecordListener $calendarListener
170            ): SystemEventDispatcher => new SystemEventDispatcher(
171                $audit,
172                $settings,
173                $davListener,
174                null,
175                $calendarListener
176            ),
177
178            EventDispatcherInterface::class => static fn(
179                SystemEventDispatcher $d
180            ): EventDispatcherInterface => $d,
181
182            SqlMetadataRepository::class => static fn(PDO $pdo): SqlMetadataRepository => (
183                new SqlMetadataRepository($pdo)
184            ),
185
186            MetadataRepositoryInterface::class => static function (ContainerInterface $c): MetadataRepositoryInterface {
187                $sqlRepo = $c->get(SqlMetadataRepository::class);
188                $cache = $c->get(CacheInterface::class);
189                $persistent = new PersistentMetadataCache($sqlRepo, $cache, 3600);
190                return new RequestScopedMetadataCache($persistent);
191            },
192
193            UniversalQueryBuilder::class => static fn(PDO $pdo): UniversalQueryBuilder => (
194                new UniversalQueryBuilder($pdo, new RelationResolver($pdo))
195            ),
196
197            UniversalPersistenceManager::class => static fn(PDO $pdo): UniversalPersistenceManager => (
198                new UniversalPersistenceManager($pdo)
199            ),
200
201            PermissionGuard::class => static fn(): PermissionGuard => new PermissionGuard(),
202            UniversalValidationEngine::class => static fn(PDO $pdo): UniversalValidationEngine => (
203                new UniversalValidationEngine($pdo)
204            ),
205
206            UiTypeTransformerPipeline::class => static fn(): UiTypeTransformerPipeline => (
207                new UiTypeTransformerPipeline(DefaultTransformersFactory::createDefaultTransformers())
208            ),
209
210            SqlPrefixRepository::class => static fn(PDO $pdo): SqlPrefixRepository => new SqlPrefixRepository($pdo),
211            PrefixGeneratorService::class => static fn(SqlPrefixRepository $r): PrefixGeneratorService => (
212                new PrefixGeneratorService($r)
213            ),
214
215            HierarchyService::class => static fn(PDO $pdo): HierarchyService => new HierarchyService($pdo),
216            RecordFavoriteService::class => static fn(
217                PDO $pdo
218            ): RecordFavoriteService => new RecordFavoriteService($pdo),
219            RecordPinService::class => static fn(PDO $pdo): RecordPinService => new RecordPinService($pdo),
220
221            RecordNavigationService::class => static fn(
222                MetadataRepositoryInterface $meta,
223                PermissionGuard $guard,
224                UniversalQueryBuilder $qb,
225                CacheInterface $cache
226            ): RecordNavigationService => new RecordNavigationService($meta, $guard, $qb, $cache),
227
228            UniversalCrudService::class => static fn(ContainerInterface $c): UniversalCrudService =>
229                new UniversalCrudService(
230                    $c->get(MetadataRepositoryInterface::class),
231                    $c->get(PermissionGuard::class),
232                    $c->get(UniversalQueryBuilder::class),
233                    $c->get(UniversalPersistenceManager::class),
234                    $c->get(UiTypeTransformerPipeline::class),
235                    $c->get(UniversalValidationEngine::class),
236                    $c->get(EventDispatcherInterface::class),
237                    $c->get(RecordNavigationService::class),
238                    $c->get(AuditRepositoryInterface::class),
239                    $c->get(DynamicDataProviderRegistry::class),
240                    $c->get(PrefixGeneratorService::class),
241                    $c->has(WorkflowEngineInterface::class) ? $c->get(WorkflowEngineInterface::class) : null,
242                    $c->has(MapGeocodingService::class) ? $c->get(MapGeocodingService::class) : null,
243                    $c->has(ProfilePermissionRepositoryInterface::class)
244                        ? $c->get(ProfilePermissionRepositoryInterface::class)
245                        : null,
246                ),
247
248            RemoteInstanceApiClient::class => static fn(): RemoteInstanceApiClient => new RemoteInstanceApiClient(),
249            RemoteInstanceEngineGateway::class => static fn(
250                RemoteInstanceApiClient $c
251            ): RemoteInstanceEngineGateway => new RemoteInstanceEngineGateway($c),
252            RemoteInstanceEngineGatewayInterface::class => static fn(
253                RemoteInstanceEngineGateway $g
254            ): RemoteInstanceEngineGatewayInterface => $g,
255        ];
256    }
257
258    /**
259     * @return array<string, mixed> Controller and API endpoint definitions.
260     */
261    private function getControllerAndServiceDefinitions(): array
262    {
263        return [
264            CentralEngineApiController::class => static fn(
265                ContainerInterface $c
266            ): CentralEngineApiController => new CentralEngineApiController(
267                $c->get(UniversalCrudService::class),
268                $c->get(Psr17Factory::class),
269                $c->get(InstanceContextManager::class),
270                $c->get(RemoteInstanceEngineGateway::class),
271                $c->get(HierarchyService::class),
272                null,
273                null,
274                $c->get(PDO::class),
275                'a_',
276                $c->get(RelationMmManager::class),
277                $c->get(RecordFavoriteService::class),
278                $c->get(RecordPinService::class)
279            ),
280
281            PicklistValuesApiController::class => static fn(
282                PDO $pdo,
283                Psr17Factory $psr17
284            ): PicklistValuesApiController => new PicklistValuesApiController($pdo, $psr17),
285
286            LanguageTranslationsApiController::class => static fn(
287                PDO $pdo,
288                Psr17Factory $psr17,
289                Aliases $aliases
290            ): LanguageTranslationsApiController => new LanguageTranslationsApiController(
291                $psr17,
292                $pdo,
293                $aliases->get('@root') . '/storage/cache/translations'
294            ),
295
296            ModuleFieldsApiController::class => static fn(
297                PDO $pdo,
298                Psr17Factory $psr17,
299                MetadataRepositoryInterface $meta
300            ): ModuleFieldsApiController => new ModuleFieldsApiController($pdo, $psr17, $meta),
301
302            ModuleRelationsApiController::class => static fn(
303                PDO $pdo,
304                Psr17Factory $psr17,
305                MetadataRepositoryInterface $meta
306            ): ModuleRelationsApiController => new ModuleRelationsApiController($pdo, $psr17, $meta),
307
308            RelationMmManager::class => static fn(
309                MetadataRepositoryInterface $meta,
310                PDO $pdo
311            ): RelationMmManager => new RelationMmManager($meta, $pdo),
312
313            RelationMmApiController::class => static fn(
314                RelationMmManager $mgr,
315                TwigEnvironment $twig,
316                Psr17Factory $psr17
317            ): RelationMmApiController => new RelationMmApiController($mgr, $twig, $psr17),
318
319            CentralEngineWebController::class => static fn(
320                TwigEnvironment $twig,
321                Psr17Factory $psr17,
322                CentralEngineApiController $api
323            ): CentralEngineWebController => new CentralEngineWebController($twig, $psr17, $api),
324        ];
325    }
326
327    /**
328     * @return array<string, mixed> Inventory subsystem definitions.
329     */
330    private function getInventoryDefinitions(): array
331    {
332        return [
333            SqlInventoryFieldRepository::class => static fn(PDO $pdo): SqlInventoryFieldRepository =>
334                new SqlInventoryFieldRepository($pdo),
335            InventoryFieldRepositoryInterface::class => static fn(
336                SqlInventoryFieldRepository $r
337            ): InventoryFieldRepositoryInterface => $r,
338
339            \App\Core\Engine\Infrastructure\Repository\SqlInventoryRecordRepository::class =>
340                static fn(PDO $pdo): \App\Core\Engine\Infrastructure\Repository\SqlInventoryRecordRepository =>
341                    new \App\Core\Engine\Infrastructure\Repository\SqlInventoryRecordRepository($pdo),
342            \App\Core\Engine\Domain\Repository\InventoryRecordRepositoryInterface::class => static fn(
343                \App\Core\Engine\Infrastructure\Repository\SqlInventoryRecordRepository $r
344            ): \App\Core\Engine\Domain\Repository\InventoryRecordRepositoryInterface => $r,
345
346            InventorySchemaEngine::class => static fn(
347                PDO $pdo,
348                InstanceContextManagerInterface $ctx
349            ): InventorySchemaEngine => new InventorySchemaEngine($pdo, $ctx),
350
351            InventoryApplicationService::class => static fn(
352                InventoryFieldRepositoryInterface $repo,
353                MetadataRepositoryInterface $meta,
354                InventorySchemaEngine $schemaEngine,
355                \App\Core\Engine\Domain\Repository\InventoryRecordRepositoryInterface $recRepo
356            ): InventoryApplicationService => new InventoryApplicationService($repo, $meta, $schemaEngine, $recRepo),
357        ];
358    }
359
360    /**
361     * @return array<string, mixed> Service extensions mapping.
362     */
363    public function getExtensions(): array
364    {
365        return [];
366    }
367}