From 3635e97510190926ddc8137c31293f00534a9bba Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 8 Jul 2021 11:21:34 +0200 Subject: [PATCH] PHPMailer::setLanguage(): fix "lang_country" codes do not fall back to "lang" When the `$langCode` is passed as "language code - country code" and no translation is found for the specified country variant, the localization would automatically fall back to English, even when there was a viable translation available in the "parent" language, i.e. just based on the _language code_. This commit changes the logic in the `PHPMailer::setLanguage()` method for when a "lang-country" code is passed. It will now try and find a "lang-country" file first, if not found, it will try to find a file for just the "lang" and only if that could also not be found, it will fall back to English. Related to 2418 - observation 2 Includes using named subpatterns in the regex to make the regex self-documenting. Includes removing a commented out line of code which is superseded anyway. --- src/PHPMailer.php | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/PHPMailer.php b/src/PHPMailer.php index 0742ab81..25ac1791 100644 --- a/src/PHPMailer.php +++ b/src/PHPMailer.php @@ -2251,19 +2251,32 @@ class PHPMailer //Validate $langcode $foundlang = true; $langcode = strtolower($langcode); - if (!preg_match('/^[a-z]{2}(?:_[a-z]{2})?$/', $langcode) && $langcode !== 'en') { + if (!preg_match('/^(?P[a-z]{2})(?P_[a-z]{2})?$/', $langcode, $matches) && $langcode !== 'en') { $foundlang = false; $langcode = 'en'; } - $lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php'; //There is no English translation file if ('en' !== $langcode) { - //Make sure language file path is readable - if (!static::fileIsAccessible($lang_file)) { + $langcodes = []; + if (!empty($matches['country'])) { + $langcodes[] = $matches['lang'] . $matches['country']; + } + $langcodes[] = $matches['lang']; + + //Try and find a readable language file for the requested language. + $foundFile = false; + foreach ($langcodes as $code) { + $lang_file = $lang_path . 'phpmailer.lang-' . $code . '.php'; + if (static::fileIsAccessible($lang_file)) { + $foundFile = true; + break; + } + } + + if ($foundFile === false) { $foundlang = false; } else { - //$foundlang = include $lang_file; $lines = file($lang_file); foreach ($lines as $line) { //Translation file lines look like this: