ZF-3305: Flaw in file scanning
We found some unexpected behaviour with Zend Translate today. In our dev environment, we had no problem, but as soon as we moved to production, we had an exception: "Internal error :Language (en_CA) has to be added before it can be used." We use the Gettext adapter using 'scan' => Zend_Translate::LOCALE_FILENAME.
It's a bit complicated so please bear with me, but here is how we managed to discover the bug: the locale "en_CA" indeed did not exist: we have en_US.mo and fr_FR.mo in our locale directory. Yet in dev, it had always worked. After using the Zend Studio Debugger to dig pretty deep within Zend_Translate_Adapter, we saw that the file scan also read our hidden .svn files and directories. Of course, those files are not present in prod, so the behaviour was different.
On lines 123-127 of Zend/Translate/Adapter.php, in our dev environment: - the file iterator finds a file such as "en_US.mo.svn-base" in a directory such as "locale/.svn/text-base/" - it removes the last element after the period (lines 123-124), $filename becomes "en_US.mo" - Zend_Locale::isLocale (line 126) determines that "en_US.mo" is not a real locale, but the first part of the string before the underscore is and keeps that ("en"). So the $locale is now "en". Then on line 146, we have $this->_addTranslationData("locale/.svn/text-base/en_US.mo.svn-base", "en"): the hidden .svn file is indeed a valid .mo file (I don't know much about the internal working of svn but it's no doubt a svn cache file identical to the latest actual file), but it's loaded into the "en" locale of $this->_locale.
So our application ends up loading the hidden svn file for en_US into the "en" locale, and since en_CA does not exist, it takes "en" instead which is indeed loaded in the _translate array. Which, I'll remind you, contains en_US translations from the en_US.mo.svn-base file!
However, in production, since we don't have the svn file, neither the "en_CA" nor the defaulting "en" .mo files are found, so an Exception is thrown instead.
I realise this is obscure and possibly difficult to reproduce, but my suggestion would be to change the file-scanning behaviour to ignore hidden files (files that start with a period), or at least add the option to ignore it. Of course on our end we can patch our production environment to have a default en.mo file or to catch the Exception, but the fact remains that the code behaviour is different depending on the environment, and that's a Bad Thing. :) Since many development teams use svn, I find it plausible that this problem could affect many more people and there's really no reason why the file scanner should read hidden files, is there?