There seems to be an issue with commerce and field translation:

When creating a commerce product entity with a language selected, other than the default value 'undefined', (e.g. German) the translation table does not reflect this choice (English = original content, German = n/a) . This behavior differs from nodes. Creating a node with a defined language, say German, will be properly reflected in the translation table (German = original content, English = n/a).

product creation with a custom language

translation overview

The issue was reproduced on a clean install of Drupal, with the following modules:

Drupal core                7.10                          
Drupal Commerce            7.x-1.1                             
Chaos tool suite (ctools)  7.x-1.0-rc1                               
Devel                      7.x-1.2                      
Entity API                 7.x-1.0-rc1                              
Entity translation         7.x-1.0-alpha1                               
Internationalization       7.x-1.3                               
Module Filter              7.x-1.6                                
Rules                      7.x-2.0                                  
Variable                   7.x-1.1
Views                      7.x-3.1

Steps to reproduce the issue:

1. Add additional languages (/admin/config/regional/language/add). I added German and French, with English being the preset default.

2. Set "Commerce Product" as translatable at (/admin/config/regional/entity_translation)

3. Edit the product type (/admin/commerce/products/types/product/edit) and set "Multilingual support" to "Enabled via Entity translation".

4. Add a new field (long text) to the predefined commerce product, check "users may translate this field" at the field settings during the creation process. everything else is kept at default values.

5. Create a new product (/admin/commerce/products/add/product), select a language from the dropdown, I picked French, but any language other than default 'language neutral' and drupals default (english) will do. Then add some lore ipsum to the translatable field and save.

6. Edit the newly created product and select the 'translate' tab. (/admin/commerce/products/%PRODUCT_ID%/translate).

At this point, you should see a table that says, the Content is available in English only (original content), with no published translations.

CommentFileSizeAuthor
#6 1414554.patch805 bytesamateescu
translation_info.jpg41.22 KBcjoy
product_language.jpg28.82 KBcjoy
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

cjoy’s picture

After creating a couple of products, the issue appears worse, still. I now encountered loss of form data again (the values entered in the translatable fields) and a NOTICE is thrown:

'Notice: Undefined property: stdClass::$field_mytranslatable_field in commerce_product_ui_product_form_translation_submit() (line 540 of /commerce/modules/product/commerce_product_ui.module).'

here is the related code from commerce_product.ui.module:

<?php

/**
* Submit callback for commerce_product_ui_product_form().
*
* Checks if translation is enabled for the product and handles language changes.
* Since this handler may change the language of submitted form values it should
* be the first submit handler called.
*
* @see commerce_product_ui_form_commerce_product_ui_product_form_alter()
*/
function commerce_product_ui_product_form_translation_submit($form, &$form_state) {
  // Get an array of available languages.
  $available_languages = field_content_languages();
  list(, , $bundle) = entity_extract_ids('commerce_product', $form_state['commerce_product']);

  foreach (field_info_instances('commerce_product', $bundle) as $instance) {
    $field_name = $instance['field_name'];
    $field = field_info_field($field_name);
    $previous_language = $form[$field_name]['#language'];

    // Handle a possible language change; new language values are inserted and
    // the previous values are deleted.
    if ($field['translatable'] && $previous_language != $form_state['values']['language']) {
// ##### LINE 540: ######
      $form_state['values'][$field_name][$form_state['values']['language']] = $form_state['commerce_product']->{$field_name}[$previous_language];
      $form_state['values'][$field_name][$previous_language] = array();
    }
  }
}

looking at the assignment in line 540 with a debugger tells me this line equates to the pseudo statement below:

$form_state['values'][$field_name][$form_state['values']['language']] = $form_state['commerce_product']->{$field_name}[$previous_language];

$form_state['values']['field_test']['fr'] = [0]['value']['my translatable field value (text entered)'];

...that makes perfect sense to me - the index is undefined as it should be added... however slightly rephrasing the line does away with the loss of the value and the "undefined index" notice:

$temp = $form_state['values'][$field_name];
      $temp[$form_state['values']['language']] =  $form_state['commerce_product']->{$field_name}[$previous_language];
      $form_state['values'][$field_name] = $temp;

The issue with the translation not being registered as such as described in the first post still stands.

edit2:

On a different install base, $form_state['commerce_product']->{$field_name} is not defined.
My go at this would be to replace line 540 as follows:

old:

$temp[$form_state['values']['language']] =  
    $form_state['commerce_product']->{$field_name}[$previous_language];

new:

$form_state['values'][$field_name][$form_state['values']['language']] = 
    $form_state['values'][$field_name][$previous_language];

this seems to do away with the NOTICE and preserve the fields content (translation set still being falsly set to english though). Any downsides to this?

cjoy’s picture

miro_dietiker was kind enough to help me narrow down the issue:
the entity is always saved in the site's default language, ignoring the select value in the product creation form.
other language variables (such as the user/UI language setting) do not seem to have any (unwanted) influence here.

cjoy’s picture

I've made some progress, narrowing in on the cause by stepping through each function invoked when saving the product:

the selected language is passed on all the way, until it gets screwed over by /entity_translation/includes/translation.handler.inc:345 where the default language suddenly pops up in the debuggers var list:

  public function initTranslations() {
    $langcode = $this->getLanguage(); // returns the sites default language

    if (!empty($langcode)) {
      $translation = array('language' => $langcode, 'status' => (int) $this->getStatus());
      $this->setTranslation($translation);
      $this->setOriginalLanguage($langcode); // sets the sites default language as original language pre-save.
    }
  }

I guess there lies the problem. Instead of using the language passed along with the entity properties, the original language is always set to be the sites default. Thus the issue is probably not so much related to commerce, as it is to entity_translation.

cjoy’s picture

response by plach @ #1420572: setOriginalLanguage ignores language set in entity

ET knows nothing about entity-specific details: Commerce needs to override the DefaultEntityTranslationHandler::getLanguage() method to return the proper value.

cjoy’s picture

commerce defines a custom translation handler, but according to my debugger, the code is never actually run when saving or updating commerce_product entities.

can someone could please verify this issue?

amateescu’s picture

Title: product entity, translation set not being saved properly » Translation set not being saved properly on the product entity
Version: 7.x-1.1 » 7.x-1.x-dev
Status: Active » Needs review
FileSize
805 bytes

This was fun to track down and ended up with a *facepalm* :)

Also, while testing this patch, I came across #1253114: Notice: unserialize() [function.unserialize]: Error at offset 0 of 5 bytes, which occurred right after deleting a field translation. Applied the patch from #26 and confirmed once more that it looks to be the correct solution.

rszrama’s picture

Status: Needs review » Fixed

Nice find, guys, and thanks for documenting it so thoroughly, cjoy! Committed the fix. : )

cjoy’s picture

small patch, huge relief.
thank you ever so much!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.