diff --git a/includes/commerce_line_item.inline_entity_form.inc b/includes/commerce_line_item.inline_entity_form.inc
index 642affb..0c767b9 100644
--- a/includes/commerce_line_item.inline_entity_form.inc
+++ b/includes/commerce_line_item.inline_entity_form.inc
@@ -98,7 +98,7 @@ class CommerceLineItemInlineEntityFormController extends EntityInlineEntityFormC
'#weight' => $extra_fields['label']['weight'],
'#fieldset' => 'line_item_details',
);
- field_attach_form('commerce_line_item', $line_item, $entity_form, $form_state);
+ $entity_form = parent::entityForm($entity_form, $form_state);
// Tweaks specific to product line items.
if (in_array($line_item->type, $this->productLineItemTypes())) {
diff --git a/includes/commerce_product.inline_entity_form.inc b/includes/commerce_product.inline_entity_form.inc
index ae6ed0d..06afee0 100644
--- a/includes/commerce_product.inline_entity_form.inc
+++ b/includes/commerce_product.inline_entity_form.inc
@@ -194,9 +194,7 @@ class CommerceProductInlineEntityFormController extends EntityInlineEntityFormCo
'#weight' => $extra_fields['status']['weight'],
);
- // Attach fields.
- $langcode = entity_language('commerce_product', $product);
- field_attach_form('commerce_product', $product, $entity_form, $form_state, $langcode);
+ $entity_form = parent::entityForm($entity_form, $form_state);
// Hide or disable the SKU field if it is auto-generated by Commerce AutoSKU.
if (module_exists('commerce_autosku') && $settings = commerce_autosku_get_settings($product)) {
@@ -362,7 +360,10 @@ class CommerceProductInlineEntityFormController extends EntityInlineEntityFormCo
// Generate the product title. Take the parent entity title as the base.
if ($this->settings['autogenerate_title']) {
- $entity->title = entity_label($context['parent_entity_type'], $context['parent_entity']);
+ // Update the entity label only with a valid value.
+ if ($label = entity_label($context['parent_entity_type'], $context['parent_entity'])) {
+ $entity->title = $label;
+ }
$attributes = $this->attributes($entity->type);
if (!empty($attributes)) {
$wrapper = entity_metadata_wrapper('commerce_product', $entity);
@@ -378,6 +379,18 @@ class CommerceProductInlineEntityFormController extends EntityInlineEntityFormCo
$entity->title .= ' (' . implode(', ', $attribute_values) . ')';
}
}
+
+ // Update the autogenerated title field, otherwise when dealing with
+ // translations the source language would be used.
+ if (module_exists('title') && entity_label($this->entityType, $entity)) {
+ $legacy_field = 'title';
+ list(, , $bundle) = entity_extract_ids($this->entityType, $entity);
+ if (title_field_replacement_enabled($this->entityType, $bundle, $legacy_field)) {
+ $info = title_field_replacement_info($this->entityType, $legacy_field);
+ $langcode = $info['field']['translatable'] ? entity_language($this->entityType, $entity) : LANGUAGE_NONE;
+ title_field_sync_set($this->entityType, $entity, $legacy_field, $info, $langcode);
+ }
+ }
}
entity_save('commerce_product', $entity);
diff --git a/includes/entity.inline_entity_form.inc b/includes/entity.inline_entity_form.inc
index 89a4246..7dba0d5 100644
--- a/includes/entity.inline_entity_form.inc
+++ b/includes/entity.inline_entity_form.inc
@@ -272,9 +272,84 @@ class EntityInlineEntityFormController {
field_attach_form($this->entityType, $entity, $entity_form, $form_state, $langcode);
}
+ $this->entityFormTranslation($entity_form);
return $entity_form;
}
+ /**
+ * Handles entity translation for inline entities.
+ *
+ * @param $entity_form
+ * The entity form.
+ */
+ protected function entityFormTranslation(&$entity_form) {
+ if (($handler = module_invoke('entity_translation', 'get_handler', $this->entityType, $entity_form['#entity'])) && !$handler->isNewEntity()) {
+ $form_langcode = $handler->getActiveLanguage();
+ $langcode = !empty($entity_form['#parent_language']) ? $entity_form['#parent_language'] : $handler->getLanguage();
+ $translations = $handler->getTranslations();
+ $update_langcode = $form_langcode && ($form_langcode != $langcode);
+ $source = $handler->getSourceLanguage();
+ $new_translation = !isset($translations->data[$form_langcode]);
+
+ if (!isset($translations->data[$form_langcode]) || count($translations->data) > 1) {
+ $handler->entityFormSharedElements($entity_form);
+ }
+
+ // If we are creating a new translation we need to retrieve form elements
+ // populated with the source language values. In this case source values
+ // have already been populated, so we need to preserve possible changes.
+ // There might be situations, e.g. ajax calls, where the form language
+ // has not been properly initialized before calling field_attach_form().
+ // In this case we need to rebuild the form with the correct form language
+ // and replace the field elements with the correct ones.
+ // Borrowed some code from entity_translation_field_attach_form()
+ // that won't get run because $form_state['rebuild'] is TRUE for all IEF
+ // forms.
+ if ($update_langcode || ($source && !isset($translations->data[$form_langcode]) && isset($translations->data[$source]))) {
+ $entity_type = $entity_form['#entity_type'];
+ list($id, , $bundle) = entity_extract_ids($entity_type, $entity_form['#entity']);
+ foreach (field_info_instances($entity_type, $bundle) as $instance) {
+
+ $field_name = $instance['field_name'];
+ $field = field_info_field($field_name);
+
+ // If we are creating a new translation we have to change the form
+ // item language information from source to target language, this way
+ // the user can find the form items already populated with the source
+ // values while the field form element holds the correct language
+ // information.
+ if ($field['translatable']) {
+ $element = &$entity_form[$field_name];
+ $element['#entity_type'] = $entity_type;
+ $element['#entity'] = $entity_form['#entity'];
+ $element['#entity_id'] = $id;
+ $element['#field_name'] = $field_name;
+ $element['#source'] = $update_langcode ? $form_langcode : $source;
+ $element['#previous'] = NULL;
+ $element['#form_parents'] = $entity_form['#parents'];
+
+ // If we are updating the form language we need to make sure that
+ // the wrong language is unset and the right one is stored in the
+ // field element (see entity_translation_prepare_element()).
+ if ($update_langcode) {
+ $element['#previous'] = $element['#language'];
+ $element['#language'] = $form_langcode;
+ }
+
+ // Swap default values during form processing to avoid recursion.
+ // We try to act before any other callback so that the correct
+ // values are already in place for them.
+ if (!isset($element['#process'])) {
+ $element['#process'] = array();
+ }
+ array_unshift($element['#process'], 'entity_translation_prepare_element');
+ }
+ }
+ }
+ $entity_form['#element_validate'][] = 'entity_translation_entity_form_validate';
+ }
+ }
+
/**
* Validates the entity form.
*
@@ -308,7 +383,7 @@ class EntityInlineEntityFormController {
$info = entity_get_info($this->entityType);
list(, , $bundle) = entity_extract_ids($this->entityType, $entity_form['#entity']);
$entity = $entity_form['#entity'];
- $entity_values = drupal_array_get_nested_value($form_state['values'], $entity_form['#parents']);
+ $entity_values = &drupal_array_get_nested_value($form_state['values'], $entity_form['#parents']);
// Copy top-level form values that are not for fields to entity properties,
// without changing existing entity properties that are not being edited by
@@ -318,8 +393,61 @@ class EntityInlineEntityFormController {
$entity->$key = $value;
}
+ // Update the entity language using the parent entity submitted value.
+ if (!empty($info['entity keys']['language'])) {
+ $parent_info = entity_get_info($entity_form['#parent_entity_type']);
+ if (isset($parent_info['entity keys']['language']) && isset($form_state['values'][$parent_info['entity keys']['language']])) {
+ $entity->{$info['entity keys']['language']} = $form_state['values'][$parent_info['entity keys']['language']];
+ $handler = module_invoke('entity_translation', 'get_handler', $this->entityType, $entity);
+ $lang = $handler->getActiveLanguage();
+ if ($lang == LANGUAGE_NONE) {
+ if ($entity_form['#parent_language'] != LANGUAGE_NONE) {
+ $handler->setFormLanguage($entity_form['#parent_language']);
+ }
+ else {
+ $handler->setFormLanguage($form_state['values'][$parent_info['entity keys']['language']]);
+ }
+ }
+ }
+ }
+
if ($info['fieldable']) {
+ // Retrieve the current entity form language.
+ $langcode = entity_language($this->entityType, $entity);
+
+ // Handle a possible language change: new language values are inserted,
+ // previous ones are deleted.
+ foreach (field_info_instances($this->entityType, $bundle) as $instance) {
+ $field_name = $instance['field_name'];
+ $field = field_info_field($field_name);
+ $previous_langcode = $entity_form[$field_name]['#language'];
+ if ($field['translatable'] && $previous_langcode != $langcode && ($langcode != LANGUAGE_NONE && $previous_langcode != language_default('language'))) {
+ $entity_values[$field_name][$langcode] = $entity_values[$field_name][$previous_langcode];
+ $entity_values[$field_name][$previous_langcode] = array();
+ }
+ }
+
field_attach_submit($this->entityType, $entity, $entity_form, $form_state);
+
+ // Handle translation submission.
+ $this->entityTranslationFormSubmit($entity_form, $entity);
+ }
+ }
+
+ /**
+ * Creates an entity translation if needed.
+ */
+ protected function entityTranslationFormSubmit($entity_form, $entity) {
+ if (($handler = module_invoke('entity_translation', 'get_handler', $this->entityType, $entity)) && ($source = $handler->getSourceLanguage())) {
+ list($id, , ) = entity_extract_ids($this->entityType, $entity);
+ $translation = array(
+ 'entity_type' => $this->entityType,
+ 'entity_id' => $id,
+ 'language' => $handler->getActiveLanguage(),
+ 'source' => $source,
+ 'status' => 1,
+ );
+ $handler->setTranslation($translation);
}
}
@@ -362,7 +490,7 @@ class EntityInlineEntityFormController {
* @param $form_state
* The form state of the parent form.
*
- * @return
+ * @return int
* IEF_ENTITY_UNLINK or IEF_ENTITY_UNLINK_DELETE.
*/
public function removeFormSubmit($remove_form, &$form_state) {
@@ -382,6 +510,31 @@ class EntityInlineEntityFormController {
return IEF_ENTITY_UNLINK_DELETE;
}
+ /**
+ * Returns the remove translation form to be shown through the IEF widget.
+ *
+ * @param $remove_form
+ * The remove form.
+ * @param $form_state
+ * The form state of the parent form.
+ */
+ public function removeTranslationForm($remove_form, &$form_state) {
+ $entity = $remove_form['#entity'];
+ list($entity_id) = entity_extract_ids($this->entityType, $entity);
+ $entity_label = entity_label($this->entityType, $entity);
+ $langcode = entity_language($this->entityType, $entity);
+ $languages = language_list();
+
+ $remove_form['message'] = array(
+ '#markup' => '
' . t('Are you sure you want to remove the @language_label translation for %label?', array(
+ '%label' => $entity_label,
+ '@language_label' => isset($languages[$langcode]) ? $languages[$langcode]->name : $langcode,
+ )) . '
',
+ );
+
+ return $remove_form;
+ }
+
/**
* Creates a clone of the given entity.
*
diff --git a/includes/node.inline_entity_form.inc b/includes/node.inline_entity_form.inc
index 4d481cb..c879b5c 100644
--- a/includes/node.inline_entity_form.inc
+++ b/includes/node.inline_entity_form.inc
@@ -65,10 +65,7 @@ class NodeInlineEntityFormController extends EntityInlineEntityFormController {
'#weight' => 99,
);
- $langcode = entity_language('node', $node);
- field_attach_form('node', $node, $entity_form, $form_state, $langcode);
-
- return $entity_form;
+ return parent::entityForm($entity_form, $form_state);
}
/**
diff --git a/includes/taxonomy_term.inline_entity_form.inc b/includes/taxonomy_term.inline_entity_form.inc
index bd2ec59..eb1667c 100644
--- a/includes/taxonomy_term.inline_entity_form.inc
+++ b/includes/taxonomy_term.inline_entity_form.inc
@@ -85,10 +85,7 @@ class TaxonomyTermInlineEntityFormController extends EntityInlineEntityFormContr
'#weight' => !empty($extra_fields['description']) ? $extra_fields['description']['weight'] : -4,
);
- $langcode = entity_language('taxonomy_term', $term);
- field_attach_form('taxonomy_term', $term, $entity_form, $form_state, $langcode);
-
- return $entity_form;
+ return parent::entityForm($entity_form, $form_state);
}
diff --git a/inline_entity_form.module b/inline_entity_form.module
index 556b376..fa02b25 100644
--- a/inline_entity_form.module
+++ b/inline_entity_form.module
@@ -166,6 +166,47 @@ function inline_entity_form_entity_delete($entity, $type) {
}
}
+/**
+ * Implements hook_entity_translation_delete().
+ *
+ * Deletes a translation of the referenced entity.
+ */
+function inline_entity_form_entity_translation_delete($entity_type, $entity, $langcode) {
+ list(,, $bundle) = entity_extract_ids($entity_type, $entity);
+ foreach (field_info_instances($entity_type, $bundle) as $field_name => $instance) {
+ if (strpos($instance['widget']['type'], 'inline_entity_form') === 0) {
+ $controller = inline_entity_form_get_controller($instance);
+
+ // The controller specified that referenced entities should be deleted.
+ if ($controller && $controller->getSetting('delete_references')) {
+ $items = field_get_items($entity_type, $entity, $field_name, $langcode);
+ if ($items) {
+ $field = field_info_field($field_name);
+ $ief_settings = inline_entity_form_settings($field, $instance);
+
+ $ids = array();
+ foreach ($items as $item) {
+ $ids[] = $item[$ief_settings['column']];
+ }
+
+ $ref_entity_type = $ief_settings['entity_type'];
+ $context = array(
+ 'parent_entity_type' => $entity_type,
+ 'parent_entity' => $entity,
+ );
+
+ foreach (entity_load($ref_entity_type, $ids) as $id => $ref_entity) {
+ $handler = entity_translation_get_handler($ref_entity_type, $ref_entity);
+ $handler->removeTranslation($langcode);
+ $controller->save($ref_entity, $context);
+ }
+ }
+ }
+ }
+ }
+}
+
+
/**
* Attaches theme specific CSS files.
*
@@ -373,6 +414,7 @@ function inline_entity_form_field_widget_form(&$form, &$form_state, $field, $ins
$widget = $instance['widget'];
$settings = inline_entity_form_settings($field, $instance);
$entity_info = entity_get_info($settings['entity_type']);
+ $parent_entity_info = entity_get_info($element['#entity_type']);
$controller = inline_entity_form_get_controller($instance);
// The current entity type is not supported, execution can't continue.
if (!$controller) {
@@ -382,11 +424,30 @@ function inline_entity_form_field_widget_form(&$form, &$form_state, $field, $ins
// Get the entity type labels for the UI strings.
$labels = $controller->labels();
+ // Use current form language for translatable field.
+ if (!empty($form_state['entity_translation']['is_translation']) && $langcode != LANGUAGE_NONE) {
+ $langcode = $form_state['entity_translation']['form_langcode'];
+ }
+
// Build a parents array for this element's values in the form.
- $parents = array_merge($element['#field_parents'], array($element['#field_name'], $element['#language']));
+ $parents = array_merge($element['#field_parents'], array($element['#field_name'], $langcode));
// Get the langcode of the parent entity.
- $parent_langcode = entity_language($element['#entity_type'], $element['#entity']);
+ // If the parent entity is new, the language is not yet set. Use the langcode
+ // from the parent form if existing in this case.
+ if (!isset($element['#entity']->{$parent_entity_info['entity keys']['id']}) && isset($form_state['complete form']['language'])) {
+ $parent_langcode = isset($form_state['complete form']['language']['#value']) ? $form_state['complete form']['language']['#value'] : $form_state['complete form']['language']['#default_value'];
+ $parent_is_translation = FALSE;
+ }
+ else {
+ // Get the langcode of the parent entity.
+ $parent_langcode = (!empty($form_state['entity_translation']['is_translation'])) ? $form_state['entity_translation']['form_langcode'] : entity_language($element['#entity_type'], $element['#entity']);
+ if (module_exists('entity_translation')){
+ $handler = entity_translation_get_handler($element['#entity_type'], $element['#entity']);
+ $translations = $handler->getTranslations();
+ $parent_is_translation = isset($translations->original) && $parent_langcode != $translations->original;
+ }
+ }
// Assign a unique identifier to each IEF widget.
// Since $parents can get quite long, sha1() ensures that every id has
@@ -424,17 +485,35 @@ function inline_entity_form_field_widget_form(&$form, &$form_state, $field, $ins
// Add entity type specific CSS.
_inline_entity_form_attach_css($controller->css(), $element['#attached']['css']);
+ // Pre-populate the widget with the values from source language.
+ // Do it only if translation is new. If user intends not to have any
+ // child items in the translatable field, then do not pre-populate.
+ // Normally, entity_translation_prepare_element() function
+ // should take care of that, however it does not work, since it fails to deal
+ // with the state stored in $form_state['inline_entity_form'].
+ // @See: https://www.drupal.org/node/2339315#comment-12235439.
+ // If the patch there is committed, then we could refactor the if-block below
+ // to be aligned with entity_translation_prepare_element() approach.
+ if (!empty($field['translatable']) &&
+ $parent_is_translation &&
+ !$items &&
+ empty($translations->data[$parent_langcode]) &&
+ !empty($element['#entity']->{$instance['field_name']}[$translations->original])
+ ) {
+ $items = $element['#entity']->{$instance['field_name']}[$translations->original];
+ }
+
// Initialize the IEF array in form state.
if (empty($form_state['inline_entity_form'][$ief_id])) {
$form_state['inline_entity_form'][$ief_id] = array(
'form' => NULL,
'settings' => $settings,
'instance' => $instance,
+ 'entities' => array(),
);
// Load the entities from the $items array and store them in the form
// state for further manipulation.
- $form_state['inline_entity_form'][$ief_id]['entities'] = array();
$entity_ids = array();
foreach ($items as $item) {
$entity_ids[] = $item[$settings['column']];
@@ -484,6 +563,8 @@ function inline_entity_form_field_widget_form(&$form, &$form_state, $field, $ins
'#parents' => array_merge($parents, array('form')),
// Pass the current entity type.
'#entity_type' => $settings['entity_type'],
+ '#parent_entity' => $element['#entity'],
+ '#parent_entity_type' => $element['#entity_type'],
// Pass the langcode of the parent entity,
'#parent_language' => $parent_langcode,
// Identifies the IEF widget to which the form belongs.
@@ -553,6 +634,8 @@ function inline_entity_form_field_widget_form(&$form, &$form_state, $field, $ins
'#entity' => $entity,
'#entity_type' => $settings['entity_type'],
// Pass the langcode of the parent entity,
+ '#parent_entity' => $element['#entity'],
+ '#parent_entity_type' => $element['#entity_type'],
'#parent_language' => $parent_langcode,
// Identifies the IEF widget to which the form belongs.
'#ief_id' => $ief_id,
@@ -584,12 +667,20 @@ function inline_entity_form_field_widget_form(&$form, &$form_state, $field, $ins
'#attributes' => array('class' => array('ief-entity-operations')),
);
+ // If we are editing a translation and the inline entity is
+ // translated, provide some different options.
+ if (module_exists('entity_translation')){
+ $handler = entity_translation_get_handler($controller->entityType(), $entity);
+ $translations = $handler->getTranslations();
+ $is_translation = $parent_is_translation && isset($translations->original) && $parent_langcode != $translations->original && isset($translations->data[$parent_langcode]);
+ }
+
// Make sure entity_access is not checked for unsaved entities.
list($entity_id) = entity_extract_ids($controller->entityType(), $entity);
if (empty($entity_id) || entity_access('update', $controller->entityType(), $entity)) {
$row['actions']['ief_entity_edit'] = array(
'#type' => 'submit',
- '#value' => t('Edit'),
+ '#value' => $is_translation ? t('Edit translation') : ($parent_is_translation ? t('Add translation') : t('Edit')),
'#name' => 'ief-' . $ief_id . '-entity-edit-' . $key,
'#limit_validation_errors' => array(),
'#ajax' => array(
@@ -605,7 +696,7 @@ function inline_entity_form_field_widget_form(&$form, &$form_state, $field, $ins
// The clone form follows the same semantics as the create form, so
// it's opened below the table.
if ($controller->getSetting('allow_clone') && !$cardinality_reached
- && entity_access('create', $controller->entityType(), $entity)) {
+ && entity_access('create', $controller->entityType(), $entity) && !$parent_is_translation) {
$row['actions']['ief_entity_clone'] = array(
'#type' => 'submit',
'#value' => t('Clone'),
@@ -626,19 +717,40 @@ function inline_entity_form_field_widget_form(&$form, &$form_state, $field, $ins
// removeForm() method.
if (empty($entity_id) || $controller->getSetting('allow_existing')
|| entity_access('delete', $controller->entityType(), $entity)) {
- $row['actions']['ief_entity_remove'] = array(
- '#type' => 'submit',
- '#value' => t('Remove'),
- '#name' => 'ief-' . $ief_id . '-entity-remove-' . $key,
- '#limit_validation_errors' => array(),
- '#ajax' => array(
- 'callback' => 'inline_entity_form_get_element',
- 'wrapper' => $wrapper,
- ),
- '#submit' => array('inline_entity_form_open_row_form'),
- '#ief_row_delta' => $key,
- '#ief_row_form' => 'remove',
- );
+ // Either provide a button to remove the translation or to remove
+ // the whole reference.
+ if ($is_translation) {
+ $row['actions']['ief_entity_remove_translation'] = array(
+ '#type' => 'submit',
+ '#value' => t('Remove translation'),
+ '#name' => 'ief-' . $ief_id . '-entity-remove-' . $key,
+ '#limit_validation_errors' => array(),
+ '#ajax' => array(
+ 'callback' => 'inline_entity_form_get_element',
+ 'wrapper' => $wrapper,
+ ),
+ '#submit' => array('inline_entity_form_open_row_form'),
+ '#ief_row_delta' => $key,
+ '#ief_row_form' => 'remove',
+ '#ief_row_is_translation' => $is_translation,
+ );
+ }
+ if (!$parent_is_translation || !empty($field['translatable'])) {
+ $row['actions']['ief_entity_remove'] = array(
+ '#type' => 'submit',
+ '#value' => t('Remove'),
+ '#name' => 'ief-' . $ief_id . '-entity-remove-' . $key,
+ '#limit_validation_errors' => array(),
+ '#ajax' => array(
+ 'callback' => 'inline_entity_form_get_element',
+ 'wrapper' => $wrapper,
+ ),
+ '#submit' => array('inline_entity_form_open_row_form'),
+ '#ief_row_delta' => $key,
+ '#ief_row_form' => 'remove',
+ '#ief_row_is_translation' => $is_translation && empty($field['translatable']),
+ );
+ }
}
}
}
@@ -690,7 +802,7 @@ function inline_entity_form_field_widget_form(&$form, &$form_state, $field, $ins
);
// The user is allowed to create an entity of at least one bundle.
- if (count($settings['create_bundles'])) {
+ if (count($settings['create_bundles']) && !$parent_is_translation) {
// Let the user select the bundle, if multiple are available.
if (count($settings['create_bundles']) > 1) {
$bundles = array();
@@ -754,6 +866,8 @@ function inline_entity_form_field_widget_form(&$form, &$form_state, $field, $ins
// values in $form_state.
'#parents' => array_merge($parents, array('form')),
// Pass the current entity type.
+ '#parent_entity' => $element['#entity'],
+ '#parent_entity_type' => $element['#entity_type'],
'#entity_type' => $settings['entity_type'],
// Pass the langcode of the parent entity,
'#parent_language' => $parent_langcode,
@@ -880,6 +994,16 @@ function inline_entity_form_entity_form($controller, $entity_form, &$form_state)
$save_label = t('Clone @type_singular', array('@type_singular' => $labels['singular']));
}
+ // Register a child entity translation handler to properly deal with the
+ // entity form language.
+ list(, , $bundle) = entity_extract_ids($entity_form['#entity_type'], $entity_form['#entity']);
+ if (module_invoke('entity_translation', 'enabled', $entity_form['#entity_type'], $bundle) && $entity_form['#parent_entity']->translations->original != null) {
+ inline_entity_form_add_child_translation_handler($entity_form);
+ // Ensure this is executed even with cached forms. This is mainly useful
+ // when dealing with AJAX calls.
+ $entity_form['#process'][] = 'inline_entity_form_add_child_translation_handler';
+ }
+
// Retrieve the form provided by the controller.
$entity_form = $controller->entityForm($entity_form, $form_state);
@@ -952,6 +1076,20 @@ function inline_entity_form_entity_form($controller, $entity_form, &$form_state)
return $entity_form;
}
+/**
+ * Registers a child entity translation handler for the given element.
+ */
+function inline_entity_form_add_child_translation_handler($element) {
+ $handler = entity_translation_get_handler($element['#parent_entity_type'], $element['#parent_entity']);
+ $handler->setFormLanguage($element['#parent_language']);
+ $source = $handler->getSourceLanguage();
+ if (!($source) && $element['#parent_entity']->translations->original != $element['#parent_language']) {
+ $handler->setSourceLanguage($element['#parent_entity']->translations->original);
+ }
+ $handler->addChild($element['#entity_type'], $element['#entity']);
+ return $element;
+}
+
/**
* Validates an entity form.
*
@@ -1187,12 +1325,24 @@ function inline_entity_form_remove_form($controller, $remove_form, &$form_state)
$delta = $remove_form['#ief_id'] . '-' . $remove_form['#ief_row_delta'];
// Retrieve the form provided by the controller.
- $remove_form = $controller->removeForm($remove_form, $form_state);
+ $row_is_translation = $form_state['triggering_element']['#ief_row_is_translation'];
+ if ($row_is_translation) {
+ $remove_form = inline_entity_form_add_child_translation_handler($remove_form);
+ $remove_form = $controller->removeTranslationForm($remove_form, $form_state);
+ }
+ else {
+ $remove_form = $controller->removeForm($remove_form, $form_state);
+ }
+
// Add the actions
$remove_form['actions'] = array(
'#type' => 'container',
'#weight' => 100,
);
+ // @todo: Compare entity original language with translation language.
+ // IF this is a translation, switch buttons and replace
+ // inline_entity_form_remove_confirm with variant that calls
+ // removeTranslationFormSubmit on the handler.
$remove_form['actions']['ief_remove_confirm'] = array(
'#type' => 'submit',
'#value' => t('Remove'),
@@ -1202,7 +1352,7 @@ function inline_entity_form_remove_form($controller, $remove_form, &$form_state)
'callback' => 'inline_entity_form_get_element',
'wrapper' => 'inline-entity-form-' . $remove_form['#ief_id'],
),
- '#submit' => array('inline_entity_form_remove_confirm'),
+ '#submit' => array($row_is_translation ? 'inline_entity_form_remove_translation_confirm' : 'inline_entity_form_remove_confirm'),
'#ief_row_delta' => $remove_form['#ief_row_delta'],
);
$remove_form['actions']['ief_remove_cancel'] = array(
@@ -1221,6 +1371,36 @@ function inline_entity_form_remove_form($controller, $remove_form, &$form_state)
return $remove_form;
}
+/**
+ * Remove translation form submit callback.
+ *
+ * The row is identified by #ief_row_delta stored on the triggering
+ * element.
+ * This isn't an #element_validate callback to avoid processing the
+ * remove form when the main form is submitted.
+ *
+ * @param $form
+ * The complete parent form.
+ * @param $form_state
+ * The form state of the parent form.
+ */
+function inline_entity_form_remove_translation_confirm($form, &$form_state) {
+ $form_state['rebuild'] = TRUE;
+ $element = inline_entity_form_get_element($form, $form_state);
+ $ief_id = $element['#ief_id'];
+ $delta = $form_state['triggering_element']['#ief_row_delta'];
+ $remove_form = $element['entities'][$delta]['form'];
+ $entity = $form_state['inline_entity_form'][$ief_id]['entities'][$delta]['entity'];
+
+ $settings = $form_state['inline_entity_form'][$ief_id]['settings'];
+ $handler = entity_translation_get_handler($settings['entity_type'], $entity);
+ $handler->removeTranslation($remove_form['#parent_language']);
+ $form_state['inline_entity_form'][$ief_id]['entities'][$delta]['needs_save'] = TRUE;
+
+ // Close form.
+ $form_state['inline_entity_form'][$ief_id]['entities'][$delta]['form'] = NULL;
+}
+
/**
* Remove form submit callback.
*
@@ -1526,6 +1706,18 @@ function inline_entity_form_field_attach_submit($parent_entity_type, $parent_ent
$need_reset = FALSE;
foreach ($values['entities'] as $item) {
if ($item['needs_save']) {
+ // Ensure the proper entity form language is set before saving.
+ if (module_invoke('entity_translation', 'enabled', $entity_type, $item['entity']) && ($handler = module_invoke('entity_translation', 'get_handler', $entity_type, $item['entity']))) {
+ // Fetch the parent language - with entity_translation this will
+ // return the current form language and thus match perfectly.
+ $parent_entity_language = entity_language($parent_entity_type, $parent_entity);
+ $entity_form_language = $handler->getActiveLanguage();
+ // If the field is language independent set the parent entity
+ // language as form language of the entity.
+ if ($langcode == LANGUAGE_NONE && $entity_form_language != $parent_entity_language) {
+ $handler->setFormLanguage($parent_entity_language);
+ }
+ }
$controller->save($item['entity'], $context);
$need_reset = TRUE;
}
diff --git a/tests/modules/inline_entity_form_test/inline_entity_form_test.module b/tests/modules/inline_entity_form_test/inline_entity_form_test.module
index 8f46348..76d71fb 100644
--- a/tests/modules/inline_entity_form_test/inline_entity_form_test.module
+++ b/tests/modules/inline_entity_form_test/inline_entity_form_test.module
@@ -146,6 +146,24 @@ function inline_entity_form_test_install() {
);
field_create_field($field);
+ $field = array(
+ 'field_name' => 'field_multiple_nodes_translate',
+ 'type' => 'entityreference',
+ 'cardinality' => -1,
+ 'translatable' => TRUE,
+ 'required' => TRUE,
+ 'settings' => array(
+ 'target_type' => 'node',
+ 'handler' => 'base',
+ 'handler_settings' => array(
+ 'target_bundles' => array(
+ 'ief_reference_type' => 'ief_reference_type',
+ ),
+ ),
+ ),
+ );
+ field_create_field($field);
+
$field_bases['field_positive_int'] = array(
'active' => 1,
'cardinality' => 1,
@@ -305,6 +323,31 @@ function inline_entity_form_test_install() {
);
field_create_instance($instance);
+ $instance = array(
+ 'bundle' => 'ief_test_multiple',
+ 'entity_type' => 'node',
+ 'field_name' => 'field_multiple_nodes_translate',
+ 'label' => 'Multiple nodes (translatable)',
+ 'required' => TRUE,
+ 'widget' => array(
+ 'type' => 'inline_entity_form',
+ 'settings' => array(
+ 'fields' => array(),
+ 'type_settings' => array(
+ 'allow_clone' => 0,
+ 'allow_existing' => 0,
+ 'allow_new' => 1,
+ 'delete_references' => 0,
+ 'label_plural' => 'nodes',
+ 'label_singular' => 'node',
+ 'match_operator' => 'CONTAINS',
+ 'override_labels' => 0,
+ ),
+ ),
+ ),
+ );
+ field_create_instance($instance);
+
$instance = array(
'bundle' => 'ief_test_custom',
'entity_type' => 'node',