Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
118 / 118
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
BootstrapRouteDispatcherFactory
100.00% covered (success)
100.00%
117 / 117
100.00% covered (success)
100.00%
3 / 3
4
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 create
100.00% covered (success)
100.00%
82 / 82
100.00% covered (success)
100.00%
1 / 1
1
 buildExtraControllers
100.00% covered (success)
100.00%
34 / 34
100.00% covered (success)
100.00%
1 / 1
2
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\Configurator;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use App\Core\Api\Presentation\ApiDispatcher;
12use App\Core\Api\Presentation\Web\OpenApiDocController;
13use App\Core\Engine\Application\Security\PermissionContextFactory;
14use App\Core\Engine\Domain\Repository\MetadataRepositoryInterface;
15use App\Core\Instance\Application\Service\InstanceContextManager;
16use App\Core\ModuleBuilder\Application\Service\ModuleBuilderService;
17use App\Core\ModuleBuilder\Presentation\Web\BuildersHubWebController;
18use App\Core\ModuleBuilder\Presentation\Web\ModuleBuilderWebController;
19use App\Modules\Calendar\Presentation\Web\CalendarRsvpWebController;
20use App\Modules\Comments\Presentation\Htmx\CommentsHtmxController;
21use App\Modules\Comments\Presentation\Htmx\MentionsHtmxController;
22use App\Modules\Comments\Presentation\Web\CommentAttachmentDownloadWebController;
23use App\Modules\Comments\Presentation\Web\MentionsWebController;
24use App\Modules\Currencies\Presentation\Web\CurrenciesWebController;
25use App\Modules\Dashboard\Presentation\Api\DashboardApiController;
26use App\Modules\Dashboard\Presentation\Htmx\DashboardHtmxController;
27use App\Modules\Dashboard\Presentation\Web\DashboardWebController;
28use App\Modules\DataMapping\Presentation\Htmx\DataMappingHtmxController;
29use App\Modules\DataMapping\Presentation\Web\DataMappingWebController;
30use App\Modules\Dav\Presentation\Web\DavSetupWebController;
31use App\Modules\Discount\Presentation\Htmx\DiscountHtmxController;
32use App\Modules\Discount\Presentation\Web\DiscountSettingsWebController;
33use App\Modules\Inventory\Presentation\Htmx\InventoryItemsHtmxController;
34use App\Modules\Inventory\Presentation\Htmx\InventorySettingsHtmxController;
35use App\Modules\Inventory\Presentation\Web\InventorySettingsWebController;
36use App\Modules\Logs\Presentation\Api\JsErrorLogApiController;
37use App\Modules\Mail\Presentation\Htmx\WebmailHtmxController;
38use App\Modules\Mail\Presentation\Web\MailTemplateWebController;
39use App\Modules\Mail\Presentation\Web\MailTrackingWebController;
40use App\Modules\Mail\Presentation\Web\WebmailWebController;
41use App\Modules\Map\Presentation\Htmx\MapHtmxController;
42use App\Modules\Map\Presentation\Web\MapWebController;
43use App\Modules\Pdf\Presentation\Htmx\PdfHtmxController;
44use App\Modules\Pdf\Presentation\Htmx\PdfQueueHtmxController;
45use App\Modules\Pdf\Presentation\Htmx\PdfSignatureHtmxController;
46use App\Modules\Pdf\Presentation\Web\DocumentVerificationWebController;
47use App\Modules\Pdf\Presentation\Web\PdfWebController;
48use App\Modules\Quotes\Presentation\Web\QuoteConversionWebController;
49use App\Modules\Tax\Presentation\Htmx\TaxHtmxController;
50use App\Modules\Tax\Presentation\Web\TaxSettingsWebController;
51use App\Modules\User\Infrastructure\Repository\SqlUserRepository;
52use App\Modules\User\Presentation\Middleware\AuthenticatedOnlyMiddleware;
53use App\Modules\User\Presentation\Middleware\GuestOnlyMiddleware;
54use App\Modules\User\Presentation\Web\AuthController;
55use App\Modules\User\Presentation\Web\ImpersonationWebController;
56use Nyholm\Psr7\Factory\Psr17Factory;
57use Yiisoft\Session\SessionInterface;
58use Yiisoft\User\CurrentUser;
59
60/**
61 * Factory responsible for assembling the central BootstrapRouteDispatcher from configuration context.
62 */
63final readonly class BootstrapRouteDispatcherFactory
64{
65    private const string LOGS_SUBPATH = '/storage/logs';
66
67    public function __construct(
68        private Psr17Factory $psr17Factory,
69        private CurrentUser $currentUser,
70        private SessionInterface $session,
71        private SqlUserRepository $userRepository
72    ) {
73    }
74
75    /**
76     * Creates and returns a fully configured BootstrapRouteDispatcher instance.
77     *
78     * @param array<string, mixed> $context
79     */
80    public function create(
81        SecurityAndTemplateConfigurator $sec,
82        string $basePath,
83        AuthController $authController,
84        ApiDispatcher $apiDispatcher,
85        BootstrapEngineFactory $engineFactory,
86        array $context
87    ): BootstrapRouteDispatcher {
88        /** @var MetadataRepositoryInterface $metadataRepo */
89        $metadataRepo = $context['metadata'];
90        /** @var InstanceContextManager $instanceContextManager */
91        $instanceContextManager = $context['instance_context'];
92        $appProfile = (string) ($context['app_profile'] ?? 'admin');
93
94        $openApiDocController = new OpenApiDocController(
95            $this->psr17Factory,
96            $sec->twig,
97            $sec->activeProfile
98        );
99        $jsErrorLogApiController = new JsErrorLogApiController(
100            $this->psr17Factory,
101            $basePath . self::LOGS_SUBPATH,
102            $sec->securityAuditLogger
103        );
104        $pdo = $engineFactory->universalCrudService->getPersistenceManager()->getPdo();
105        $contextFactory = new PermissionContextFactory($this->session, $pdo);
106        $authMiddleware = new AuthenticatedOnlyMiddleware($this->currentUser, $this->psr17Factory);
107        $guestMiddleware = new GuestOnlyMiddleware($this->currentUser, $this->psr17Factory);
108
109        $extra = $this->buildExtraControllers($sec, $appProfile, $pdo, $metadataRepo, $engineFactory);
110
111        return new BootstrapRouteDispatcher(
112            $openApiDocController,
113            $jsErrorLogApiController,
114            $apiDispatcher,
115            $authController,
116            $engineFactory->centralEngineWebController,
117            $engineFactory->centralEngineApiController,
118            $engineFactory->picklistValuesApiController,
119            $engineFactory->moduleFieldsApiController,
120            $engineFactory->moduleRelationsApiController,
121            $metadataRepo,
122            $this->userRepository,
123            $this->currentUser,
124            $this->session,
125            $contextFactory,
126            $authMiddleware,
127            $guestMiddleware,
128            $sec->csrfMiddleware,
129            $this->psr17Factory,
130            $instanceContextManager,
131            $engineFactory->relationMmApiController,
132            $context['dav_setup'] ?? null,
133            $context['webmail_web'] ?? null,
134            $context['webmail_htmx'] ?? null,
135            $sec->twig,
136            $engineFactory->mediaUploadApiController,
137            $engineFactory->documentDownloadWebController,
138            $context['map_web'] ?? null,
139            $context['map_htmx'] ?? null,
140            $context['pdf_htmx'] ?? null,
141            $context['pdf_web'] ?? null,
142            $context['doc_verification'] ?? null,
143            $context['pdf_signature_htmx'] ?? null,
144            $context['pdf_queue_htmx'] ?? null,
145            $context['mail_tracking_web'] ?? null,
146            $context['mail_template_web'] ?? null,
147            $context['access_web'] ?? null,
148            $context['comments_htmx'] ?? null,
149            $context['comment_attachment_download_web'] ?? null,
150            $context['mentions_web'] ?? null,
151            $context['mentions_htmx'] ?? null,
152            $context['impersonation_web'] ?? null,
153            $context['dashboard_web'] ?? null,
154            $context['dashboard_api'] ?? null,
155            $context['dashboard_htmx'] ?? null,
156            $appProfile,
157            null,
158            $context['tax_web'] ?? null,
159            $context['tax_htmx'] ?? null,
160            $context['discount_web'] ?? null,
161            $context['discount_htmx'] ?? null,
162            $context['inventory_web'] ?? null,
163            $context['inventory_htmx'] ?? null,
164            $context['inventory_items_htmx'] ?? null,
165            $context['mapping_web'] ?? null,
166            $context['mapping_htmx'] ?? null,
167            $context['quote_conversion_web'] ?? null,
168            $context['currencies_web'] ?? null,
169            $engineFactory->languageTranslationsApiController,
170            $extra['data_exchange_htmx'],
171            $extra['module_builder_web'],
172            $context['calendar_rsvp_web'] ?? null,
173            $extra['builders_hub_web']
174        );
175    }
176
177    /**
178     * @return array{
179     *     data_exchange_htmx: \App\Core\DataExchange\Presentation\Htmx\DataExchangeHtmxController,
180     *     module_builder_web: ModuleBuilderWebController,
181     *     builders_hub_web: BuildersHubWebController
182     * }
183     */
184    private function buildExtraControllers(
185        SecurityAndTemplateConfigurator $sec,
186        string $appProfile,
187        \PDO $pdo,
188        MetadataRepositoryInterface $metadataRepo,
189        BootstrapEngineFactory $engineFactory
190    ): array {
191        $exportService = new \App\Core\DataExchange\Application\Service\DataExportService(
192            $engineFactory->centralEngineApiController->getCrudService(),
193            $pdo
194        );
195        $importService = new \App\Core\DataExchange\Application\Service\DataImportService(
196            $engineFactory->centralEngineApiController->getCrudService(),
197            $pdo
198        );
199        $dataExchangeHtmxController = new \App\Core\DataExchange\Presentation\Htmx\DataExchangeHtmxController(
200            $exportService,
201            $importService,
202            $metadataRepo,
203            null,
204            $sec->twig,
205            $this->psr17Factory,
206            $pdo
207        );
208
209        $moduleBuilderService = new ModuleBuilderService(
210            $pdo,
211            null,
212            ($appProfile === 'client') ? 'c_' : 'a_'
213        );
214        $moduleBuilderWebController = new ModuleBuilderWebController(
215            $moduleBuilderService,
216            $sec->twig,
217            $this->psr17Factory,
218            $appProfile
219        );
220        $buildersHubWebController = new BuildersHubWebController($this->psr17Factory);
221
222        return [
223            'data_exchange_htmx' => $dataExchangeHtmxController,
224            'module_builder_web' => $moduleBuilderWebController,
225            'builders_hub_web'   => $buildersHubWebController,
226        ];
227    }
228}