Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
91.89% |
34 / 37 |
|
0.00% |
0 / 2 |
CRAP | |
0.00% |
0 / 1 |
ErrorMessages | |
91.89% |
34 / 37 |
|
0.00% |
0 / 2 |
9.04 | |
0.00% |
0 / 1 |
get | |
96.55% |
28 / 29 |
|
0.00% |
0 / 1 |
3 | |||
getHighestStatusCode | |
75.00% |
6 / 8 |
|
0.00% |
0 / 1 |
6.56 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | namespace BO\Zmscitizenapi\Localization; |
6 | |
7 | use BO\Zmscitizenapi\Middleware\LanguageMiddleware; |
8 | |
9 | class ErrorMessages |
10 | { |
11 | private const HTTP_OK = 200; |
12 | private const HTTP_BAD_REQUEST = 400; |
13 | private const HTTP_FORBIDDEN = 403; |
14 | private const HTTP_NOT_FOUND = 404; |
15 | private const HTTP_INVALID_REQUEST_METHOD = 405; |
16 | private const HTTP_NOT_ACCEPTABLE = 406; |
17 | private const HTTP_CONFLICT = 409; |
18 | private const HTTP_REQUEST_ENTITY_TOO_LARGE = 413; |
19 | private const HTTP_TOO_MANY_REQUESTS = 429; |
20 | private const HTTP_INTERNAL_SERVER_ERROR = 500; |
21 | private const HTTP_NOT_IMPLEMENTED = 501; |
22 | private const HTTP_UNAVAILABLE = 503; |
23 | private const HTTP_UNKNOWN = 520; |
24 | private const DEFAULT_LANGUAGE = 'DE'; |
25 | private const FALLBACK_LANGUAGE = 'EN'; |
26 | // English messages |
27 | public const EN = [ |
28 | 'zmsClientCommunicationError' => [ |
29 | 'errorCode' => 'zmsClientCommunicationError', |
30 | 'errorMessage' => 'The service is temporarily unavailable. Please try again later.', |
31 | 'statusCode' => 503 |
32 | ], |
33 | 'notImplemented' => [ |
34 | 'errorCode' => 'notImplemented', |
35 | 'statusCode' => self::HTTP_NOT_IMPLEMENTED, |
36 | 'errorMessage' => 'Feature not implemented yet.', |
37 | ], |
38 | 'notFound' => [ |
39 | 'errorCode' => 'notFound', |
40 | 'statusCode' => self::HTTP_NOT_FOUND, |
41 | 'errorMessage' => 'Endpoint not found.', |
42 | ], |
43 | 'invalidRequest' => [ |
44 | 'errorCode' => 'invalidRequest', |
45 | 'statusCode' => self::HTTP_BAD_REQUEST, |
46 | 'errorMessage' => 'Invalid request.' |
47 | ], |
48 | 'requestMethodNotAllowed' => [ |
49 | 'errorCode' => 'requestMethodNotAllowed', |
50 | 'statusCode' => self::HTTP_INVALID_REQUEST_METHOD, |
51 | 'errorMessage' => 'Request method not allowed.', |
52 | ], |
53 | 'captchaVerificationFailed' => [ |
54 | 'errorCode' => 'captchaVerificationFailed', |
55 | 'statusCode' => self::HTTP_BAD_REQUEST, |
56 | 'errorMessage' => 'Captcha verification failed.' |
57 | ], |
58 | 'invalidLocationAndServiceCombination' => [ |
59 | 'errorCode' => 'invalidLocationAndServiceCombination', |
60 | 'statusCode' => self::HTTP_BAD_REQUEST, |
61 | 'errorMessage' => 'The provided service(s) do not exist at the given location.' |
62 | ], |
63 | 'invalidStartDate' => [ |
64 | 'errorCode' => 'invalidStartDate', |
65 | 'statusCode' => self::HTTP_BAD_REQUEST, |
66 | 'errorMessage' => 'startDate is required and must be a valid date.' |
67 | ], |
68 | 'invalidEndDate' => [ |
69 | 'errorCode' => 'invalidEndDate', |
70 | 'statusCode' => self::HTTP_BAD_REQUEST, |
71 | 'errorMessage' => 'endDate is required and must be a valid date.' |
72 | ], |
73 | 'invalidOfficeId' => [ |
74 | 'errorCode' => 'invalidOfficeId', |
75 | 'statusCode' => self::HTTP_BAD_REQUEST, |
76 | 'errorMessage' => 'officeId should be a 32-bit integer.' |
77 | ], |
78 | 'invalidServiceId' => [ |
79 | 'errorCode' => 'invalidServiceId', |
80 | 'statusCode' => self::HTTP_BAD_REQUEST, |
81 | 'errorMessage' => 'serviceId should be a 32-bit integer.' |
82 | ], |
83 | 'emptyServiceArrays' => [ |
84 | 'errorCode' => 'EMPTY_SERVICE_ARRAYS', |
85 | 'statusCode' => self::HTTP_BAD_REQUEST, |
86 | 'errorMessage' => 'Service IDs and counts cannot be empty' |
87 | ], |
88 | 'mismatchedArrays' => [ |
89 | 'errorCode' => 'MISMATCHED_ARRAYS', |
90 | 'statusCode' => self::HTTP_BAD_REQUEST, |
91 | 'errorMessage' => 'Service IDs and counts must have same length' |
92 | ], |
93 | 'invalidServiceCount' => [ |
94 | 'errorCode' => 'invalidServiceCount', |
95 | 'statusCode' => self::HTTP_BAD_REQUEST, |
96 | 'errorMessage' => 'serviceCounts should be an array of numeric values.' |
97 | ], |
98 | 'invalidProcessId' => [ |
99 | 'errorCode' => 'invalidProcessId', |
100 | 'statusCode' => self::HTTP_BAD_REQUEST, |
101 | 'errorMessage' => 'processId should be a positive 32-bit integer.' |
102 | ], |
103 | 'invalidScopeId' => [ |
104 | 'errorCode' => 'invalidScopeId', |
105 | 'statusCode' => self::HTTP_BAD_REQUEST, |
106 | 'errorMessage' => 'scopeId should be a positive 32-bit integer.' |
107 | ], |
108 | 'invalidAuthKey' => [ |
109 | 'errorCode' => 'invalidAuthKey', |
110 | 'statusCode' => self::HTTP_BAD_REQUEST, |
111 | 'errorMessage' => 'authKey should be a string.' |
112 | ], |
113 | 'invalidDate' => [ |
114 | 'errorCode' => 'invalidDate', |
115 | 'statusCode' => self::HTTP_BAD_REQUEST, |
116 | 'errorMessage' => 'date is required and must be a valid date.' |
117 | ], |
118 | 'invalidTimestamp' => [ |
119 | 'errorCode' => 'invalidTimestamp', |
120 | 'statusCode' => self::HTTP_BAD_REQUEST, |
121 | 'errorMessage' => 'Missing timestamp or invalid timestamp format. It should be a positive numeric value.' |
122 | ], |
123 | 'invalidFamilyName' => [ |
124 | 'errorCode' => 'invalidFamilyName', |
125 | 'statusCode' => self::HTTP_BAD_REQUEST, |
126 | 'errorMessage' => 'familyName should be a non-empty string.' |
127 | ], |
128 | 'invalidEmail' => [ |
129 | 'errorCode' => 'invalidEmail', |
130 | 'statusCode' => self::HTTP_BAD_REQUEST, |
131 | 'errorMessage' => 'email should be a valid email address.' |
132 | ], |
133 | 'invalidTelephone' => [ |
134 | 'errorCode' => 'invalidTelephone', |
135 | 'statusCode' => self::HTTP_BAD_REQUEST, |
136 | 'errorMessage' => 'telephone should be a numeric string between 7 and 15 digits.' |
137 | ], |
138 | 'invalidCustomTextfield' => [ |
139 | 'errorCode' => 'invalidCustomTextfield', |
140 | 'statusCode' => self::HTTP_BAD_REQUEST, |
141 | 'errorMessage' => 'customTextfield should be a string.' |
142 | ], |
143 | 'appointmentCanNotBeCanceled' => [ |
144 | 'errorCode' => 'appointmentCanNotBeCanceled', |
145 | 'statusCode' => self::HTTP_NOT_ACCEPTABLE, |
146 | 'errorMessage' => 'The selected appointment cannot be canceled.' |
147 | ], |
148 | 'appointmentNotAvailable' => [ |
149 | 'errorCode' => 'appointmentNotAvailable', |
150 | 'statusCode' => self::HTTP_OK, |
151 | 'errorMessage' => 'The selected appointment is unfortunately no longer available.' |
152 | ], |
153 | 'noAppointmentForThisDay' => [ |
154 | 'errorCode' => 'noAppointmentForThisDay', |
155 | 'statusCode' => self::HTTP_OK, |
156 | 'errorMessage' => 'No available days found for the given criteria.' |
157 | ], |
158 | 'captchaVerificationError' => [ |
159 | 'errorCode' => 'captchaVerificationError', |
160 | 'statusCode' => self::HTTP_BAD_REQUEST, |
161 | 'errorMessage' => 'An error occurred during captcha verification.' |
162 | ], |
163 | 'captchaMissing' => [ |
164 | 'errorCode' => 'captchaMissing', |
165 | 'statusCode' => self::HTTP_BAD_REQUEST, |
166 | 'errorMessage' => 'Missing captcha token.', |
167 | ], |
168 | 'captchaInvalid' => [ |
169 | 'errorCode' => 'captchaInvalid', |
170 | 'statusCode' => self::HTTP_BAD_REQUEST, |
171 | 'errorMessage' => 'Invalid captcha token.', |
172 | ], |
173 | 'captchaExpired' => [ |
174 | 'errorCode' => 'captchaExpired', |
175 | 'statusCode' => self::HTTP_BAD_REQUEST, |
176 | 'errorMessage' => 'Captcha token expired.', |
177 | ], |
178 | 'serviceUnavailable' => [ |
179 | 'errorCode' => 'serviceUnavailable', |
180 | 'statusCode' => self::HTTP_UNAVAILABLE, |
181 | 'errorMessage' => 'Service Unavailable: The application is under maintenance.' |
182 | ], |
183 | 'invalidSchema' => [ |
184 | 'errorCode' => 'invalidSchema', |
185 | 'statusCode' => self::HTTP_BAD_REQUEST, |
186 | 'errorMessage' => 'Data does not match the required schema.' |
187 | ], |
188 | |
189 | //Zmsapi exceptions |
190 | 'internalError' => [ |
191 | 'errorCode' => 'internalError', |
192 | 'errorMessage' => 'An internal error occurred. Please try again later.', |
193 | 'statusCode' => self::HTTP_INTERNAL_SERVER_ERROR |
194 | ], |
195 | 'invalidApiClient' => [ |
196 | 'errorCode' => 'invalidApiClient', |
197 | 'errorMessage' => 'Invalid API client.', |
198 | 'statusCode' => self::HTTP_BAD_REQUEST |
199 | ], |
200 | 'sourceNotFound' => [ |
201 | 'errorCode' => 'sourceNotFound', |
202 | 'statusCode' => self::HTTP_NOT_FOUND, |
203 | 'errorMessage' => 'Source not found.', |
204 | ], |
205 | 'departmentNotFound' => [ |
206 | 'errorCode' => 'departmentNotFound', |
207 | 'errorMessage' => 'Department not found.', |
208 | 'statusCode' => self::HTTP_NOT_FOUND |
209 | ], |
210 | 'mailNotFound' => [ |
211 | 'errorCode' => 'mailNotFound', |
212 | 'errorMessage' => 'Mail template not found.', |
213 | 'statusCode' => self::HTTP_NOT_FOUND |
214 | ], |
215 | 'organisationNotFound' => [ |
216 | 'errorCode' => 'organisationNotFound', |
217 | 'errorMessage' => 'Organisation not found.', |
218 | 'statusCode' => self::HTTP_NOT_FOUND |
219 | ], |
220 | 'providerNotFound' => [ |
221 | 'errorCode' => 'providerNotFound', |
222 | 'errorMessage' => 'Provider not found.', |
223 | 'statusCode' => self::HTTP_NOT_FOUND |
224 | ], |
225 | 'requestNotFound' => [ |
226 | 'errorCode' => 'requestNotFound', |
227 | 'errorMessage' => 'Requested service not found.', |
228 | 'statusCode' => self::HTTP_NOT_FOUND |
229 | ], |
230 | 'scopeNotFound' => [ |
231 | 'errorCode' => 'scopeNotFound', |
232 | 'errorMessage' => 'Scope not found.', |
233 | 'statusCode' => self::HTTP_NOT_FOUND |
234 | ], |
235 | 'processInvalid' => [ |
236 | 'errorCode' => 'processInvalid', |
237 | 'errorMessage' => 'The process data is invalid.', |
238 | 'statusCode' => self::HTTP_BAD_REQUEST |
239 | ], |
240 | 'processAlreadyExists' => [ |
241 | 'errorCode' => 'processAlreadyExists', |
242 | 'errorMessage' => 'An appointment process already exists.', |
243 | 'statusCode' => self::HTTP_CONFLICT |
244 | ], |
245 | 'processDeleteFailed' => [ |
246 | 'errorCode' => 'processDeleteFailed', |
247 | 'errorMessage' => 'Failed to delete the appointment.', |
248 | 'statusCode' => self::HTTP_INTERNAL_SERVER_ERROR |
249 | ], |
250 | 'processAlreadyCalled' => [ |
251 | 'errorCode' => 'processAlreadyCalled', |
252 | 'errorMessage' => 'The appointment has already been called.', |
253 | 'statusCode' => self::HTTP_CONFLICT |
254 | ], |
255 | 'processNotReservedAnymore' => [ |
256 | 'errorCode' => 'processNotReservedAnymore', |
257 | 'errorMessage' => 'The appointment is no longer reserved.', |
258 | 'statusCode' => self::HTTP_CONFLICT |
259 | ], |
260 | 'processNotPreconfirmedAnymore' => [ |
261 | 'errorCode' => 'processNotPreconfirmedAnymore', |
262 | 'errorMessage' => 'The appointment is no longer preconfirmed.', |
263 | 'statusCode' => self::HTTP_CONFLICT |
264 | ], |
265 | 'emailIsRequired' => [ |
266 | 'errorCode' => 'emailIsRequired', |
267 | 'errorMessage' => 'Email address is required.', |
268 | 'statusCode' => self::HTTP_NOT_ACCEPTABLE |
269 | ], |
270 | 'telephoneIsRequired' => [ |
271 | 'errorCode' => 'telephoneIsRequired', |
272 | 'errorMessage' => 'Telephone number is required.', |
273 | 'statusCode' => self::HTTP_NOT_ACCEPTABLE |
274 | ], |
275 | 'appointmentNotFound' => [ |
276 | 'errorCode' => 'appointmentNotFound', |
277 | 'errorMessage' => 'The requested appointment could not be found.', |
278 | 'statusCode' => self::HTTP_NOT_FOUND |
279 | ], |
280 | 'authKeyMismatch' => [ |
281 | 'errorCode' => 'authKeyMismatch', |
282 | 'errorMessage' => 'Invalid authentication key.', |
283 | 'statusCode' => self::HTTP_NOT_ACCEPTABLE |
284 | ], |
285 | 'noAppointmentForThisScope' => [ |
286 | 'errorCode' => 'noAppointmentForThisScope', |
287 | 'errorMessage' => 'Unfortunately, there are currently no available appointments at this location.', |
288 | 'statusCode' => self::HTTP_OK |
289 | ], |
290 | 'tooManyAppointmentsWithSameMail' => [ |
291 | 'errorCode' => 'tooManyAppointmentsWithSameMail', |
292 | 'errorMessage' => 'Too many appointments with the same email address.', |
293 | 'statusCode' => self::HTTP_NOT_ACCEPTABLE |
294 | ], |
295 | 'scopesNotFound' => [ |
296 | 'errorCode' => 'scopesNotFound', |
297 | 'errorMessage' => 'No scopes found.', |
298 | 'statusCode' => self::HTTP_NOT_FOUND |
299 | ], |
300 | 'preconfirmationExpired' => [ |
301 | 'errorCode' => 'preconfirmationExpired', |
302 | 'statusCode' => self::HTTP_BAD_REQUEST, |
303 | 'errorMessage' => 'The preconfirmation has expired. Please make a new appointment.' |
304 | ], |
305 | |
306 | //Middleware exceptions |
307 | 'ipBlacklisted' => [ |
308 | 'errorCode' => 'IP_BLACKLISTED', |
309 | 'statusCode' => self::HTTP_FORBIDDEN, |
310 | 'errorMessage' => 'Access denied - IP address is blacklisted.' |
311 | ], |
312 | 'corsOriginNotAllowed' => [ |
313 | 'errorCode' => 'corsOriginNotAllowed', |
314 | 'statusCode' => self::HTTP_FORBIDDEN, |
315 | 'errorMessage' => 'Origin not allowed by CORS policy.' |
316 | ], |
317 | 'csrfTokenMissing' => [ |
318 | 'errorCode' => 'csrfTokenMissing', |
319 | 'statusCode' => self::HTTP_FORBIDDEN, |
320 | 'errorMessage' => 'CSRF token is missing.' |
321 | ], |
322 | 'csrfTokenInvalid' => [ |
323 | 'errorCode' => 'csrfTokenInvalid', |
324 | 'statusCode' => self::HTTP_FORBIDDEN, |
325 | 'errorMessage' => 'Invalid CSRF token.' |
326 | ], |
327 | 'rateLimitExceeded' => [ |
328 | 'errorCode' => 'rateLimitExceeded', |
329 | 'statusCode' => self::HTTP_TOO_MANY_REQUESTS, |
330 | 'errorMessage' => 'Rate limit exceeded. Please try again later.' |
331 | ], |
332 | 'requestEntityTooLarge' => [ |
333 | 'errorCode' => 'requestEntityTooLarge', |
334 | 'statusCode' => self::HTTP_REQUEST_ENTITY_TOO_LARGE, |
335 | 'errorMessage' => 'Request entity too large.' |
336 | ], |
337 | 'securityHeaderViolation' => [ |
338 | 'errorCode' => 'securityHeaderViolation', |
339 | 'statusCode' => self::HTTP_FORBIDDEN, |
340 | 'errorMessage' => 'Security policy violation.' |
341 | ] |
342 | |
343 | ]; |
344 | // German messages |
345 | public const DE = [ |
346 | 'zmsClientCommunicationError' => [ |
347 | 'errorCode' => 'zmsClientCommunicationError', |
348 | 'errorMessage' => 'Der Dienst ist vorübergehend nicht verfügbar. Bitte versuchen Sie es später erneut.', |
349 | 'statusCode' => 503 |
350 | ], |
351 | 'notImplemented' => [ |
352 | 'errorCode' => 'notImplemented', |
353 | 'statusCode' => self::HTTP_NOT_IMPLEMENTED, |
354 | 'errorMessage' => 'Funktion ist noch nicht implementiert.', |
355 | ], |
356 | 'notFound' => [ |
357 | 'errorCode' => 'notFound', |
358 | 'statusCode' => self::HTTP_NOT_FOUND, |
359 | 'errorMessage' => 'Endpunkt nicht gefunden.', |
360 | ], |
361 | 'invalidRequest' => [ |
362 | 'errorCode' => 'invalidRequest', |
363 | 'statusCode' => self::HTTP_BAD_REQUEST, |
364 | 'errorMessage' => 'Ungültige Anfrage.' |
365 | ], |
366 | 'requestMethodNotAllowed' => [ |
367 | 'errorCode' => 'requestMethodNotAllowed', |
368 | 'statusCode' => self::HTTP_INVALID_REQUEST_METHOD, |
369 | 'errorMessage' => 'Anfragemethode nicht zulässig.', |
370 | ], |
371 | 'captchaVerificationFailed' => [ |
372 | 'errorCode' => 'captchaVerificationFailed', |
373 | 'statusCode' => self::HTTP_BAD_REQUEST, |
374 | 'errorMessage' => 'Captcha-Prüfung fehlgeschlagen.' |
375 | ], |
376 | 'invalidLocationAndServiceCombination' => [ |
377 | 'errorCode' => 'invalidLocationAndServiceCombination', |
378 | 'statusCode' => self::HTTP_BAD_REQUEST, |
379 | 'errorMessage' => 'Die angegebene Dienstleistung ist an diesem Standort nicht verfügbar.' |
380 | ], |
381 | 'invalidStartDate' => [ |
382 | 'errorCode' => 'invalidStartDate', |
383 | 'statusCode' => self::HTTP_BAD_REQUEST, |
384 | 'errorMessage' => 'startDate ist erforderlich und muss ein gültiges Datum sein.' |
385 | ], |
386 | 'invalidEndDate' => [ |
387 | 'errorCode' => 'invalidEndDate', |
388 | 'statusCode' => self::HTTP_BAD_REQUEST, |
389 | 'errorMessage' => 'endDate ist erforderlich und muss ein gültiges Datum sein.' |
390 | ], |
391 | 'invalidOfficeId' => [ |
392 | 'errorCode' => 'invalidOfficeId', |
393 | 'statusCode' => self::HTTP_BAD_REQUEST, |
394 | 'errorMessage' => 'officeId muss eine 32-Bit-Ganzzahl sein.' |
395 | ], |
396 | 'invalidServiceId' => [ |
397 | 'errorCode' => 'invalidServiceId', |
398 | 'statusCode' => self::HTTP_BAD_REQUEST, |
399 | 'errorMessage' => 'serviceId muss eine 32-Bit-Ganzzahl sein.' |
400 | ], |
401 | 'invalidServiceCount' => [ |
402 | 'errorCode' => 'invalidServiceCount', |
403 | 'statusCode' => self::HTTP_BAD_REQUEST, |
404 | 'errorMessage' => 'serviceCounts muss ein Array aus numerischen Werten sein.' |
405 | ], |
406 | 'emptyServiceArrays' => [ |
407 | 'errorCode' => 'EMPTY_SERVICE_ARRAYS', |
408 | 'statusCode' => self::HTTP_BAD_REQUEST, |
409 | 'errorMessage' => 'Service-IDs und Anzahl dürfen nicht leer sein' |
410 | ], |
411 | 'mismatchedArrays' => [ |
412 | 'errorCode' => 'MISMATCHED_ARRAYS', |
413 | 'statusCode' => self::HTTP_BAD_REQUEST, |
414 | 'errorMessage' => 'Service-IDs und Anzahl müssen gleiche Länge haben' |
415 | ], |
416 | 'invalidProcessId' => [ |
417 | 'errorCode' => 'invalidProcessId', |
418 | 'statusCode' => self::HTTP_BAD_REQUEST, |
419 | 'errorMessage' => 'processId muss eine positive 32-Bit-Ganzzahl sein.' |
420 | ], |
421 | 'invalidScopeId' => [ |
422 | 'errorCode' => 'invalidScopeId', |
423 | 'statusCode' => self::HTTP_BAD_REQUEST, |
424 | 'errorMessage' => 'scopeId muss eine positive 32-Bit-Ganzzahl sein.' |
425 | ], |
426 | 'invalidAuthKey' => [ |
427 | 'errorCode' => 'invalidAuthKey', |
428 | 'statusCode' => self::HTTP_BAD_REQUEST, |
429 | 'errorMessage' => 'authKey muss eine Zeichenkette sein.' |
430 | ], |
431 | 'invalidDate' => [ |
432 | 'errorCode' => 'invalidDate', |
433 | 'statusCode' => self::HTTP_BAD_REQUEST, |
434 | 'errorMessage' => 'date ist erforderlich und muss ein gültiges Datum sein.' |
435 | ], |
436 | 'invalidTimestamp' => [ |
437 | 'errorCode' => 'invalidTimestamp', |
438 | 'statusCode' => self::HTTP_BAD_REQUEST, |
439 | 'errorMessage' => 'Fehlender oder ungültiger Zeitstempel. Der Wert muss eine positive Zahl sein.' |
440 | ], |
441 | 'invalidFamilyName' => [ |
442 | 'errorCode' => 'invalidFamilyName', |
443 | 'statusCode' => self::HTTP_BAD_REQUEST, |
444 | 'errorMessage' => 'familyName muss eine nicht-leere Zeichenkette sein.' |
445 | ], |
446 | 'invalidEmail' => [ |
447 | 'errorCode' => 'invalidEmail', |
448 | 'statusCode' => self::HTTP_BAD_REQUEST, |
449 | 'errorMessage' => 'email muss eine gültige E-Mail-Adresse sein.' |
450 | ], |
451 | 'invalidTelephone' => [ |
452 | 'errorCode' => 'invalidTelephone', |
453 | 'statusCode' => self::HTTP_BAD_REQUEST, |
454 | 'errorMessage' => 'telephone muss eine Zahlenkette zwischen 7 und 15 Stellen sein.' |
455 | ], |
456 | 'invalidCustomTextfield' => [ |
457 | 'errorCode' => 'invalidCustomTextfield', |
458 | 'statusCode' => self::HTTP_BAD_REQUEST, |
459 | 'errorMessage' => 'customTextfield muss eine Zeichenkette sein.' |
460 | ], |
461 | 'appointmentCanNotBeCanceled' => [ |
462 | 'errorCode' => 'appointmentCanNotBeCanceled', |
463 | 'statusCode' => self::HTTP_NOT_ACCEPTABLE, |
464 | 'errorMessage' => 'Der von Ihnen gewählte Termin kann leider nicht mehr gelöscht werden.' |
465 | ], |
466 | 'appointmentNotAvailable' => [ |
467 | 'errorCode' => 'appointmentNotAvailable', |
468 | 'statusCode' => self::HTTP_OK, |
469 | 'errorMessage' => 'Der von Ihnen gewählte Termin ist leider nicht mehr verfügbar.' |
470 | ], |
471 | 'noAppointmentForThisDay' => [ |
472 | 'errorCode' => 'noAppointmentForThisDay', |
473 | 'statusCode' => self::HTTP_OK, |
474 | 'errorMessage' => 'Keine verfügbaren Termine für dieses Datum.' |
475 | ], |
476 | 'captchaVerificationError' => [ |
477 | 'errorCode' => 'captchaVerificationError', |
478 | 'statusCode' => self::HTTP_BAD_REQUEST, |
479 | 'errorMessage' => 'Bei der Captcha-Prüfung ist ein Fehler aufgetreten.' |
480 | ], |
481 | 'serviceUnavailable' => [ |
482 | 'errorCode' => 'serviceUnavailable', |
483 | 'statusCode' => self::HTTP_UNAVAILABLE, |
484 | 'errorMessage' => 'Der Dienst ist nicht verfügbar: Die Anwendung wird gerade gewartet.' |
485 | ], |
486 | 'invalidSchema' => [ |
487 | 'errorCode' => 'invalidSchema', |
488 | 'statusCode' => self::HTTP_BAD_REQUEST, |
489 | 'errorMessage' => 'Daten entsprechen nicht dem erforderlichen Schema.' |
490 | ], |
491 | |
492 | //Zmsapi exceptions |
493 | 'internalError' => [ |
494 | 'errorCode' => 'internalError', |
495 | 'errorMessage' => 'Ein interner Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.', |
496 | 'statusCode' => self::HTTP_INTERNAL_SERVER_ERROR |
497 | ], |
498 | 'invalidApiClient' => [ |
499 | 'errorCode' => 'invalidApiClient', |
500 | 'errorMessage' => 'Ungültiger API-Client.', |
501 | 'statusCode' => self::HTTP_BAD_REQUEST |
502 | ], |
503 | 'sourceNotFound' => [ |
504 | 'errorCode' => 'sourceNotFound', |
505 | 'statusCode' => self::HTTP_NOT_FOUND, |
506 | 'errorMessage' => 'Quelle nicht gefunden.', |
507 | ], |
508 | 'departmentNotFound' => [ |
509 | 'errorCode' => 'departmentNotFound', |
510 | 'errorMessage' => 'Abteilung nicht gefunden.', |
511 | 'statusCode' => self::HTTP_NOT_FOUND |
512 | ], |
513 | 'mailNotFound' => [ |
514 | 'errorCode' => 'mailNotFound', |
515 | 'errorMessage' => 'E-Mail-Vorlage nicht gefunden.', |
516 | 'statusCode' => self::HTTP_NOT_FOUND |
517 | ], |
518 | 'organisationNotFound' => [ |
519 | 'errorCode' => 'organisationNotFound', |
520 | 'errorMessage' => 'Organisation nicht gefunden.', |
521 | 'statusCode' => self::HTTP_NOT_FOUND |
522 | ], |
523 | 'providerNotFound' => [ |
524 | 'errorCode' => 'providerNotFound', |
525 | 'errorMessage' => 'Anbieter nicht gefunden.', |
526 | 'statusCode' => self::HTTP_NOT_FOUND |
527 | ], |
528 | 'requestNotFound' => [ |
529 | 'errorCode' => 'requestNotFound', |
530 | 'errorMessage' => 'Angeforderter Dienst nicht gefunden.', |
531 | 'statusCode' => self::HTTP_NOT_FOUND |
532 | ], |
533 | 'scopeNotFound' => [ |
534 | 'errorCode' => 'scopeNotFound', |
535 | 'errorMessage' => 'Bereich nicht gefunden.', |
536 | 'statusCode' => self::HTTP_NOT_FOUND |
537 | ], |
538 | 'processInvalid' => [ |
539 | 'errorCode' => 'processInvalid', |
540 | 'errorMessage' => 'Die Prozessdaten sind ungültig.', |
541 | 'statusCode' => self::HTTP_BAD_REQUEST |
542 | ], |
543 | 'processAlreadyExists' => [ |
544 | 'errorCode' => 'processAlreadyExists', |
545 | 'errorMessage' => 'Ein Terminprozess existiert bereits.', |
546 | 'statusCode' => self::HTTP_CONFLICT |
547 | ], |
548 | 'processDeleteFailed' => [ |
549 | 'errorCode' => 'processDeleteFailed', |
550 | 'errorMessage' => 'Der Termin konnte nicht gelöscht werden.', |
551 | 'statusCode' => self::HTTP_INTERNAL_SERVER_ERROR |
552 | ], |
553 | 'processAlreadyCalled' => [ |
554 | 'errorCode' => 'processAlreadyCalled', |
555 | 'errorMessage' => 'Der Termin wurde bereits aufgerufen.', |
556 | 'statusCode' => self::HTTP_CONFLICT |
557 | ], |
558 | 'processNotReservedAnymore' => [ |
559 | 'errorCode' => 'processNotReservedAnymore', |
560 | 'errorMessage' => 'Der Termin ist nicht mehr reserviert.', |
561 | 'statusCode' => self::HTTP_CONFLICT |
562 | ], |
563 | 'processNotPreconfirmedAnymore' => [ |
564 | 'errorCode' => 'processNotPreconfirmedAnymore', |
565 | 'errorMessage' => 'Der Termin ist nicht mehr vorbestätigt.', |
566 | 'statusCode' => self::HTTP_CONFLICT |
567 | ], |
568 | 'emailIsRequired' => [ |
569 | 'errorCode' => 'emailIsRequired', |
570 | 'errorMessage' => 'E-Mail-Adresse ist erforderlich.', |
571 | 'statusCode' => self::HTTP_NOT_ACCEPTABLE |
572 | ], |
573 | 'telephoneIsRequired' => [ |
574 | 'errorCode' => 'telephoneIsRequired', |
575 | 'errorMessage' => 'Telefonnummer ist erforderlich.', |
576 | 'statusCode' => self::HTTP_NOT_ACCEPTABLE |
577 | ], |
578 | 'appointmentNotFound' => [ |
579 | 'errorCode' => 'appointmentNotFound', |
580 | 'errorMessage' => 'Der angeforderte Termin wurde nicht gefunden.', |
581 | 'statusCode' => self::HTTP_NOT_FOUND |
582 | ], |
583 | 'authKeyMismatch' => [ |
584 | 'errorCode' => 'authKeyMismatch', |
585 | 'errorMessage' => 'Ungültiger Authentifizierungsschlüssel.', |
586 | 'statusCode' => self::HTTP_NOT_ACCEPTABLE |
587 | ], |
588 | 'noAppointmentForThisScope' => [ |
589 | 'errorCode' => 'noAppointmentForThisScope', |
590 | 'errorMessage' => 'An diesem Standort gibt es aktuell leider keine freien Termine.', |
591 | 'statusCode' => self::HTTP_OK |
592 | ], |
593 | 'tooManyAppointmentsWithSameMail' => [ |
594 | 'errorCode' => 'tooManyAppointmentsWithSameMail', |
595 | 'errorMessage' => 'Zu viele Termine mit derselben E-Mail-Adresse.', |
596 | 'statusCode' => self::HTTP_NOT_ACCEPTABLE |
597 | ], |
598 | 'scopesNotFound' => [ |
599 | 'errorCode' => 'scopesNotFound', |
600 | 'errorMessage' => 'Keine Bereiche gefunden.', |
601 | 'statusCode' => self::HTTP_NOT_FOUND |
602 | ], |
603 | 'preconfirmationExpired' => [ |
604 | 'errorCode' => 'preconfirmationExpired', |
605 | 'statusCode' => self::HTTP_BAD_REQUEST, |
606 | 'errorMessage' => 'Die Vorbestätigung ist abgelaufen. Bitte vereinbaren Sie einen neuen Termin.' |
607 | ], |
608 | |
609 | //Middleware exceptions |
610 | 'ipBlacklisted' => [ |
611 | 'errorCode' => 'IP_BLACKLISTED', |
612 | 'statusCode' => self::HTTP_FORBIDDEN, |
613 | 'errorMessage' => 'Zugriff verweigert - IP-Adresse ist auf der schwarzen Liste.' |
614 | ], |
615 | 'corsOriginNotAllowed' => [ |
616 | 'errorCode' => 'corsOriginNotAllowed', |
617 | 'statusCode' => self::HTTP_FORBIDDEN, |
618 | 'errorMessage' => 'Ursprung durch CORS-Richtlinie nicht erlaubt.' // DE: 'Ursprung durch CORS-Richtlinie nicht erlaubt.' |
619 | ], |
620 | 'csrfTokenMissing' => [ |
621 | 'errorCode' => 'csrfTokenMissing', |
622 | 'statusCode' => self::HTTP_FORBIDDEN, |
623 | 'errorMessage' => 'CSRF-Token fehlt.' // DE: 'CSRF-Token fehlt.' |
624 | ], |
625 | 'csrfTokenInvalid' => [ |
626 | 'errorCode' => 'csrfTokenInvalid', |
627 | 'statusCode' => self::HTTP_FORBIDDEN, |
628 | 'errorMessage' => 'Ungültiger CSRF-Token.' // DE: 'Ungültiger CSRF-Token.' |
629 | ], |
630 | 'rateLimitExceeded' => [ |
631 | 'errorCode' => 'rateLimitExceeded', |
632 | 'statusCode' => self::HTTP_TOO_MANY_REQUESTS, |
633 | 'errorMessage' => 'Anfragelimit überschritten. Bitte versuchen Sie es später erneut.' // DE: 'Anfragelimit überschritten. Bitte versuchen Sie es später erneut.' |
634 | ], |
635 | 'requestEntityTooLarge' => [ |
636 | 'errorCode' => 'requestEntityTooLarge', |
637 | 'statusCode' => self::HTTP_REQUEST_ENTITY_TOO_LARGE, |
638 | 'errorMessage' => 'Anfrage zu groß.' // DE: 'Anfrage zu groß.' |
639 | ], |
640 | 'securityHeaderViolation' => [ |
641 | 'errorCode' => 'securityHeaderViolation', |
642 | 'statusCode' => self::HTTP_FORBIDDEN, |
643 | 'errorMessage' => 'Verstoß gegen Sicherheitsrichtlinien.' // DE: 'Verstoß gegen Sicherheitsrichtlinien.' |
644 | ] |
645 | |
646 | ]; |
647 | public const UA = [ |
648 | 'zmsClientCommunicationError' => [ |
649 | 'errorCode' => 'zmsClientCommunicationError', |
650 | 'errorMessage' => 'Сервіс тимчасово недоступний. Будь ласка, спробуйте пізніше.', |
651 | 'statusCode' => 503 |
652 | ], |
653 | 'notImplemented' => [ |
654 | 'errorCode' => 'notImplemented', |
655 | 'statusCode' => self::HTTP_NOT_IMPLEMENTED, |
656 | 'errorMessage' => 'Функцію ще не реалізовано.', |
657 | ], |
658 | 'notFound' => [ |
659 | 'errorCode' => 'notFound', |
660 | 'statusCode' => self::HTTP_NOT_FOUND, |
661 | 'errorMessage' => 'Кінцеву точку не знайдено.', |
662 | ], |
663 | 'invalidRequest' => [ |
664 | 'errorCode' => 'invalidRequest', |
665 | 'statusCode' => self::HTTP_BAD_REQUEST, |
666 | 'errorMessage' => 'Недійсний запит.' |
667 | ], |
668 | 'requestMethodNotAllowed' => [ |
669 | 'errorCode' => 'requestMethodNotAllowed', |
670 | 'statusCode' => self::HTTP_INVALID_REQUEST_METHOD, |
671 | 'errorMessage' => 'Метод запиту не дозволено.', |
672 | ], |
673 | 'captchaVerificationFailed' => [ |
674 | 'errorCode' => 'captchaVerificationFailed', |
675 | 'statusCode' => self::HTTP_BAD_REQUEST, |
676 | 'errorMessage' => 'Перевірка капчі не вдалася.' |
677 | ], |
678 | 'invalidLocationAndServiceCombination' => [ |
679 | 'errorCode' => 'invalidLocationAndServiceCombination', |
680 | 'statusCode' => self::HTTP_BAD_REQUEST, |
681 | 'errorMessage' => 'Вказані послуги не існують у цьому місці.' |
682 | ], |
683 | 'invalidStartDate' => [ |
684 | 'errorCode' => 'invalidStartDate', |
685 | 'statusCode' => self::HTTP_BAD_REQUEST, |
686 | 'errorMessage' => 'Потрібна дійсна дата початку.' |
687 | ], |
688 | 'invalidEndDate' => [ |
689 | 'errorCode' => 'invalidEndDate', |
690 | 'statusCode' => self::HTTP_BAD_REQUEST, |
691 | 'errorMessage' => 'Потрібна дійсна дата завершення.' |
692 | ], |
693 | 'invalidOfficeId' => [ |
694 | 'errorCode' => 'invalidOfficeId', |
695 | 'statusCode' => self::HTTP_BAD_REQUEST, |
696 | 'errorMessage' => 'officeId має бути 32-бітним цілим числом.' |
697 | ], |
698 | 'invalidServiceId' => [ |
699 | 'errorCode' => 'invalidServiceId', |
700 | 'statusCode' => self::HTTP_BAD_REQUEST, |
701 | 'errorMessage' => 'serviceId має бути 32-бітним цілим числом.' |
702 | ], |
703 | 'emptyServiceArrays' => [ |
704 | 'errorCode' => 'EMPTY_SERVICE_ARRAYS', |
705 | 'statusCode' => self::HTTP_BAD_REQUEST, |
706 | 'errorMessage' => 'Ідентифікатори та кількість послуг не можуть бути порожніми' |
707 | ], |
708 | 'mismatchedArrays' => [ |
709 | 'errorCode' => 'MISMATCHED_ARRAYS', |
710 | 'statusCode' => self::HTTP_BAD_REQUEST, |
711 | 'errorMessage' => 'Ідентифікатори та кількість послуг повинні мати однакову довжину' |
712 | ], |
713 | 'invalidServiceCount' => [ |
714 | 'errorCode' => 'invalidServiceCount', |
715 | 'statusCode' => self::HTTP_BAD_REQUEST, |
716 | 'errorMessage' => 'serviceCounts має бути масивом числових значень.' |
717 | ], |
718 | 'invalidProcessId' => [ |
719 | 'errorCode' => 'invalidProcessId', |
720 | 'statusCode' => self::HTTP_BAD_REQUEST, |
721 | 'errorMessage' => 'processId має бути додатним 32-бітним цілим числом.' |
722 | ], |
723 | 'invalidScopeId' => [ |
724 | 'errorCode' => 'invalidScopeId', |
725 | 'statusCode' => self::HTTP_BAD_REQUEST, |
726 | 'errorMessage' => 'scopeId має бути додатним 32-бітним цілим числом.' |
727 | ], |
728 | 'invalidAuthKey' => [ |
729 | 'errorCode' => 'invalidAuthKey', |
730 | 'statusCode' => self::HTTP_BAD_REQUEST, |
731 | 'errorMessage' => 'authKey має бути рядком.' |
732 | ], |
733 | 'invalidDate' => [ |
734 | 'errorCode' => 'invalidDate', |
735 | 'statusCode' => self::HTTP_BAD_REQUEST, |
736 | 'errorMessage' => 'Потрібна дійсна дата.' |
737 | ], |
738 | 'invalidTimestamp' => [ |
739 | 'errorCode' => 'invalidTimestamp', |
740 | 'statusCode' => self::HTTP_BAD_REQUEST, |
741 | 'errorMessage' => 'Відсутня або недійсна мітка часу. Має бути додатним числовим значенням.' |
742 | ], |
743 | 'invalidFamilyName' => [ |
744 | 'errorCode' => 'invalidFamilyName', |
745 | 'statusCode' => self::HTTP_BAD_REQUEST, |
746 | 'errorMessage' => 'Прізвище не може бути порожнім.' |
747 | ], |
748 | 'invalidEmail' => [ |
749 | 'errorCode' => 'invalidEmail', |
750 | 'statusCode' => self::HTTP_BAD_REQUEST, |
751 | 'errorMessage' => 'Потрібна дійсна електронна адреса.' |
752 | ], |
753 | 'invalidTelephone' => [ |
754 | 'errorCode' => 'invalidTelephone', |
755 | 'statusCode' => self::HTTP_BAD_REQUEST, |
756 | 'errorMessage' => 'Номер телефону має містити від 7 до 15 цифр.' |
757 | ], |
758 | 'invalidCustomTextfield' => [ |
759 | 'errorCode' => 'invalidCustomTextfield', |
760 | 'statusCode' => self::HTTP_BAD_REQUEST, |
761 | 'errorMessage' => 'customTextfield має бути рядком.' |
762 | ], |
763 | 'appointmentCanNotBeCanceled' => [ |
764 | 'errorCode' => 'appointmentCanNotBeCanceled', |
765 | 'statusCode' => self::HTTP_NOT_ACCEPTABLE, |
766 | 'errorMessage' => 'Обраний запис не може бути скасовано.' |
767 | ], |
768 | 'appointmentNotAvailable' => [ |
769 | 'errorCode' => 'appointmentNotAvailable', |
770 | 'statusCode' => self::HTTP_OK, |
771 | 'errorMessage' => 'На жаль, обраний запис більше недоступний.' |
772 | ], |
773 | 'noAppointmentForThisDay' => [ |
774 | 'errorCode' => 'noAppointmentForThisDay', |
775 | 'statusCode' => self::HTTP_OK, |
776 | 'errorMessage' => 'Немає доступних днів за вказаними критеріями.' |
777 | ], |
778 | 'captchaVerificationError' => [ |
779 | 'errorCode' => 'captchaVerificationError', |
780 | 'statusCode' => self::HTTP_BAD_REQUEST, |
781 | 'errorMessage' => 'Виникла помилка під час перевірки капчі.' |
782 | ], |
783 | 'serviceUnavailable' => [ |
784 | 'errorCode' => 'serviceUnavailable', |
785 | 'statusCode' => self::HTTP_UNAVAILABLE, |
786 | 'errorMessage' => 'Сервіс недоступний: Додаток перебуває на технічному обслуговуванні.' |
787 | ], |
788 | 'invalidSchema' => [ |
789 | 'errorCode' => 'invalidSchema', |
790 | 'statusCode' => self::HTTP_BAD_REQUEST, |
791 | 'errorMessage' => 'Дані не відповідають необхідній схемі.' |
792 | ], |
793 | 'internalError' => [ |
794 | 'errorCode' => 'internalError', |
795 | 'errorMessage' => 'Виникла внутрішня помилка. Спробуйте пізніше.', |
796 | 'statusCode' => self::HTTP_INTERNAL_SERVER_ERROR |
797 | ], |
798 | 'invalidApiClient' => [ |
799 | 'errorCode' => 'invalidApiClient', |
800 | 'errorMessage' => 'Недійсний API клієнт.', |
801 | 'statusCode' => self::HTTP_BAD_REQUEST |
802 | ], |
803 | 'sourceNotFound' => [ |
804 | 'errorCode' => 'sourceNotFound', |
805 | 'statusCode' => self::HTTP_NOT_FOUND, |
806 | 'errorMessage' => 'Джерело не знайдено.', |
807 | ], |
808 | 'departmentNotFound' => [ |
809 | 'errorCode' => 'departmentNotFound', |
810 | 'errorMessage' => 'Відділ не знайдено.', |
811 | 'statusCode' => self::HTTP_NOT_FOUND |
812 | ], |
813 | 'mailNotFound' => [ |
814 | 'errorCode' => 'mailNotFound', |
815 | 'errorMessage' => 'Шаблон листа не знайдено.', |
816 | 'statusCode' => self::HTTP_NOT_FOUND |
817 | ], |
818 | 'organisationNotFound' => [ |
819 | 'errorCode' => 'organisationNotFound', |
820 | 'errorMessage' => 'Організацію не знайдено.', |
821 | 'statusCode' => self::HTTP_NOT_FOUND |
822 | ], |
823 | 'providerNotFound' => [ |
824 | 'errorCode' => 'providerNotFound', |
825 | 'errorMessage' => 'Постачальника не знайдено.', |
826 | 'statusCode' => self::HTTP_NOT_FOUND |
827 | ], |
828 | 'requestNotFound' => [ |
829 | 'errorCode' => 'requestNotFound', |
830 | 'errorMessage' => 'Запитану послугу не знайдено.', |
831 | 'statusCode' => self::HTTP_NOT_FOUND |
832 | ], |
833 | 'scopeNotFound' => [ |
834 | 'errorCode' => 'scopeNotFound', |
835 | 'errorMessage' => 'Область не знайдено.', |
836 | 'statusCode' => self::HTTP_NOT_FOUND |
837 | ], |
838 | 'processInvalid' => [ |
839 | 'errorCode' => 'processInvalid', |
840 | 'errorMessage' => 'Дані процесу недійсні.', |
841 | 'statusCode' => self::HTTP_BAD_REQUEST |
842 | ], |
843 | 'processAlreadyExists' => [ |
844 | 'errorCode' => 'processAlreadyExists', |
845 | 'errorMessage' => 'Процес запису вже існує.', |
846 | 'statusCode' => self::HTTP_CONFLICT |
847 | ], |
848 | 'processDeleteFailed' => [ |
849 | 'errorCode' => 'processDeleteFailed', |
850 | 'errorMessage' => 'Не вдалося видалити запис.', |
851 | 'statusCode' => self::HTTP_INTERNAL_SERVER_ERROR |
852 | ], |
853 | 'processAlreadyCalled' => [ |
854 | 'errorCode' => 'processAlreadyCalled', |
855 | 'errorMessage' => 'Запис вже викликано.', |
856 | 'statusCode' => self::HTTP_CONFLICT |
857 | ], |
858 | 'processNotReservedAnymore' => [ |
859 | 'errorCode' => 'processNotReservedAnymore', |
860 | 'errorMessage' => 'Запис більше не зарезервовано.', |
861 | 'statusCode' => self::HTTP_CONFLICT |
862 | ], |
863 | 'processNotPreconfirmedAnymore' => [ |
864 | 'errorCode' => 'processNotPreconfirmedAnymore', |
865 | 'errorMessage' => 'Запис більше не попередньо підтверджено.', |
866 | 'statusCode' => self::HTTP_CONFLICT |
867 | ], |
868 | 'emailIsRequired' => [ |
869 | 'errorCode' => 'emailIsRequired', |
870 | 'errorMessage' => 'Потрібна електронна адреса.', |
871 | 'statusCode' => self::HTTP_NOT_ACCEPTABLE |
872 | ], |
873 | 'telephoneIsRequired' => [ |
874 | 'errorCode' => 'telephoneIsRequired', |
875 | 'errorMessage' => 'Потрібен номер телефону.', |
876 | 'statusCode' => self::HTTP_NOT_ACCEPTABLE |
877 | ], |
878 | 'appointmentNotFound' => [ |
879 | 'errorCode' => 'appointmentNotFound', |
880 | 'errorMessage' => 'Запитаний запис не знайдено.', |
881 | 'statusCode' => self::HTTP_NOT_FOUND |
882 | ], |
883 | 'authKeyMismatch' => [ |
884 | 'errorCode' => 'authKeyMismatch', |
885 | 'errorMessage' => 'Недійсний ключ автентифікації.', |
886 | 'statusCode' => self::HTTP_NOT_ACCEPTABLE |
887 | ], |
888 | 'noAppointmentForThisScope' => [ |
889 | 'errorCode' => 'noAppointmentForThisScope', |
890 | 'errorMessage' => 'На жаль, наразі на цій локації немає вільних записів.', |
891 | 'statusCode' => self::HTTP_OK |
892 | ], |
893 | 'tooManyAppointmentsWithSameMail' => [ |
894 | 'errorCode' => 'tooManyAppointmentsWithSameMail', |
895 | 'errorMessage' => 'Забагато записів з однією електронною адресою.', |
896 | 'statusCode' => self::HTTP_NOT_ACCEPTABLE |
897 | ], |
898 | 'scopesNotFound' => [ |
899 | 'errorCode' => 'scopesNotFound', |
900 | 'errorMessage' => 'Області не знайдено.', |
901 | 'statusCode' => self::HTTP_NOT_FOUND |
902 | ], |
903 | 'preconfirmationExpired' => [ |
904 | 'errorCode' => 'preconfirmationExpired', |
905 | 'statusCode' => self::HTTP_BAD_REQUEST, |
906 | 'errorMessage' => 'Попереднє підтвердження закінчилося. Будь ласка, створіть новий запис.' |
907 | ], |
908 | 'ipBlacklisted' => [ |
909 | 'errorCode' => 'IP_BLACKLISTED', |
910 | 'statusCode' => self::HTTP_FORBIDDEN, |
911 | 'errorMessage' => 'Доступ заборонено - IP-адресу заблоковано.' |
912 | ], |
913 | 'corsOriginNotAllowed' => [ |
914 | 'errorCode' => 'corsOriginNotAllowed', |
915 | 'statusCode' => self::HTTP_FORBIDDEN, |
916 | 'errorMessage' => 'Джерело не дозволено політикою CORS.' |
917 | ], |
918 | 'csrfTokenMissing' => [ |
919 | 'errorCode' => 'csrfTokenMissing', |
920 | 'statusCode' => self::HTTP_FORBIDDEN, |
921 | 'errorMessage' => 'Відсутній CSRF токен.' |
922 | ], |
923 | 'csrfTokenInvalid' => [ |
924 | 'errorCode' => 'csrfTokenInvalid', |
925 | 'statusCode' => self::HTTP_FORBIDDEN, |
926 | 'errorMessage' => 'Недійсний CSRF токен.' |
927 | ], |
928 | 'rateLimitExceeded' => [ |
929 | 'errorCode' => 'rateLimitExceeded', |
930 | 'statusCode' => self::HTTP_TOO_MANY_REQUESTS, |
931 | 'errorMessage' => 'Перевищено ліміт запитів. Спробуйте пізніше.' |
932 | ], |
933 | 'requestEntityTooLarge' => [ |
934 | 'errorCode' => 'requestEntityTooLarge', |
935 | 'statusCode' => self::HTTP_REQUEST_ENTITY_TOO_LARGE, |
936 | 'errorMessage' => 'Тіло запиту занадто велике.' |
937 | ], |
938 | 'securityHeaderViolation' => [ |
939 | 'errorCode' => 'securityHeaderViolation', |
940 | 'statusCode' => self::HTTP_FORBIDDEN, |
941 | 'errorMessage' => 'Порушення політики безпеки.' |
942 | ] |
943 | ]; |
944 | /** |
945 | * Get an error message by key with fallback logic. |
946 | * |
947 | * @param string $key The error message key. |
948 | * @param string|null $language Optional language (default is LanguageMiddleware's default). |
949 | * @return array The error message array. |
950 | */ |
951 | public static function get(string $key, ?string $language = null): array |
952 | { |
953 | $language = LanguageMiddleware::normalizeLanguage($language); |
954 | $messages = match ($language) { |
955 | 'en' => self::EN, |
956 | 'de' => self::DE, |
957 | 'ua' => self::UA, |
958 | default => constant('self::' . strtoupper(LanguageMiddleware::getDefaultLanguage())), |
959 | }; |
960 | if (isset($messages[$key])) { |
961 | return $messages[$key]; |
962 | } |
963 | |
964 | $fallbackMessages = constant('self::' . strtoupper(LanguageMiddleware::getFallbackLanguage())); |
965 | if (isset($fallbackMessages[$key])) { |
966 | return $fallbackMessages[$key]; |
967 | } |
968 | |
969 | return match ($language) { |
970 | 'de' => [ |
971 | 'errorCode' => 'unknownError', |
972 | 'statusCode' => self::HTTP_UNKNOWN, |
973 | 'errorMessage' => 'Ein unbekannter Fehler ist aufgetreten.' |
974 | ], |
975 | 'ua' => [ |
976 | 'errorCode' => 'unknownError', |
977 | 'statusCode' => self::HTTP_UNKNOWN, |
978 | 'errorMessage' => 'Виникла невідома помилка.' |
979 | ], |
980 | default => [ |
981 | 'errorCode' => 'unknownError', |
982 | 'statusCode' => self::HTTP_UNKNOWN, |
983 | 'errorMessage' => 'An unknown error occurred.' |
984 | ], |
985 | }; |
986 | } |
987 | |
988 | /** |
989 | * Get the highest status code from an array of errors. |
990 | * |
991 | * @param array $errors Array of error messages |
992 | * @return int The highest status code found, or HTTP_OK (200) if no errors |
993 | * @throws \InvalidArgumentException If any error has an invalid structure |
994 | */ |
995 | public static function getHighestStatusCode(array $errors): int |
996 | { |
997 | if (empty($errors)) { |
998 | return self::HTTP_OK; |
999 | } |
1000 | |
1001 | $errorCodes = []; |
1002 | foreach ($errors as $error) { |
1003 | if (!is_array($error) || !isset($error['statusCode']) || !is_int($error['statusCode'])) { |
1004 | throw new \InvalidArgumentException('Invalid error structure. Each error must have a statusCode.'); |
1005 | } |
1006 | $errorCodes[] = $error['statusCode']; |
1007 | } |
1008 | |
1009 | return max($errorCodes); |
1010 | } |
1011 | } |