@@ -11,12 +11,82 @@ class RaiAcceptService
1111 public const STATUS_CANCELED = "CANCELED " ;
1212 public const STATUS_ABANDONED = "ABANDONED " ;
1313
14+ /**
15+ * Transliteration map for non-Latin characters to Latin equivalents
16+ * Initialized once when class is loaded for optimal performance
17+ */
18+ private static array $ transliterationMap = [
19+ // Greek
20+ 'Α ' =>'A ' ,'α ' =>'a ' ,'Β ' =>'B ' ,'β ' =>'b ' ,'Γ ' =>'G ' ,'γ ' =>'g ' ,'Δ ' =>'D ' ,'δ ' =>'d ' ,
21+ 'Ε ' =>'E ' ,'ε ' =>'e ' ,'Ζ ' =>'Z ' ,'ζ ' =>'z ' ,'Η ' =>'E ' ,'η ' =>'e ' ,'Θ ' =>'Th ' ,'θ ' =>'th ' ,
22+ 'Ι ' =>'I ' ,'ι ' =>'i ' ,'Κ ' =>'K ' ,'κ ' =>'k ' ,'Λ ' =>'L ' ,'λ ' =>'l ' ,'Μ ' =>'M ' ,'μ ' =>'m ' ,
23+ 'Ν ' =>'N ' ,'ν ' =>'n ' ,'Ξ ' =>'X ' ,'ξ ' =>'x ' ,'Ο ' =>'O ' ,'ο ' =>'o ' ,'Π ' =>'P ' ,'π ' =>'p ' ,
24+ 'Ρ ' =>'R ' ,'ρ ' =>'r ' ,'Σ ' =>'S ' ,'σ ' =>'s ' ,'ς ' =>'s ' ,'Τ ' =>'T ' ,'τ ' =>'t ' ,'Υ ' =>'Y ' ,'υ ' =>'y ' ,
25+ 'Φ ' =>'Ph ' ,'φ ' =>'ph ' ,'Χ ' =>'Ch ' ,'χ ' =>'ch ' ,'Ψ ' =>'Ps ' ,'ψ ' =>'ps ' ,'Ω ' =>'O ' ,'ω ' =>'o ' ,
26+
27+ // Arabic (basic mapping for common names)
28+ 'ا ' =>'a ' ,'ب ' =>'b ' ,'ت ' =>'t ' ,'ث ' =>'th ' ,'ج ' =>'j ' ,'ح ' =>'h ' ,'خ ' =>'kh ' ,'د ' =>'d ' ,
29+ 'ذ ' =>'dh ' ,'ر ' =>'r ' ,'ز ' =>'z ' ,'س ' =>'s ' ,'ش ' =>'sh ' ,'ص ' =>'s ' ,'ض ' =>'d ' ,'ط ' =>'t ' ,
30+ 'ظ ' =>'z ' ,'ع ' =>'a ' ,'غ ' =>'gh ' ,'ف ' =>'f ' ,'ق ' =>'q ' ,'ك ' =>'k ' ,'ل ' =>'l ' ,'م ' =>'m ' ,
31+ 'ن ' =>'n ' ,'ه ' =>'h ' ,'و ' =>'w ' ,'ي ' =>'y ' ,'ء ' =>'' ,'آ ' =>'a ' ,'أ ' =>'a ' ,'إ ' =>'i ' ,
32+ 'ى ' =>'a ' ,'ة ' =>'h ' ,
33+
34+ // Hebrew
35+ 'א ' =>'' ,'ב ' =>'b ' ,'ג ' =>'g ' ,'ד ' =>'d ' ,'ה ' =>'h ' ,'ו ' =>'v ' ,'ז ' =>'z ' ,'ח ' =>'ch ' ,
36+ 'ט ' =>'t ' ,'י ' =>'y ' ,'כ ' =>'k ' ,'ך ' =>'k ' ,'ל ' =>'l ' ,'מ ' =>'m ' ,'ם ' =>'m ' ,'נ ' =>'n ' ,
37+ 'ן ' =>'n ' ,'ס ' =>'s ' ,'ע ' =>'' ,'פ ' =>'p ' ,'ף ' =>'p ' ,'צ ' =>'ts ' ,'ץ ' =>'ts ' ,'ק ' =>'k ' ,
38+ 'ר ' =>'r ' ,'ש ' =>'sh ' ,'ת ' =>'t ' ,
39+
40+ // Cyrillic
41+ 'А ' =>'A ' ,'а ' =>'a ' ,'Б ' =>'B ' ,'б ' =>'b ' ,'В ' =>'V ' ,'в ' =>'v ' ,'Г ' =>'G ' ,'г ' =>'g ' ,
42+ 'Д ' =>'D ' ,'д ' =>'d ' ,'Е ' =>'E ' ,'е ' =>'e ' ,'Ё ' =>'E ' ,'ё ' =>'e ' ,'Ж ' =>'Z ' ,'ж ' =>'z ' ,
43+ 'З ' =>'Z ' ,'з ' =>'z ' ,'И ' =>'I ' ,'и ' =>'i ' ,'Й ' =>'J ' ,'й ' =>'j ' ,'К ' =>'K ' ,'к ' =>'k ' ,
44+ 'Л ' =>'L ' ,'л ' =>'l ' ,'М ' =>'M ' ,'м ' =>'m ' ,'Н ' =>'N ' ,'н ' =>'n ' ,'О ' =>'O ' ,'о ' =>'o ' ,
45+ 'П ' =>'P ' ,'п ' =>'p ' ,'Р ' =>'R ' ,'р ' =>'r ' ,'С ' =>'S ' ,'с ' =>'s ' ,'Т ' =>'T ' ,'т ' =>'t ' ,
46+ 'У ' =>'U ' ,'у ' =>'u ' ,'Ф ' =>'F ' ,'ф ' =>'f ' ,'Х ' =>'H ' ,'х ' =>'h ' ,'Ц ' =>'C ' ,'ц ' =>'c ' ,
47+ 'Ч ' =>'Ch ' ,'ч ' =>'ch ' ,'Ш ' =>'Sh ' ,'ш ' =>'sh ' ,'Щ ' =>'Sch ' ,'щ ' =>'sch ' ,'Ъ ' =>'' ,'ъ ' =>'' ,
48+ 'Ы ' =>'Y ' ,'ы ' =>'y ' ,'Ь ' =>'' ,'ь ' =>'' ,'Э ' =>'E ' ,'э ' =>'e ' ,'Ю ' =>'Yu ' ,'ю ' =>'yu ' ,
49+ 'Я ' =>'Ya ' ,'я ' =>'ya ' ,
50+
51+ // Ukrainian
52+ 'Є ' =>'Ye ' ,'є ' =>'ye ' ,'І ' =>'I ' ,'і ' =>'i ' ,'Ї ' =>'Yi ' ,'ї ' =>'yi ' ,'Ґ ' =>'G ' ,'ґ ' =>'g ' ,
53+
54+ // Belarusian
55+ 'Ў ' =>'U ' ,'ў ' =>'u ' ,
56+
57+ // Serbian / Macedonian extras
58+ 'Ђ ' =>'Dj ' ,'ђ ' =>'dj ' ,'Љ ' =>'Lj ' ,'љ ' =>'lj ' ,'Њ ' =>'Nj ' ,'њ ' =>'nj ' ,'Ћ ' =>'C ' ,'ћ ' =>'c ' ,
59+ 'Џ ' =>'Dz ' ,'џ ' =>'dz ' ,
60+ ];
61+
1462 public static function transliterate (string $ string )
1563 {
16- $ string = transliterator_transliterate ('Any-Latin; Latin-ASCII ' , $ string );
17- return $ string ;
64+ if (function_exists ('transliterator_transliterate ' )) {
65+ $ out = transliterator_transliterate ('Any-Latin ' , $ string );
66+ if (is_string ($ out )) {
67+ return $ out ;
68+ }
69+ }
70+
71+ $ string = self ::transliterateNonLatinFallback ($ string );
72+ $ string = preg_replace ('/[^\p{Latin}\p{N}\s\.\,\- \'\/@]/u ' , '' , $ string ) ?? $ string ;
73+
74+ // 4) Normalize whitespace
75+ $ string = preg_replace ('/\s+/u ' , ' ' , $ string ) ?? $ string ;
76+
77+ return trim ($ string );
1878 }
1979
80+ private static function transliterateNonLatinFallback (string $ s ): string
81+ {
82+ // Early return for strings that only contain Latin characters and common punctuation
83+ if (!preg_match ('/[^\p{Latin}\p{N}\s\.\,\- \'\/@]/u ' , $ s )) {
84+ return $ s ;
85+ }
86+
87+ return strtr ($ s , self ::$ transliterationMap );
88+ }
89+
2090 public static function transliterate_and_limit_length (string $ string , int $ limit = 127 )
2191 {
2292 $ string = self ::transliterate ($ string );
0 commit comments