From 00cc89a049b06cd4f246d327c203a3184bbf1379 Mon Sep 17 00:00:00 2001
From: Pedro Cambra <pedro.cambra@gmail.com>
Date: Wed, 23 Mar 2011 11:44:39 +0100
Subject: [PATCH] Issue #1032302 by das-peter, rfay,  bojanz, pcambra: Integrate translation handler for commerce products.

---
 ...-integrate-translation-handler-1032302-10.patch |  222 ++++++++++++++++++++
 modules/product/commerce_product.info              |    3 +
 modules/product/commerce_product_ui.module         |   65 ++++++
 .../includes/commerce_product.controller.inc       |    1 +
 .../product/includes/commerce_product.forms.inc    |    9 +-
 .../translation.handler.commerce_product.inc       |   55 +++++
 6 files changed, 354 insertions(+), 1 deletions(-)
 create mode 100644 commerce-integrate-translation-handler-1032302-10.patch
 create mode 100644 modules/product/includes/translation.handler.commerce_product.inc

diff --git a/commerce-integrate-translation-handler-1032302-10.patch b/commerce-integrate-translation-handler-1032302-10.patch
new file mode 100644
index 0000000..b7ca76a
--- /dev/null
+++ b/commerce-integrate-translation-handler-1032302-10.patch
@@ -0,0 +1,222 @@
+From bddcb3289ba1f04a009369e405a56754dd69df2f Mon Sep 17 00:00:00 2001
+From: Pedro Cambra <pedro.cambra@gmail.com>
+Date: Wed, 23 Mar 2011 11:40:55 +0100
+Subject: [PATCH] Issue #1032302 by das-peter, fray,  bojanz, pcambra: Integrate translation handler for commerce products.
+
+---
+ modules/product/commerce_product.info              |    3 +
+ modules/product/commerce_product_ui.module         |   65 ++++++++++++++++++++
+ .../includes/commerce_product.controller.inc       |    1 +
+ .../product/includes/commerce_product.forms.inc    |    9 +++-
+ .../translation.handler.commerce_product.inc       |   55 +++++++++++++++++
+ 5 files changed, 132 insertions(+), 1 deletions(-)
+ create mode 100644 modules/product/includes/translation.handler.commerce_product.inc
+
+diff --git a/modules/product/commerce_product.info b/modules/product/commerce_product.info
+index 6a20cd0..036fdf0 100644
+--- a/modules/product/commerce_product.info
++++ b/modules/product/commerce_product.info
+@@ -20,3 +20,6 @@ files[] = includes/views/handlers/commerce_product_handler_filter_product_type.i
+ 
+ ; Simple tests
+ files[] = tests/commerce_product.test
++
++; Translation handler
++files[] = includes/translation.handler.commerce_product.inc
+diff --git a/modules/product/commerce_product_ui.module b/modules/product/commerce_product_ui.module
+index d961dde..648ec15 100644
+--- a/modules/product/commerce_product_ui.module
++++ b/modules/product/commerce_product_ui.module
+@@ -452,6 +452,20 @@ function commerce_product_ui_form_commerce_product_ui_product_form_alter(&$form,
+   // Add a submit handler to the save button to add a redirect.
+   $form['actions']['submit']['#submit'][] = 'commerce_product_ui_product_form_submit';
+ 
++  // If translation support is enabled - provide the suitable languages
++  if (module_exists('entity_translation') && function_exists('entity_translation_enabled') && entity_translation_enabled('commerce_product')) {
++  	$form['language'] = array(
++      '#type' => 'select',
++      '#title' => t('Language'),
++      '#default_value' => (isset($form_state['commerce_product']->language) ? $form_state['commerce_product']->language : ''),
++      '#options' => array(LANGUAGE_NONE => t('Language neutral')) + locale_language_list('name'),
++      '#weight' => -10,
++    );
++    // Since this function may changes the language of the submitted form
++    // values it has to be the first called.
++    array_unshift($form['actions']['submit']['#submit'], 'commerce_product_ui_product_form_translation_processing');
++  }
++
+   // Add the save and continue button for new products.
+   if (empty($form_state['commerce_product']->product_id)) {
+     $form['actions']['save_continue'] = array(
+@@ -483,6 +497,34 @@ function commerce_product_ui_product_form_submit($form, &$form_state) {
+ }
+ 
+ /**
++ * Special submit callback for commerce_product_ui_product_form().
++ *
++ * Checks if translation is enabled and handle possible language changes.
++ * Since this handler may changes the language of submitted form values it
++ * should be invoked as the first submit handler.
++ */
++function commerce_product_ui_product_form_translation_processing($form, &$form_state) {
++  // If translation support is enabled - make sure language changes are handled.
++  if (module_exists('translation') && function_exists('entity_translation_enabled') && entity_translation_enabled('commerce_product')) {
++    $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,
++      // previous ones are deleted.
++      if ($field['translatable'] && $previous_language != $form_state['values']['language']) {
++        $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();
++      }
++    }
++  }
++}
++
++/**
+  * Implements hook_form_FORM_ID_alter().
+  *
+  * The Product UI module instantiates the Product delete form at a particular
+@@ -536,3 +578,26 @@ function commerce_product_ui_set_breadcrumb($product_types = FALSE) {
+ 
+   drupal_set_breadcrumb($breadcrumb);
+ }
++
++/**
++ * Implements hook_translation_info().
++ *
++ * Translation handler is already registered in the commerce_product module.
++ * @see includes/translation.handler.commerce_product.inc
++ */
++function commerce_product_ui_translation_info($types = NULL) {
++  $info = array();
++
++  $info['commerce_product'] = array(
++    'translation' => array(
++      'entity_translation' => array(
++        'class' => 'EntityTranslationCommerceProductHandler',
++        'base path' => 'admin/commerce/products/%commerce_product',
++        'access callback' => 'commerce_product_access',
++        'access arguments' => array('update', 3),
++        'edit form' => TRUE,
++      ),
++    ),
++  );
++  return $info;
++}
+diff --git a/modules/product/includes/commerce_product.controller.inc b/modules/product/includes/commerce_product.controller.inc
+index 6b80cff..4e200c2 100644
+--- a/modules/product/includes/commerce_product.controller.inc
++++ b/modules/product/includes/commerce_product.controller.inc
+@@ -31,6 +31,7 @@ class CommerceProductEntityController extends DrupalDefaultEntityController {
+       'status' => 1,
+       'created' => '',
+       'changed' => '',
++      'language' => LANGUAGE_NONE,
+     );
+   }
+ 
+diff --git a/modules/product/includes/commerce_product.forms.inc b/modules/product/includes/commerce_product.forms.inc
+index 5eb6ce8..4513629 100644
+--- a/modules/product/includes/commerce_product.forms.inc
++++ b/modules/product/includes/commerce_product.forms.inc
+@@ -40,7 +40,7 @@ function commerce_product_product_form($form, &$form_state, $product) {
+ 
+   // Add the field related form elements.
+   $form_state['commerce_product'] = $product;
+-  field_attach_form('commerce_product', $product, $form, $form_state);
++  field_attach_form('commerce_product', $product, $form, $form_state, $product->language);
+ 
+   $form['status'] = array(
+     '#type' => 'radios',
+@@ -61,6 +61,12 @@ function commerce_product_product_form($form, &$form_state, $product) {
+     '#weight' => 400,
+   );
+ 
++  // Simply use default language
++  $form['language'] = array(
++    '#type' => 'value',
++    '#value' => $product->language,
++  );
++
+   // We add the form's #submit array to this button along with the actual submit
+   // handler to preserve any submit handlers added by a form callback_wrapper.
+   $submit = array();
+@@ -122,6 +128,7 @@ function commerce_product_product_form_submit($form, &$form_state) {
+   $product->sku = $form_state['values']['sku'];
+   $product->title = $form_state['values']['title'];
+   $product->status = $form_state['values']['status'];
++  $product->language = $form_state['values']['language'];
+ 
+   // Set the product's uid if it's being created at this time.
+   if (empty($product->product_id)) {
+diff --git a/modules/product/includes/translation.handler.commerce_product.inc b/modules/product/includes/translation.handler.commerce_product.inc
+new file mode 100644
+index 0000000..e8ee130
+--- /dev/null
++++ b/modules/product/includes/translation.handler.commerce_product.inc
+@@ -0,0 +1,55 @@
++<?php
++// $Id$
++
++/**
++ * @file
++ * Commerce product translation handler for the translation module.
++ */
++
++
++/**
++ * Commerce product translation handler.
++ *
++ * Override the default behaviours to provide the needed commerce product
++ * properties.
++ *
++ * This class is registered in the commerce_product_ui.module. If you want to
++ * use it without the commerce_product_ui.module make sure you register it
++ * on your own by using hook_translation_info().
++ * @see hook_translation_info()
++ * @see commerce_product_ui.module
++ */
++class EntityTranslationCommerceProductHandler extends EntityTranslationDefaultHandler {
++
++  public function __construct($entity_type, $entity_info, $entity, $entity_id) {
++    parent::__construct('commerce_product', $entity_info, $entity, $entity_id);
++  }
++
++  /**
++   * Indicates whether this commerce product is a revision or not.
++   */
++  public function isRevision() {
++    return !empty($this->entity->revision);
++  }
++
++  /**
++   * Returns the original language of the commerce product.
++   */
++  public function getLanguage() {
++    return $this->entity->language;
++  }
++
++  /**
++   * Checks whether the current user has access to this commerce product.
++   */
++  public function getAccess($op) {
++    return commerce_product_access($op, $this->entity);
++  }
++
++  /**
++   * Returns whether the commerce product is active (TRUE) or disabled (FALSE).
++   */
++  protected function getStatus() {
++    return (boolean) $this->entity->status;
++  }
++}
+-- 
+1.7.3.3
+
diff --git a/modules/product/commerce_product.info b/modules/product/commerce_product.info
index 6a20cd0..036fdf0 100644
--- a/modules/product/commerce_product.info
+++ b/modules/product/commerce_product.info
@@ -20,3 +20,6 @@ files[] = includes/views/handlers/commerce_product_handler_filter_product_type.i
 
 ; Simple tests
 files[] = tests/commerce_product.test
+
+; Translation handler
+files[] = includes/translation.handler.commerce_product.inc
diff --git a/modules/product/commerce_product_ui.module b/modules/product/commerce_product_ui.module
index d961dde..648ec15 100644
--- a/modules/product/commerce_product_ui.module
+++ b/modules/product/commerce_product_ui.module
@@ -452,6 +452,20 @@ function commerce_product_ui_form_commerce_product_ui_product_form_alter(&$form,
   // Add a submit handler to the save button to add a redirect.
   $form['actions']['submit']['#submit'][] = 'commerce_product_ui_product_form_submit';
 
+  // If translation support is enabled - provide the suitable languages
+  if (module_exists('entity_translation') && function_exists('entity_translation_enabled') && entity_translation_enabled('commerce_product')) {
+  	$form['language'] = array(
+      '#type' => 'select',
+      '#title' => t('Language'),
+      '#default_value' => (isset($form_state['commerce_product']->language) ? $form_state['commerce_product']->language : ''),
+      '#options' => array(LANGUAGE_NONE => t('Language neutral')) + locale_language_list('name'),
+      '#weight' => -10,
+    );
+    // Since this function may changes the language of the submitted form
+    // values it has to be the first called.
+    array_unshift($form['actions']['submit']['#submit'], 'commerce_product_ui_product_form_translation_processing');
+  }
+
   // Add the save and continue button for new products.
   if (empty($form_state['commerce_product']->product_id)) {
     $form['actions']['save_continue'] = array(
@@ -483,6 +497,34 @@ function commerce_product_ui_product_form_submit($form, &$form_state) {
 }
 
 /**
+ * Special submit callback for commerce_product_ui_product_form().
+ *
+ * Checks if translation is enabled and handle possible language changes.
+ * Since this handler may changes the language of submitted form values it
+ * should be invoked as the first submit handler.
+ */
+function commerce_product_ui_product_form_translation_processing($form, &$form_state) {
+  // If translation support is enabled - make sure language changes are handled.
+  if (module_exists('translation') && function_exists('entity_translation_enabled') && entity_translation_enabled('commerce_product')) {
+    $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,
+      // previous ones are deleted.
+      if ($field['translatable'] && $previous_language != $form_state['values']['language']) {
+        $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();
+      }
+    }
+  }
+}
+
+/**
  * Implements hook_form_FORM_ID_alter().
  *
  * The Product UI module instantiates the Product delete form at a particular
@@ -536,3 +578,26 @@ function commerce_product_ui_set_breadcrumb($product_types = FALSE) {
 
   drupal_set_breadcrumb($breadcrumb);
 }
+
+/**
+ * Implements hook_translation_info().
+ *
+ * Translation handler is already registered in the commerce_product module.
+ * @see includes/translation.handler.commerce_product.inc
+ */
+function commerce_product_ui_translation_info($types = NULL) {
+  $info = array();
+
+  $info['commerce_product'] = array(
+    'translation' => array(
+      'entity_translation' => array(
+        'class' => 'EntityTranslationCommerceProductHandler',
+        'base path' => 'admin/commerce/products/%commerce_product',
+        'access callback' => 'commerce_product_access',
+        'access arguments' => array('update', 3),
+        'edit form' => TRUE,
+      ),
+    ),
+  );
+  return $info;
+}
diff --git a/modules/product/includes/commerce_product.controller.inc b/modules/product/includes/commerce_product.controller.inc
index 6b80cff..4e200c2 100644
--- a/modules/product/includes/commerce_product.controller.inc
+++ b/modules/product/includes/commerce_product.controller.inc
@@ -31,6 +31,7 @@ class CommerceProductEntityController extends DrupalDefaultEntityController {
       'status' => 1,
       'created' => '',
       'changed' => '',
+      'language' => LANGUAGE_NONE,
     );
   }
 
diff --git a/modules/product/includes/commerce_product.forms.inc b/modules/product/includes/commerce_product.forms.inc
index 5eb6ce8..4513629 100644
--- a/modules/product/includes/commerce_product.forms.inc
+++ b/modules/product/includes/commerce_product.forms.inc
@@ -40,7 +40,7 @@ function commerce_product_product_form($form, &$form_state, $product) {
 
   // Add the field related form elements.
   $form_state['commerce_product'] = $product;
-  field_attach_form('commerce_product', $product, $form, $form_state);
+  field_attach_form('commerce_product', $product, $form, $form_state, $product->language);
 
   $form['status'] = array(
     '#type' => 'radios',
@@ -61,6 +61,12 @@ function commerce_product_product_form($form, &$form_state, $product) {
     '#weight' => 400,
   );
 
+  // Simply use default language
+  $form['language'] = array(
+    '#type' => 'value',
+    '#value' => $product->language,
+  );
+
   // We add the form's #submit array to this button along with the actual submit
   // handler to preserve any submit handlers added by a form callback_wrapper.
   $submit = array();
@@ -122,6 +128,7 @@ function commerce_product_product_form_submit($form, &$form_state) {
   $product->sku = $form_state['values']['sku'];
   $product->title = $form_state['values']['title'];
   $product->status = $form_state['values']['status'];
+  $product->language = $form_state['values']['language'];
 
   // Set the product's uid if it's being created at this time.
   if (empty($product->product_id)) {
diff --git a/modules/product/includes/translation.handler.commerce_product.inc b/modules/product/includes/translation.handler.commerce_product.inc
new file mode 100644
index 0000000..e8ee130
--- /dev/null
+++ b/modules/product/includes/translation.handler.commerce_product.inc
@@ -0,0 +1,55 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Commerce product translation handler for the translation module.
+ */
+
+
+/**
+ * Commerce product translation handler.
+ *
+ * Override the default behaviours to provide the needed commerce product
+ * properties.
+ *
+ * This class is registered in the commerce_product_ui.module. If you want to
+ * use it without the commerce_product_ui.module make sure you register it
+ * on your own by using hook_translation_info().
+ * @see hook_translation_info()
+ * @see commerce_product_ui.module
+ */
+class EntityTranslationCommerceProductHandler extends EntityTranslationDefaultHandler {
+
+  public function __construct($entity_type, $entity_info, $entity, $entity_id) {
+    parent::__construct('commerce_product', $entity_info, $entity, $entity_id);
+  }
+
+  /**
+   * Indicates whether this commerce product is a revision or not.
+   */
+  public function isRevision() {
+    return !empty($this->entity->revision);
+  }
+
+  /**
+   * Returns the original language of the commerce product.
+   */
+  public function getLanguage() {
+    return $this->entity->language;
+  }
+
+  /**
+   * Checks whether the current user has access to this commerce product.
+   */
+  public function getAccess($op) {
+    return commerce_product_access($op, $this->entity);
+  }
+
+  /**
+   * Returns whether the commerce product is active (TRUE) or disabled (FALSE).
+   */
+  protected function getStatus() {
+    return (boolean) $this->entity->status;
+  }
+}
-- 
1.7.3.3

