Issues

ZF-6509: Zend_Cache with Zend_Translate omits language label in cache filenames resulting in translations not working

Description

1)No bug with Zend Framework v1.7.2. 2)Bug with Zend Framework v1.8.0dev.

I use a very simple translate config with array adapter:

    $frontendOptions = array(
            'lifetime' => 30,
            'automatic_serialization' => true);
    // cache_dir: directory where to put the cache files
    $backendOptions = array(
            'cache_dir' => $this->_root . '/var/tmp/');
    // getting a Zend_Cache_Core object
    $this->_cache = Zend_Cache::factory(
            'Core',
            'File',
            $frontendOptions,
            $backendOptions);
    Zend_Registry::set('cache', $this->_cache);


    $english = array('title' => 'title');
    $italian= array('title' => 'titolo');
    $german= array('title' => 'Titel');

    Zend_Translate::setCache(Zend_Registry::get('cache'));
    $translate = new Zend_Translate('array', $english, 'en');
    $translate->addTranslation($italian, 'it');
    $translate->addTranslation($german, 'de');

Cache files (content of ..../var/tmp/): Case 1) : zend_cache---internal-metadatas---Zend_Translate_Array_de_Array zend_cache---internal-metadatas---Zend_Translate_Array_en_Array zend_cache---internal-metadatas---Zend_Translate_Array_it_Array zend_cache---internal-metadatas---Zend_Translate_Array_Options zend_cache---Zend_Translate_Array_de_Array zend_cache---Zend_Translate_Array_en_Array zend_cache---Zend_Translate_Array_it_Array zend_cache---Zend_Translate_Array_Options

Case 2) : zend_cache---internal-metadatas---Zend_Translate_Array_Array zend_cache---internal-metadatas---Zend_Translate_Array_Options zend_cache---Zend_Translate_Array_Array zend_cache---Zend_Translate_Array_Options

In case 2) only the first loaded translation works.

Comments

The reason for this behaviour is that you don't give a file but only the content of the file to the adapter. The cachename holds the filename (translation files are cached based on their path and filename). The old behaviour did not work for 2/3 of usecases and specially for multilingual files.

So to have it working correct there are 2 ways for you:

  • Load the array from within a file (that's ho the manual describes the array adapter)
  • Load only the one single array you want to use actually... no user needs to have a site simultanly in 2 or more languages.

Thank you very much, loading the array from within a file works perfectly.

remove Zend_Cache as affected component (not a Zend_Cache issue)

In Incubator since r16247, waiting for code review of ZF-2400

It doesn't seem right that this doesn't work anymore when you give the content to the adapter. There is an example in the manuel, to just give the data. So it should work that way also. I'm using an custom adapter that loads the data from MySQL, so I don't have a file. But now I can't cache anymore because of this change.


$english = array(
    'message1' => 'message1',
    'message2' => 'message2',
    'message3' => 'message3');

$german = array(
    'message1' => 'Nachricht1',
    'message2' => 'Nachricht2',
    'message3' => 'Nachricht3');

$translate = new Zend_Translate('array', $english, 'en');
$translate->addTranslation($deutsch, 'de');

You may have noted that this issue is marked as "in progress" which means that it's not resolved in core. You may have also noted that this issue is fixed within incubator and actually blocked by another issue.

Please read previous comment before adding a own comment. Giving someone help to make his application work should always be allowed even if it's not the fix itself.

Accepted and integrated into core with r16883.

Caching still didn't work - even when applying the above mentioned version.

We had to add the locale to the cache key to make caching work as it should:


$id = 'Zend_Translate_' . (string) $locale. '_'. md5(serialize($data)) . '_' . $this->toString();

instead of:


$id = 'Zend_Translate_' . md5(serialize($data)) . '_' . $this->toString();

in Zend_Translate_Adapter.

It helped for us, so someone else might be interested too in this fix.

Again, now with markup as it should (I hope):


$id = 'Zend_Translate_' . (string) $locale. '_'. md5(serialize($data)) . '_' . $this->toString();

instead of:


$id = 'Zend_Translate_' . md5(serialize($data)) . '_' . $this->toString();

Your proposed change re-introduces the problem that caching does not work with multilimgual translation files.

Locale and Caching must not be fixed to each other. As $data referrs to the filename/path this is the better way than using the locale. Additionally your change introduces problems when someone uses multiple files for the same locale.

Our unittests show that things work as expected with release 1.9. The problem described in this issue does no longer exist with the mentioned release.

As you said "Applying" I think that you did not use the release but only this single release. You should note that before and after that also changes occured. And changes could have been done in other components as well (Zend_Cache).

Feel free to give reproducable information that this problem is not fixed with 1.9 and we will reopen it.