From 016afcdd62bdb04252db140f8c822b43092b2b7e Mon Sep 17 00:00:00 2001 From: Claus Due <claus@namelesscoder.net> Date: Mon, 11 Sep 2017 16:43:19 +0200 Subject: [PATCH] [TASK] Improve LocalizationUtility logic and feedback This patch does two things to improve the translation flow in LocalizationUtility::translate: * Early return null on empty $key (would cause null anyway) * Feedback message on failure to sprintf In order to provide failure feedback for formatted strings, vsprintf had to be replaced with sprintf and array unrolling, since vsprintf does not return false on errors and sprintf does. The error is returned as translation result so even if an unexpected failure occurs, at least a partially meaningful text is shown. Change-Id: I568be30b701f0c374289ed44fc5b31b13f492483 Resolves: #82453 Releases: master Reviewed-on: https://review.typo3.org/54118 Reviewed-by: Benni Mack <benni@typo3.org> Tested-by: Benni Mack <benni@typo3.org> Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch> Tested-by: Christian Kuhn <lolli@schwarzbu.ch> --- .../extbase/Classes/Utility/LocalizationUtility.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/typo3/sysext/extbase/Classes/Utility/LocalizationUtility.php b/typo3/sysext/extbase/Classes/Utility/LocalizationUtility.php index 9ebcd361f0f7..1f00f33cb4a7 100644 --- a/typo3/sysext/extbase/Classes/Utility/LocalizationUtility.php +++ b/typo3/sysext/extbase/Classes/Utility/LocalizationUtility.php @@ -64,10 +64,14 @@ class LocalizationUtility * @param string[] $alternativeLanguageKeys The alternative language keys if no translation was found. If null and we are in the frontend, then the language_alt from TypoScript setup will be used * @return string|null The value from LOCAL_LANG or null if no translation was found. * @api - * @todo : If vsprintf gets a malformed string, it returns FALSE! Should we throw an exception there? */ public static function translate($key, $extensionName = null, $arguments = null, string $languageKey = null, array $alternativeLanguageKeys = null) { + if ((string)$key === '') { + // Early return guard: returns null if the key was empty, because the key may be a dynamic value + // (from for example Fluid). Returning null allows null coalescing to a default value when that happens. + return null; + } $value = null; if (GeneralUtility::isFirstPartOfStr($key, 'LLL:')) { $keyParts = explode(':', $key); @@ -120,7 +124,10 @@ class LocalizationUtility } if (is_array($arguments) && $value !== null) { - return vsprintf($value, $arguments); + // This unrolls arguments from $arguments - instead of calling vsprintf which receives arguments as an array. + // The reason is that only sprintf() will return an error message if the number of arguments does not match + // the number of placeholders in the format string. Whereas, vsprintf would silently return nothing. + return sprintf($value, ...$arguments) ?: sprintf('Error: could not translate key "%s" with value "%s" and %d argument(s)!', $key, $value, count($arguments)); } return $value; } -- GitLab