fix(bring): avoid ambiguous fallback match on generic words like 'dolce'
- italianToBring(): pass-2 whole-word fallback now ignores generic qualifiers (dolce, light, classico, originale, etc.) - when multiple single-word matches exist, choose the longest/specific token instead of first catalog iteration hit - prevents wrong mappings like 'Pancetta Dolce' being interpreted via generic adjective rather than the core product token
This commit is contained in:
+15
-1
@@ -2811,18 +2811,32 @@ function italianToBring(string $italianName): string {
|
|||||||
// Uses word-boundary logic (split on spaces) to avoid substring false positives like
|
// Uses word-boundary logic (split on spaces) to avoid substring false positives like
|
||||||
// "gin" inside "original", "rum" inside "crumble", "aceto" inside "pancetta", etc.
|
// "gin" inside "original", "rum" inside "crumble", "aceto" inside "pancetta", etc.
|
||||||
// Only considers single-word catalog keys (multi-word keys need Pass 1 exact match).
|
// Only considers single-word catalog keys (multi-word keys need Pass 1 exact match).
|
||||||
|
// To avoid ambiguous mappings (e.g. "pancetta dolce" => "mais"), skip generic qualifiers
|
||||||
|
// and pick the most specific (longest) matching token.
|
||||||
$inputWords = array_filter(
|
$inputWords = array_filter(
|
||||||
preg_split('/\s+/', $lower),
|
preg_split('/\s+/', $lower),
|
||||||
fn($w) => mb_strlen($w) >= 4 // skip very short words — too ambiguous
|
fn($w) => mb_strlen($w) >= 4 // skip very short words — too ambiguous
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$genericQualifiers = [
|
||||||
|
'dolce','salato','light','bio','classico','original','naturale','fresco','fresca',
|
||||||
|
'intero','intera','magro','magra','piccolo','piccola','grande','rosso','bianco'
|
||||||
|
];
|
||||||
|
$candidates = [];
|
||||||
foreach ($catalog['it2de'] as $itLower => $deKey) {
|
foreach ($catalog['it2de'] as $itLower => $deKey) {
|
||||||
if (str_contains($itLower, ' ')) continue; // multi-word key → exact-only
|
if (str_contains($itLower, ' ')) continue; // multi-word key → exact-only
|
||||||
if (mb_strlen($itLower) < 4) continue; // too short → skip (gin, rum, etc.)
|
if (mb_strlen($itLower) < 4) continue; // too short → skip (gin, rum, etc.)
|
||||||
|
if (in_array($itLower, $genericQualifiers, true)) continue;
|
||||||
if (in_array($itLower, $inputWords, true)) {
|
if (in_array($itLower, $inputWords, true)) {
|
||||||
return $deKey;
|
$candidates[] = ['it' => $itLower, 'de' => $deKey, 'len' => mb_strlen($itLower)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!empty($candidates)) {
|
||||||
|
usort($candidates, fn($a, $b) => $b['len'] <=> $a['len']);
|
||||||
|
return $candidates[0]['de'];
|
||||||
|
}
|
||||||
|
|
||||||
// No match — return the original Italian name so Bring! shows it as a custom item
|
// No match — return the original Italian name so Bring! shows it as a custom item
|
||||||
return $italianName;
|
return $italianName;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user