Issues

ZF-10418: Order of translation files affects runnability / key-value problem

Description

  • I have increased the priority to Blocker because this error draws my application unusable on some not avoidable conditions. *

In all releases used by me - also the most current one in the svn-trunk - there is an issue which indeterminably affects the runnability of a web application and so I have chosen to priorize it as "Critical".

The application uses three different translation-mo files (here in gettext format) - one for the forms, one for the routes and one for the main textual content (form.mo, route.mo, content.mo). Now the site runs on some systems and on some not - although all necessary extensions are loaded and settings made. The reason for this was found in the loading order of the translation-files.

Responsible for the loading order is the RecursiveDirectoryIterator (Row 244, Zend/Translate/Adapter.php).

  • The loading order is indeed system-dependent but if it affects the functionality of the framework it should / has to be considered as a bug. Please take a look at: http://bugs.php.net/bug.php?id=48881

If the loading order is reversed or different, all translated segements of the defined routes don't match anymore altough they are well-defined.

Bug reproduction: 1) Create two different gettext-translation mo-files* and call them f.ex. route.mo and content.mo *I guess it should also work with other formats than gettext. 2) In translation file A (it doesn't matter which of them is A or B) define a key-value pair (f.ex. apple => Apfel) 3) In translation file b (the other file) define a key-value where the value exists also as key in the other file (f.ex. test => apple) So we have got the following structure and content: route.mo: apple => Apfel content.mo: test => apple 4) Define some/one route(s) with translated segments where the key(s) is/are used defined before in the translation-files 5) Request the route (with your browser) 6) Now the error should occure on some systems. If it doesn't occure on your current system try to change the loading order by prefixing a number to the filenames (f.ex. 1route.mo and 2content.mo) to provoke the error.

Maybe this is even only a side-effect revealed by the loading order but I guess it is really a bug and worth investigating: I guess the main problem lies in the router.

Edit: The translation-part in the Route.php is responsible for this error: Zend/Controller/Router/Route.php; Row 251 When there are two translation files where translation file A has got a value which is used in translation file B as a key, the value is overriden with the original key.

Thank you! With best regards Inno

Comments

Please note that Zend_Translate only translates ONCE. There is no way how Zend_Translate can translate twice.

When another component calls Zend_Translate twice and tries to translate a already translated content then there is no way for Zend_Translate to recognise if the content should be translated or not translated. A call of "translate()" mean "please translate the content". So the behaviour is from point of view for Zend_Translate correct.

Change affected component from Zend_Translate to Zend_Controller. A route should not be tried to be translated twice.

Glad that this bug has been accepted. Will there be a fix soon?

You can circumvent the problem by using a separate translation adapter for the router (as DASPRiD recommended).

Bootstrap-routine example: <?php [...] class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { [...] /** * Set up routing * * @return void */ protected function _initRoutes() {
//de_DE: $route_translate = new Zend_Translate( array( 'adapter' => 'Zend_Translate_Adapter_Gettext', 'content' => LANGUAGE_PATH . 'de_DE/route.mo', 'locale' => 'de-DE' ) );

    //en_EN:
    $route_translate->addTranslation(
        array(
            'content' => LANGUAGE_PATH . 'en_US/route.mo',
            'locale'  => 'en-US'
        )
    );

    //fr_FR:
    $route_translate->addTranslation(
        array(
            'content' => LANGUAGE_PATH . 'fr_FR/route.mo',
            'locale'  => 'fr-FR'
        )
    );

    Zend_Registry::set('Route_Translate', $route_translate);

    Zend_Controller_Router_Route::setDefaultTranslator($route_translate); 
}
    [...]

} [...]

With best regards Inno