phptal / PHPTAL

PHP Template Attribute Language — template engine for XSS-proof well-formed XHTML and HTML5 pages
http://phptal.org
GNU Lesser General Public License v2.1
175 stars 43 forks source link

setLanguage throws error with empty strings. #70

Open adjenks opened 5 years ago

adjenks commented 5 years ago

This code:

$TALTranslator = new \PHPTAL_GetTextTranslator();
$TALTranslator->addDomain('mydomain', './locale');
$TALTranslator->useDomain('mydomain');
$TALTranslator->setLanguage('', 'en_US'); // Empty string as first argument

Will throw this exception:

Language(s) code(s) ", en_US" not supported by your system.

Looks like some sort of strange string concatenation problem as indicated by the leading comma in the list of languages in the error.

adjenks commented 5 years ago

BTW, thank you, to all of the maintainers of this library. I appreciate your work.

Ocramius commented 5 years ago

I'd say that this is the correct behaviour, since '' is not a language. UX for the exception can be improved, maybe, but an empty string should very much lead to a thrown error.

adjenks commented 5 years ago

I think it should just fallback to 'en_US' because if I write: $TALTranslator->setLanguage('potato', 'en_US'); it still works, because it falls back to 'en_US'.

However when setLanguage() calls trySettingLanguages(LC_ALL, ['','en_US']), trySettingLanguages() returns an empty string and setLanguage() casts the empty string to false here:

$langCode = $this->trySettingLanguages(LC_MESSAGES, $langs);
if ($langCode) return $langCode;

trySettingLanguages() returns en empty string because it returns the original string, not the one output by setlocale(), as seen below:

    private function trySettingLanguages($category, array $langs)
    {
        foreach ($langs as $langCode) {
            putenv("LANG=$langCode");
            putenv("LC_ALL=$langCode");
            putenv("LANGUAGE=$langCode");
            if (setlocale($category, $langCode)) {
                return $langCode;
            }
        }
        return null;
    }

On my system, var_export(setlocale(LC_ALL,'')); outputs "en_CA", so an empty string appears to return the currently set locale, as does passing it null as the second argument.

If you read the php docs, it states:

The return value of setlocale() depends on the system that PHP is running. It returns exactly what the system setlocale function returns.

So it may vary. Personally I would like PHPTAL to not throw an error, because setlocale does not throw an error.