2 namespace TYPO3\CMS\IndexedSearch\Utility;
63 public function metaphone($string, $sys_language_uid = 0)
66 return $res[
'primary'];
80 $this->secondary =
'';
83 $this->length = strlen($string);
84 $this->last = $this->length - 1;
85 $this->original = $string .
' ';
86 $this->original = strtoupper($this->original);
88 if ($this->
StringAt($this->original, 0, 2, array(
'GN',
'KN',
'PN',
'WR',
'PS'))) {
92 if ($this->original[0] ===
'X') {
93 $this->primary .=
'S';
95 $this->secondary .=
'S';
99 while (strlen($this->primary) < 4 || strlen($this->secondary < 4)) {
100 if ($this->current >= $this->length) {
103 switch (substr($this->original, $this->current, 1)) {
115 if ($this->current == 0) {
117 $this->primary .=
'A';
118 $this->secondary .=
'A';
124 $this->primary .=
'P';
125 $this->secondary .=
'P';
126 if (substr($this->original, $this->current + 1, 1) ==
'B') {
133 $this->primary .=
'S';
134 $this->secondary .=
'S';
139 if ($this->current > 1 && !$this->
IsVowel($this->original, ($this->current - 2)) && $this->
StringAt($this->original, $this->current - 1, 3, array(
'ACH')) && (substr($this->original, $this->current + 2, 1) !=
'I' && (substr($this->original, $this->current + 2, 1) !=
'E' || $this->
StringAt($this->original, $this->current - 2, 6, array(
'BACHER',
'MACHER'))))) {
140 $this->primary .=
'K';
141 $this->secondary .=
'K';
146 if ($this->current == 0 && $this->
StringAt($this->original, $this->current, 6, array(
'CAESAR'))) {
147 $this->primary .=
'S';
148 $this->secondary .=
'S';
153 if ($this->
StringAt($this->original, $this->current, 4, array(
'CHIA'))) {
154 $this->primary .=
'K';
155 $this->secondary .=
'K';
159 if ($this->
StringAt($this->original, $this->current, 2, array(
'CH'))) {
161 if ($this->current > 0 && $this->
StringAt($this->original, $this->current, 4, array(
'CHAE'))) {
162 $this->primary .=
'K';
163 $this->secondary .=
'X';
168 if ($this->current == 0 && ($this->
StringAt($this->original, $this->current + 1, 5, array(
'HARAC',
'HARIS')) || $this->
StringAt($this->original, $this->current + 1, 3, array(
'HOR',
'HYM',
'HIA',
'HEM'))) && !$this->
StringAt($this->original, 0, 5, array(
'CHORE'))) {
169 $this->primary .=
'K';
170 $this->secondary .=
'K';
175 if ($this->
StringAt($this->original, 0, 4, array(
'VAN ',
'VON ')) || $this->
StringAt($this->original, 0, 3, array(
'SCH')) || $this->
StringAt($this->original, $this->current - 2, 6, array(
'ORCHES',
'ARCHIT',
'ORCHID')) || $this->
StringAt($this->original, $this->current + 2, 1, array(
'T',
'S')) || ($this->
StringAt($this->original, $this->current - 1, 1, array(
'A',
'O',
'U',
'E')) || $this->current == 0) && $this->
StringAt($this->original, $this->current + 2, 1, array(
'L',
'R',
'N',
'M',
'B',
'H',
'F',
'V',
'W',
' '))) {
176 $this->primary .=
'K';
177 $this->secondary .=
'K';
179 if ($this->current > 0) {
180 if ($this->
StringAt($this->original, 0, 2, array(
'MC'))) {
182 $this->primary .=
'K';
183 $this->secondary .=
'K';
185 $this->primary .=
'X';
186 $this->secondary .=
'K';
189 $this->primary .=
'X';
190 $this->secondary .=
'X';
197 if ($this->
StringAt($this->original, $this->current, 2, array(
'CZ')) && !$this->
StringAt($this->original, ($this->current - 2), 4, array(
'WICZ'))) {
198 $this->primary .=
'S';
199 $this->secondary .=
'X';
204 if ($this->
StringAt($this->original, $this->current + 1, 3, array(
'CIA'))) {
205 $this->primary .=
'X';
206 $this->secondary .=
'X';
211 if ($this->
StringAt($this->original, $this->current, 2, array(
'CC')) && !($this->current == 1 && $this->original[0] ===
'M')) {
213 if ($this->
StringAt($this->original, $this->current + 2, 1, array(
'I',
'E',
'H')) && !$this->
StringAt($this->original, ($this->current + 2), 2, array(
'HU'))) {
215 if ($this->current == 1 && substr($this->original, $this->current - 1, 1) ==
'A' || $this->
StringAt($this->original, $this->current - 1, 5, array(
'UCCEE',
'UCCES'))) {
216 $this->primary .=
'KS';
217 $this->secondary .=
'KS';
219 $this->primary .=
'X';
220 $this->secondary .=
'X';
226 $this->primary .=
'K';
227 $this->secondary .=
'K';
232 if ($this->
StringAt($this->original, $this->current, 2, array(
'CK',
'CG',
'CQ'))) {
233 $this->primary .=
'K';
234 $this->secondary .=
'K';
238 if ($this->
StringAt($this->original, $this->current, 2, array(
'CI',
'CE',
'CY'))) {
240 if ($this->
StringAt($this->original, $this->current, 3, array(
'CIO',
'CIE',
'CIA'))) {
241 $this->primary .=
'S';
242 $this->secondary .=
'X';
244 $this->primary .=
'S';
245 $this->secondary .=
'S';
251 $this->primary .=
'K';
252 $this->secondary .=
'K';
254 if ($this->
StringAt($this->original, $this->current + 1, 2, array(
' C',
' Q',
' G'))) {
257 if ($this->
StringAt($this->original, $this->current + 1, 1, array(
'C',
'K',
'Q')) && !$this->
StringAt($this->original, ($this->current + 1), 2, array(
'CE',
'CI'))) {
265 if ($this->
StringAt($this->original, $this->current, 2, array(
'DG'))) {
266 if ($this->
StringAt($this->original, $this->current + 2, 1, array(
'I',
'E',
'Y'))) {
268 $this->primary .=
'J';
269 $this->secondary .=
'J';
274 $this->primary .=
'TK';
275 $this->secondary .=
'TK';
280 if ($this->
StringAt($this->original, $this->current, 2, array(
'DT',
'DD'))) {
281 $this->primary .=
'T';
282 $this->secondary .=
'T';
287 $this->primary .=
'T';
288 $this->secondary .=
'T';
292 if (substr($this->original, $this->current + 1, 1) ==
'F') {
297 $this->primary .=
'F';
298 $this->secondary .=
'F';
301 if (substr($this->original, $this->current + 1, 1) ==
'H') {
302 if ($this->current > 0 && !$this->
IsVowel($this->original, ($this->current - 1))) {
303 $this->primary .=
'K';
304 $this->secondary .=
'K';
308 if ($this->current < 3) {
310 if ($this->current == 0) {
311 if (substr($this->original, $this->current + 2, 1) ==
'I') {
312 $this->primary .=
'J';
313 $this->secondary .=
'J';
315 $this->primary .=
'K';
316 $this->secondary .=
'K';
323 if ($this->current > 1 && $this->
StringAt($this->original, $this->current - 2, 1, array(
'B',
'H',
'D')) || $this->current > 2 && $this->
StringAt($this->original, $this->current - 3, 1, array(
'B',
'H',
'D')) || $this->current > 3 && $this->
StringAt($this->original, $this->current - 4, 1, array(
'B',
'H'))) {
328 if ($this->current > 2 && substr($this->original, $this->current - 1, 1) ==
'U' && $this->
StringAt($this->original, $this->current - 3, 1, array(
'C',
'G',
'L',
'R',
'T'))) {
329 $this->primary .=
'F';
330 $this->secondary .=
'F';
331 }
elseif ($this->current > 0 && substr($this->original, $this->current - 1, 1) !=
'I') {
332 $this->primary .=
'K';
333 $this->secondary .=
'K';
339 if (substr($this->original, $this->current + 1, 1) ==
'N') {
340 if ($this->current == 1 && $this->
IsVowel($this->original, 0) && !$this->
SlavoGermanic($this->original)) {
341 $this->primary .=
'KN';
342 $this->secondary .=
'N';
345 if (!$this->
StringAt($this->original, ($this->current + 2), 2, array(
'EY')) && substr($this->original, $this->current + 1) !=
'Y' && !$this->
SlavoGermanic($this->original)) {
346 $this->primary .=
'N';
347 $this->secondary .=
'KN';
349 $this->primary .=
'KN';
350 $this->secondary .=
'KN';
357 if ($this->
StringAt($this->original, $this->current + 1, 2, array(
'LI')) && !$this->
SlavoGermanic($this->original)) {
358 $this->primary .=
'KL';
359 $this->secondary .=
'L';
364 if ($this->current == 0 && (substr($this->original, $this->current + 1, 1) ==
'Y' || $this->
StringAt($this->original, $this->current + 1, 2, array(
377 $this->primary .=
'K';
378 $this->secondary .=
'J';
383 if (($this->
StringAt($this->original, $this->current + 1, 2, array(
'ER')) || substr($this->original, $this->current + 1, 1) ==
'Y') && !$this->
StringAt($this->original, 0, 6, array(
'DANGER',
'RANGER',
'MANGER')) && !$this->
StringAt($this->original, ($this->current - 1), 1, array(
'E',
'I')) && !$this->
StringAt($this->original, ($this->current - 1), 3, array(
'RGY',
'OGY'))) {
384 $this->primary .=
'K';
385 $this->secondary .=
'J';
390 if ($this->
StringAt($this->original, $this->current + 1, 1, array(
'E',
'I',
'Y')) || $this->
StringAt($this->original, $this->current - 1, 4, array(
'AGGI',
'OGGI'))) {
392 if ($this->
StringAt($this->original, 0, 4, array(
'VAN ',
'VON ')) || $this->
StringAt($this->original, 0, 3, array(
'SCH')) || $this->
StringAt($this->original, $this->current + 1, 2, array(
'ET'))) {
393 $this->primary .=
'K';
394 $this->secondary .=
'K';
397 if ($this->
StringAt($this->original, $this->current + 1, 4, array(
'IER '))) {
398 $this->primary .=
'J';
399 $this->secondary .=
'J';
401 $this->primary .=
'J';
402 $this->secondary .=
'K';
408 if (substr($this->original, $this->current + 1, 1) ==
'G') {
413 $this->primary .=
'K';
414 $this->secondary .=
'K';
418 if (($this->current == 0 || $this->
IsVowel($this->original, $this->current - 1)) && $this->
IsVowel($this->original, $this->current + 1)) {
419 $this->primary .=
'H';
420 $this->secondary .=
'H';
428 if ($this->
StringAt($this->original, $this->current, 4, array(
'JOSE')) || $this->
StringAt($this->original, 0, 4, array(
'SAN '))) {
429 if ($this->current == 0 && substr($this->original, $this->current + 4, 1) ==
' ' || $this->
StringAt($this->original, 0, 4, array(
'SAN '))) {
430 $this->primary .=
'H';
431 $this->secondary .=
'H';
433 $this->primary .=
'J';
434 $this->secondary .=
'H';
439 if ($this->current == 0 && !$this->
StringAt($this->original, $this->current, 4, array(
'JOSE'))) {
440 $this->primary .=
'J';
442 $this->secondary .=
'A';
445 if ($this->
IsVowel($this->original, $this->current - 1) && !$this->
SlavoGermanic($this->original) && (substr($this->original, $this->current + 1, 1) ==
'A' || substr($this->original, $this->current + 1, 1) ==
'O')) {
446 $this->primary .=
'J';
447 $this->secondary .=
'H';
449 if ($this->current == $this->last) {
450 $this->primary .=
'J';
451 $this->secondary .=
'';
453 if (!$this->
StringAt($this->original, ($this->current + 1), 1, array(
'L',
'T',
'K',
'S',
'N',
'M',
'B',
'Z')) && !$this->
StringAt($this->original, ($this->current - 1), 1, array(
'S',
'K',
'L'))) {
454 $this->primary .=
'J';
455 $this->secondary .=
'J';
460 if (substr($this->original, $this->current + 1, 1) ==
'J') {
468 if (substr($this->original, $this->current + 1, 1) ==
'K') {
473 $this->primary .=
'K';
474 $this->secondary .=
'K';
477 if (substr($this->original, $this->current + 1, 1) ==
'L') {
479 if ($this->current == $this->length - 3 && $this->
StringAt($this->original, $this->current - 1, 4, array(
'ILLO',
'ILLA',
'ALLE')) || ($this->
StringAt($this->original, $this->last - 1, 2, array(
'AS',
'OS')) || $this->
StringAt($this->original, $this->last, 1, array(
'A',
'O'))) && $this->
StringAt($this->original, $this->current - 1, 4, array(
'ALLE'))) {
480 $this->primary .=
'L';
481 $this->secondary .=
'';
489 $this->primary .=
'L';
490 $this->secondary .=
'L';
493 if ($this->
StringAt($this->original, $this->current - 1, 3, array(
'UMB')) && ($this->current + 1 == $this->last || $this->
StringAt($this->original, $this->current + 2, 2, array(
'ER'))) || substr($this->original, $this->current + 1, 1) ==
'M') {
498 $this->primary .=
'M';
499 $this->secondary .=
'M';
502 if (substr($this->original, $this->current + 1, 1) ==
'N') {
507 $this->primary .=
'N';
508 $this->secondary .=
'N';
512 $this->primary .=
'N';
513 $this->secondary .=
'N';
516 if (substr($this->original, $this->current + 1, 1) ==
'H') {
518 $this->primary .=
'F';
519 $this->secondary .=
'F';
523 if ($this->
StringAt($this->original, $this->current + 1, 1, array(
'P',
'B'))) {
528 $this->primary .=
'P';
529 $this->secondary .=
'P';
532 if (substr($this->original, $this->current + 1, 1) ==
'Q') {
537 $this->primary .=
'K';
538 $this->secondary .=
'K';
542 if ($this->current == $this->last && !$this->
SlavoGermanic($this->original) && $this->
StringAt($this->original, $this->current - 2, 2, array(
'IE')) && !$this->
StringAt($this->original, ($this->current - 4), 2, array(
'ME',
'MA'))) {
543 $this->primary .=
'';
544 $this->secondary .=
'R';
546 $this->primary .=
'R';
547 $this->secondary .=
'R';
549 if (substr($this->original, $this->current + 1, 1) ==
'R') {
557 if ($this->
StringAt($this->original, $this->current - 1, 3, array(
'ISL',
'YSL'))) {
562 if ($this->current == 0 && $this->
StringAt($this->original, $this->current, 5, array(
'SUGAR'))) {
563 $this->primary .=
'X';
564 $this->secondary .=
'S';
568 if ($this->
StringAt($this->original, $this->current, 2, array(
'SH'))) {
570 if ($this->
StringAt($this->original, $this->current + 1, 4, array(
'HEIM',
'HOEK',
'HOLM',
'HOLZ'))) {
571 $this->primary .=
'S';
572 $this->secondary .=
'S';
574 $this->primary .=
'X';
575 $this->secondary .=
'X';
581 if ($this->
StringAt($this->original, $this->current, 3, array(
'SIO',
'SIA')) || $this->
StringAt($this->original, $this->current, 4, array(
'SIAN'))) {
583 $this->primary .=
'S';
584 $this->secondary .=
'X';
586 $this->primary .=
'S';
587 $this->secondary .=
'S';
594 if ($this->current == 0 && $this->
StringAt($this->original, $this->current + 1, 1, array(
'M',
'N',
'L',
'W')) || $this->
StringAt($this->original, $this->current + 1, 1, array(
'Z'))) {
595 $this->primary .=
'S';
596 $this->secondary .=
'X';
597 if ($this->
StringAt($this->original, $this->current + 1, 1, array(
'Z'))) {
604 if ($this->
StringAt($this->original, $this->current, 2, array(
'SC'))) {
606 if (substr($this->original, $this->current + 2, 1) ==
'H') {
608 if ($this->
StringAt($this->original, $this->current + 3, 2, array(
'OO',
'ER',
'EN',
'UY',
'ED',
'EM'))) {
610 if ($this->
StringAt($this->original, $this->current + 3, 2, array(
'ER',
'EN'))) {
611 $this->primary .=
'X';
612 $this->secondary .=
'SK';
614 $this->primary .=
'SK';
615 $this->secondary .=
'SK';
620 if ($this->current == 0 && !$this->
IsVowel($this->original, 3) && substr($this->original, $this->current + 3, 1) !=
'W') {
621 $this->primary .=
'X';
622 $this->secondary .=
'S';
624 $this->primary .=
'X';
625 $this->secondary .=
'X';
631 if ($this->
StringAt($this->original, $this->current + 2, 1, array(
'I',
'E',
'Y'))) {
632 $this->primary .=
'S';
633 $this->secondary .=
'S';
638 $this->primary .=
'SK';
639 $this->secondary .=
'SK';
644 if ($this->current == $this->last && $this->
StringAt($this->original, $this->current - 2, 2, array(
'AI',
'OI'))) {
645 $this->primary .=
'';
646 $this->secondary .=
'S';
648 $this->primary .=
'S';
649 $this->secondary .=
'S';
651 if ($this->
StringAt($this->original, $this->current + 1, 1, array(
'S',
'Z'))) {
658 if ($this->
StringAt($this->original, $this->current, 4, array(
'TION'))) {
659 $this->primary .=
'X';
660 $this->secondary .=
'X';
664 if ($this->
StringAt($this->original, $this->current, 3, array(
'TIA',
'TCH'))) {
665 $this->primary .=
'X';
666 $this->secondary .=
'X';
670 if ($this->
StringAt($this->original, $this->current, 2, array(
'TH')) || $this->
StringAt($this->original, $this->current, 3, array(
'TTH'))) {
672 if ($this->
StringAt($this->original, $this->current + 2, 2, array(
'OM',
'AM')) || $this->
StringAt($this->original, 0, 4, array(
'VAN ',
'VON ')) || $this->
StringAt($this->original, 0, 3, array(
'SCH'))) {
673 $this->primary .=
'T';
674 $this->secondary .=
'T';
676 $this->primary .=
'0';
677 $this->secondary .=
'T';
682 if ($this->
StringAt($this->original, $this->current + 1, 1, array(
'T',
'D'))) {
687 $this->primary .=
'T';
688 $this->secondary .=
'T';
691 if (substr($this->original, $this->current + 1, 1) ==
'V') {
696 $this->primary .=
'F';
697 $this->secondary .=
'F';
701 if ($this->
StringAt($this->original, $this->current, 2, array(
'WR'))) {
702 $this->primary .=
'R';
703 $this->secondary .=
'R';
707 if ($this->current == 0 && ($this->
IsVowel($this->original, $this->current + 1) || $this->
StringAt($this->original, $this->current, 2, array(
'WH')))) {
709 if ($this->
IsVowel($this->original, $this->current + 1)) {
710 $this->primary .=
'A';
711 $this->secondary .=
'F';
714 $this->primary .=
'A';
715 $this->secondary .=
'A';
719 if ($this->current == $this->last && $this->
IsVowel($this->original, $this->current - 1) || $this->
StringAt($this->original, $this->current - 1, 5, array(
'EWSKI',
'EWSKY',
'OWSKI',
'OWSKY')) || $this->
StringAt($this->original, 0, 3, array(
'SCH'))) {
720 $this->primary .=
'';
721 $this->secondary .=
'F';
726 if ($this->
StringAt($this->original, $this->current, 4, array(
'WICZ',
'WITZ'))) {
727 $this->primary .=
'TS';
728 $this->secondary .=
'FX';
737 if (!($this->current == $this->last && ($this->
StringAt($this->original, $this->current - 3, 3, array(
'IAU',
'EAU')) || $this->
StringAt($this->original, $this->current - 2, 2, array(
'AU',
'OU'))))) {
738 $this->primary .=
'KS';
739 $this->secondary .=
'KS';
741 if ($this->
StringAt($this->original, $this->current + 1, 1, array(
'C',
'X'))) {
749 if (substr($this->original, $this->current + 1, 1) ==
'H') {
750 $this->primary .=
'J';
751 $this->secondary .=
'J';
754 }
elseif ($this->
StringAt($this->original, $this->current + 1, 2, array(
'ZO',
'ZI',
'ZA')) || $this->
SlavoGermanic($this->original) && ($this->current > 0 && substr($this->original, $this->current - 1, 1) !=
'T')) {
755 $this->primary .=
'S';
756 $this->secondary .=
'TS';
758 $this->primary .=
'S';
759 $this->secondary .=
'S';
761 if (substr($this->original, $this->current + 1, 1) ==
'Z') {
772 $this->primary = substr($this->primary, 0, 4);
773 $this->secondary = substr($this->secondary, 0, 4);
792 if ($start < 0 || $start >= strlen($string)) {
795 $listCount = count(
$list);
796 for ($i = 0; $i < $listCount; $i++) {
813 return preg_match(
'/[AEIOUY]/', substr($string, $pos, 1));
824 return preg_match(
'/W|K|CZ|WITZ/', $string);