Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
100.00% |
143 / 143 |
|
100.00% |
1 / 1 |
CRAP | |
100.00% |
1 / 1 |
| AppRouterFactory | |
100.00% |
142 / 142 |
|
100.00% |
1 / 1 |
2 | |
100.00% |
1 / 1 |
| createMatcher | |
100.00% |
142 / 142 |
|
100.00% |
1 / 1 |
2 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | /** @license For full copyright and license information, please see the LICENSE.md file. */ |
| 6 | |
| 7 | namespace App\Core\Router; |
| 8 | |
| 9 | defined('AMMONLY_APP') || exit('Direct script access is forbidden.'); |
| 10 | |
| 11 | use Yiisoft\Http\Method; |
| 12 | use Yiisoft\Router\FastRoute\UrlMatcher; |
| 13 | use Yiisoft\Router\Group; |
| 14 | use Yiisoft\Router\Route; |
| 15 | use Yiisoft\Router\RouteCollection; |
| 16 | use Yiisoft\Router\RouteCollector; |
| 17 | use Yiisoft\Router\UrlMatcherInterface; |
| 18 | |
| 19 | /** |
| 20 | * AppRouterFactory. |
| 21 | * |
| 22 | * Constructs and configures the compiled FastRoute URL matcher and route collections for all modules. |
| 23 | * |
| 24 | * @package App\Core\Router |
| 25 | */ |
| 26 | final class AppRouterFactory |
| 27 | { |
| 28 | private const string ROUTE_TAX_RATE_ITEM = '/api/v1/tax/rates/{id:\d+}'; |
| 29 | private const string ROUTE_DISCOUNT_ITEM = '/api/v1/discounts/{id:\d+}'; |
| 30 | |
| 31 | /** |
| 32 | * Builds the unified application UrlMatcher. |
| 33 | * |
| 34 | * @return UrlMatcherInterface Configured FastRoute URL matcher. |
| 35 | */ |
| 36 | public static function createMatcher(): UrlMatcherInterface |
| 37 | { |
| 38 | $collector = new RouteCollector(); |
| 39 | |
| 40 | $dummyAction = static fn(): null => null; |
| 41 | |
| 42 | $routes = [ |
| 43 | // Static & Docs |
| 44 | Route::get('/api')->action($dummyAction)->name('api_doc_ui'), |
| 45 | Route::get('/api/')->action($dummyAction)->name('api_doc_ui_slash'), |
| 46 | Route::get('/api/v1/openapi.json')->action($dummyAction)->name('openapi_spec'), |
| 47 | Route::post('/api/v1/logs/js-error')->action($dummyAction)->name('js_error_log'), |
| 48 | |
| 49 | // Auth |
| 50 | Route::methods([Method::GET, Method::POST], '/login')->action($dummyAction)->name('web_login'), |
| 51 | Route::methods([Method::GET, Method::POST], '/logout')->action($dummyAction)->name('web_logout'), |
| 52 | Route::post('/api/v1/auth/login')->action($dummyAction)->name('api_auth_login'), |
| 53 | Route::post('/api/v1/auth/logout')->action($dummyAction)->name('api_auth_logout'), |
| 54 | Route::get('/api/v1/auth/me')->action($dummyAction)->name('api_auth_me'), |
| 55 | |
| 56 | // Locale & I18n |
| 57 | Route::post('/api/v1/locale/change')->action($dummyAction)->name('api_locale_change'), |
| 58 | Route::get('/api/v1/locale/translations')->action($dummyAction)->name('api_translations'), |
| 59 | |
| 60 | // Calendar RSVP |
| 61 | Route::get('/calendar/rsvp')->action($dummyAction)->name('web_calendar_rsvp'), |
| 62 | Route::get('/calendar/rsvp/download')->action($dummyAction)->name('web_calendar_rsvp_download'), |
| 63 | |
| 64 | |
| 65 | Route::post('/api/v1/mail/smtp/{id:\d+}/test-connection')->action($dummyAction)->name('api_mail_test_smtp'), |
| 66 | Route::post('/api/v1/mail/servers/{id:\d+}/test-connection') |
| 67 | ->action($dummyAction) |
| 68 | ->name('api_mail_test_server'), |
| 69 | Route::post('/api/v1/mail/mailboxes/{id:\d+}/test-connection') |
| 70 | ->action($dummyAction) |
| 71 | ->name('api_mail_test_mailbox'), |
| 72 | Route::post('/api/v1/mail/enqueue')->action($dummyAction)->name('api_mail_enqueue'), |
| 73 | |
| 74 | // About & System Diagnostics |
| 75 | Route::get('/api/v1/about/licenses')->action($dummyAction)->name('api_about_licenses'), |
| 76 | Route::get('/api/v1/about/requirements')->action($dummyAction)->name('api_about_requirements'), |
| 77 | |
| 78 | // Menu |
| 79 | Route::get('/api/v1/menu')->action($dummyAction)->name('api_menu_tree'), |
| 80 | |
| 81 | // Central Engine API |
| 82 | Route::get('/api/v1/engine/{module:[a-zA-Z0-9_-]+}/list') |
| 83 | ->action($dummyAction) |
| 84 | ->name('api_engine_list'), |
| 85 | Route::get('/api/v1/engine/{module:[a-zA-Z0-9_-]+}/schema') |
| 86 | ->action($dummyAction) |
| 87 | ->name('api_engine_schema'), |
| 88 | Route::get('/api/v1/engine/{module:[a-zA-Z0-9_-]+}/read/{id:\d+}') |
| 89 | ->action($dummyAction) |
| 90 | ->name('api_engine_read'), |
| 91 | Route::post('/api/v1/engine/{module:[a-zA-Z0-9_-]+}/create') |
| 92 | ->action($dummyAction) |
| 93 | ->name('api_engine_create'), |
| 94 | Route::methods([Method::PUT, Method::PATCH], '/api/v1/engine/{module:[a-zA-Z0-9_-]+}/update/{id:\d+}') |
| 95 | ->action($dummyAction) |
| 96 | ->name('api_engine_update'), |
| 97 | Route::delete('/api/v1/engine/{module:[a-zA-Z0-9_-]+}/delete/{id:\d+}') |
| 98 | ->action($dummyAction) |
| 99 | ->name('api_engine_delete'), |
| 100 | Route::get('/api/v1/engine/{module:[a-zA-Z0-9_-]+}/timeline/{id:\d+}') |
| 101 | ->action($dummyAction) |
| 102 | ->name('api_engine_timeline'), |
| 103 | Route::post('/api/v1/engine/{module:[a-zA-Z0-9_-]+}/{id:\d+}/favorite') |
| 104 | ->action($dummyAction) |
| 105 | ->name('api_engine_favorite'), |
| 106 | Route::post('/api/v1/engine/{module:[a-zA-Z0-9_-]+}/{id:\d+}/pin') |
| 107 | ->action($dummyAction) |
| 108 | ->name('api_engine_pin'), |
| 109 | Route::get('/api/v1/engine/picklist/values') |
| 110 | ->action($dummyAction) |
| 111 | ->name('api_picklist_values'), |
| 112 | Route::get('/api/v1/engine/fields/{moduleId:\d+}') |
| 113 | ->action($dummyAction) |
| 114 | ->name('api_module_fields'), |
| 115 | Route::get('/api/v1/engine/{module:[a-z0-9_]+}/fields') |
| 116 | ->action($dummyAction) |
| 117 | ->name('api_engine_module_fields'), |
| 118 | Route::get('/api/v1/engine/relations/{moduleId:\d+}') |
| 119 | ->action($dummyAction) |
| 120 | ->name('api_module_relations'), |
| 121 | |
| 122 | // Data Exchange Endpoints (Import / Export) |
| 123 | Route::post('/api/v1/engine/{module:[a-zA-Z0-9_-]+}/export') |
| 124 | ->action($dummyAction) |
| 125 | ->name('api_engine_export'), |
| 126 | Route::post('/api/v1/engine/{module:[a-zA-Z0-9_-]+}/import/analyze') |
| 127 | ->action($dummyAction) |
| 128 | ->name('api_engine_import_analyze'), |
| 129 | Route::post('/api/v1/engine/{module:[a-zA-Z0-9_-]+}/import/execute') |
| 130 | ->action($dummyAction) |
| 131 | ->name('api_engine_import_execute'), |
| 132 | Route::get('/api/v1/engine/{module:[a-zA-Z0-9_-]+}/import/jobs/{id:\d+}') |
| 133 | ->action($dummyAction) |
| 134 | ->name('api_engine_import_job_status'), |
| 135 | |
| 136 | // Gantt & Kanban Endpoints |
| 137 | Route::get('/api/v1/projects/gantt')->action($dummyAction)->name('api_projects_gantt_all'), |
| 138 | Route::get('/api/v1/projects/{id:\d+}/gantt')->action($dummyAction)->name('api_projects_gantt'), |
| 139 | Route::get('/api/v1/project-stages/{id:\d+}/gantt')->action($dummyAction)->name('api_stages_gantt'), |
| 140 | Route::get('/api/v1/{module:[a-zA-Z0-9_-]+}/kanban')->action($dummyAction)->name('api_kanban_data'), |
| 141 | Route::methods( |
| 142 | [Method::PATCH, Method::PUT, Method::POST], |
| 143 | '/api/v1/{module:[a-zA-Z0-9_-]+}/{id:\d+}/status' |
| 144 | )->action($dummyAction)->name('api_kanban_status_update'), |
| 145 | |
| 146 | // PDF Engine & Template Endpoints |
| 147 | Route::get('/api/v1/pdf/templates')->action($dummyAction)->name('api_pdf_templates'), |
| 148 | Route::get('/api/v1/pdf/variables')->action($dummyAction)->name('api_pdf_variables'), |
| 149 | Route::post('/api/v1/pdf/compile-blocks')->action($dummyAction)->name('api_pdf_compile_blocks'), |
| 150 | Route::get('/api/v1/pdf/generate/{templateId:\d+}/{recordId:\d+}') |
| 151 | ->action($dummyAction) |
| 152 | ->name('api_pdf_generate'), |
| 153 | |
| 154 | // Tax Endpoints |
| 155 | Route::get('/api/v1/tax/rates')->action($dummyAction)->name('api_tax_rates_list'), |
| 156 | Route::get(self::ROUTE_TAX_RATE_ITEM)->action($dummyAction)->name('api_tax_rates_detail'), |
| 157 | Route::post('/api/v1/tax/rates')->action($dummyAction)->name('api_tax_rates_create'), |
| 158 | Route::methods([Method::PUT, Method::PATCH], self::ROUTE_TAX_RATE_ITEM) |
| 159 | ->action($dummyAction) |
| 160 | ->name('api_tax_rates_update'), |
| 161 | Route::delete(self::ROUTE_TAX_RATE_ITEM)->action($dummyAction)->name('api_tax_rates_delete'), |
| 162 | Route::post('/api/v1/tax/calculate')->action($dummyAction)->name('api_tax_calculate'), |
| 163 | Route::post('/api/v1/tax/simulate')->action($dummyAction)->name('api_tax_simulate'), |
| 164 | |
| 165 | // Discount Endpoints |
| 166 | Route::get('/api/v1/discounts')->action($dummyAction)->name('api_discounts_list'), |
| 167 | Route::get(self::ROUTE_DISCOUNT_ITEM)->action($dummyAction)->name('api_discounts_detail'), |
| 168 | Route::post('/api/v1/discounts')->action($dummyAction)->name('api_discounts_create'), |
| 169 | Route::methods([Method::PUT, Method::PATCH], self::ROUTE_DISCOUNT_ITEM) |
| 170 | ->action($dummyAction) |
| 171 | ->name('api_discounts_update'), |
| 172 | Route::delete(self::ROUTE_DISCOUNT_ITEM)->action($dummyAction)->name('api_discounts_delete'), |
| 173 | |
| 174 | // Inventory Fields Endpoints |
| 175 | Route::get('/api/v1/modules/{moduleId:\d+}/inventory-fields') |
| 176 | ->action($dummyAction) |
| 177 | ->name('api_module_inventory_fields_list'), |
| 178 | Route::post('/api/v1/modules/{moduleId:\d+}/inventory-fields') |
| 179 | ->action($dummyAction) |
| 180 | ->name('api_module_inventory_fields_create'), |
| 181 | Route::methods([Method::PUT, Method::PATCH], '/api/v1/modules/inventory-fields/{id:\d+}') |
| 182 | ->action($dummyAction) |
| 183 | ->name('api_module_inventory_fields_update'), |
| 184 | Route::delete('/api/v1/modules/inventory-fields/{id:\d+}') |
| 185 | ->action($dummyAction) |
| 186 | ->name('api_module_inventory_fields_delete'), |
| 187 | |
| 188 | // Module Builder Endpoints |
| 189 | Route::get('/api/v1/system/module-builder/metadata-options') |
| 190 | ->action($dummyAction) |
| 191 | ->name('api_module_builder_metadata_options'), |
| 192 | Route::get('/api/v1/system/module-builder/schema/{id:\d+}') |
| 193 | ->action($dummyAction) |
| 194 | ->name('api_module_builder_schema'), |
| 195 | Route::post('/api/v1/system/module-builder/suggest-field') |
| 196 | ->action($dummyAction) |
| 197 | ->name('api_module_builder_suggest_field'), |
| 198 | Route::post('/api/v1/system/module-builder/create') |
| 199 | ->action($dummyAction) |
| 200 | ->name('api_module_builder_create'), |
| 201 | Route::methods([Method::PUT, Method::PATCH, Method::POST], '/api/v1/system/module-builder/update/{id:\d+}') |
| 202 | ->action($dummyAction) |
| 203 | ->name('api_module_builder_update'), |
| 204 | Route::delete('/api/v1/system/module-builder/{id:\d+}') |
| 205 | ->action($dummyAction) |
| 206 | ->name('api_module_builder_delete'), |
| 207 | ]; |
| 208 | |
| 209 | foreach ($routes as $route) { |
| 210 | $collector->addRoute($route); |
| 211 | } |
| 212 | |
| 213 | return new UrlMatcher(new RouteCollection($collector)); |
| 214 | } |
| 215 | } |