diff --git a/feeds.info b/feeds.info
index eb7387b..aba8bf9 100644
--- a/feeds.info
+++ b/feeds.info
@@ -36,6 +36,7 @@ files[] = tests/feeds_mapper_date.test
files[] = tests/feeds_mapper_date_multiple.test
files[] = tests/feeds_mapper_field.test
files[] = tests/feeds_mapper_file.test
+files[] = tests/feeds_mapper_multilingual_fields.test
files[] = tests/feeds_mapper_path.test
files[] = tests/feeds_mapper_profile.test
files[] = tests/feeds_mapper.test
@@ -61,3 +62,10 @@ files[] = views/feeds_views_handler_field_log_message.inc
files[] = views/feeds_views_handler_field_severity.inc
files[] = views/feeds_views_handler_field_source.inc
files[] = views/feeds_views_handler_filter_severity.inc
+
+; Information added by Drupal.org packaging script on 2014-08-06
+version = "7.x-2.0-alpha8+44-dev"
+core = "7.x"
+project = "feeds"
+datestamp = "1407357366"
+
diff --git a/feeds.module b/feeds.module
index cba702d..5c8e0a4 100644
--- a/feeds.module
+++ b/feeds.module
@@ -896,6 +896,72 @@ function feeds_item_info_save($entity, $entity_id) {
}
/**
+ * Returns the language summary text for use in a mapper target summary_callback
+ *
+ * @param array $mapping
+ * Associative array of the mapping settings.
+ * @param array $target
+ * Array of target settings, as defined by the processor or
+ * hook_feeds_processor_targets_alter().
+ * @param array $form
+ * The whole mapping form.
+ * @param array $form_state
+ * The form state of the mapping form.
+ *
+ * @return string
+ * Returns, as a string that may contain HTML, the summary to display while
+ * the full form isn't visible.
+ * If the return value is empty, no summary and no option to view the form
+ * will be displayed.
+ */
+function feeds_mapper_summary_language($mapping, $target, $form, $form_state) {
+ if (module_exists('locale')) {
+ list($field_name) = explode(':', $mapping['target']);
+ $info = field_info_field($field_name);
+ if ($info['translatable']) {
+ $language_options = array(LANGUAGE_NONE => t('All languages')) + locale_language_list('name');
+ if (empty($mapping['language'])) {
+ return t('Language: @search', array('@search' => $language_options[LANGUAGE_NONE]));
+ }
+ return t('Language: @search', array('@search' => $language_options[$mapping['language']]));
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * Returns tha language form for use in a mapper target form_callback
+ *
+ * @param array $mapping
+ * Associative array of the mapping settings.
+ * @param array $target
+ * Array of target settings, as defined by the processor or
+ * hook_feeds_processor_targets_alter().
+ * @param array $form
+ * The whole mapping form.
+ * @param array $form_state
+ * The form state of the mapping form.
+ *
+ * @return string
+ * Returns, as a string that may contain HTML, the summary to display while
+ * the full form isn't visible.
+ * If the return value is empty, no summary and no option to view the form
+ * will be displayed.
+ */
+function feeds_mapper_form_language($mapping, $target, $form, $form_state) {
+ $form = array();
+ if (module_exists('locale')) {
+ list($field_name) = explode(':', $mapping['target']);
+ $info = field_info_field($field_name);
+ if ($info['translatable']) {
+ $language_options = array(LANGUAGE_NONE => t('All languages')) + locale_language_list('name');
+ $form['language'] = module_exists('translation') ? language_default('language') : LANGUAGE_NONE;
+ }
+ }
+ return $form;
+}
+
+/**
* @}
*/
diff --git a/feeds_import/feeds_import.info b/feeds_import/feeds_import.info
index 6509d60..585a938 100644
--- a/feeds_import/feeds_import.info
+++ b/feeds_import/feeds_import.info
@@ -8,3 +8,10 @@ files[] = "feeds_import.test"
name = "Feeds Import"
package = "Feeds"
php = "5.2.4"
+
+; Information added by Drupal.org packaging script on 2014-08-06
+version = "7.x-2.0-alpha8+44-dev"
+core = "7.x"
+project = "feeds"
+datestamp = "1407357366"
+
diff --git a/feeds_news/feeds_news.info b/feeds_news/feeds_news.info
index 3d19f04..031f934 100644
--- a/feeds_news/feeds_news.info
+++ b/feeds_news/feeds_news.info
@@ -18,3 +18,10 @@ features[node][] = feed_item
features[views_view][] = feeds_defaults_feed_items
files[] = feeds_news.module
files[] = feeds_news.test
+
+; Information added by Drupal.org packaging script on 2014-08-06
+version = "7.x-2.0-alpha8+44-dev"
+core = "7.x"
+project = "feeds"
+datestamp = "1407357366"
+
diff --git a/feeds_ui/feeds_ui.info b/feeds_ui/feeds_ui.info
index 1ef5b46..4197b86 100644
--- a/feeds_ui/feeds_ui.info
+++ b/feeds_ui/feeds_ui.info
@@ -6,3 +6,10 @@ dependencies[] = feeds
configure = admin/structure/feeds
files[] = feeds_ui.test
+
+; Information added by Drupal.org packaging script on 2014-08-06
+version = "7.x-2.0-alpha8+44-dev"
+core = "7.x"
+project = "feeds"
+datestamp = "1407357366"
+
diff --git a/mappers/file.inc b/mappers/file.inc
index e9cbc26..3e015c9 100644
--- a/mappers/file.inc
+++ b/mappers/file.inc
@@ -21,6 +21,8 @@ function file_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam
'callback' => 'file_feeds_set_target',
'description' => t('The URI of the @label field.', array('@label' => $instance['label'])),
'real_target' => $name,
+ 'summary_callback' => 'feeds_mapper_summary_language',
+ 'form_callback' => 'feeds_mapper_form_language',
);
if ($info['type'] == 'image') {
@@ -29,12 +31,16 @@ function file_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam
'callback' => 'file_feeds_set_target',
'description' => t('The alt tag of the @label field.', array('@label' => $instance['label'])),
'real_target' => $name,
+ 'summary_callback' => 'feeds_mapper_summary_language',
+ 'form_callback' => 'feeds_mapper_form_language',
);
$targets[$name . ':title'] = array(
'name' => t('@label: Title', array('@label' => $instance['label'])),
'callback' => 'file_feeds_set_target',
'description' => t('The title of the @label field.', array('@label' => $instance['label'])),
'real_target' => $name,
+ 'summary_callback' => 'feeds_mapper_summary_language',
+ 'form_callback' => 'feeds_mapper_form_language',
);
}
}
@@ -48,11 +54,14 @@ function file_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam
* user has decided to map to and $value contains the value of the feed item
* element the user has picked as a source.
*/
-function file_feeds_set_target($source, $entity, $target, array $values) {
+function file_feeds_set_target($source, $entity, $target, array $values, $mapping = array()) {
// Add default of uri for backwards compatibility.
list($field_name, $sub_field) = explode(':', $target . ':uri');
$info = field_info_field($field_name);
+ // Set the language of the field depending on the mapping configuration.
+ $langcode = isset($mapping['language']) ? $mapping['language'] : LANGUAGE_NONE;
+
if ($sub_field == 'uri') {
foreach ($values as $k => $v) {
@@ -84,30 +93,30 @@ function file_feeds_set_target($source, $entity, $target, array $values) {
}
// Populate entity.
- $field = isset($entity->$field_name) ? $entity->$field_name : array(LANGUAGE_NONE => array());
+ $field = isset($entity->$field_name) ? $entity->$field_name : array($langcode => array());
$delta = 0;
foreach ($values as $v) {
if ($info['cardinality'] == $delta) {
break;
}
- if (!isset($field[LANGUAGE_NONE][$delta])) {
- $field[LANGUAGE_NONE][$delta] = array();
+ if (!isset($field[$langcode][$delta])) {
+ $field[$langcode][$delta] = array();
}
switch ($sub_field) {
case 'alt':
case 'title':
- $field[LANGUAGE_NONE][$delta][$sub_field] = $v;
+ $field[$langcode][$delta][$sub_field] = $v;
break;
case 'uri':
if ($v) {
try {
$file = $v->getFile($destination);
- $field[LANGUAGE_NONE][$delta] += (array) $file;
+ $field[$langcode][$delta] += (array) $file;
// @todo: Figure out how to properly populate this field.
- $field[LANGUAGE_NONE][$delta]['display'] = 1;
+ $field[$langcode][$delta]['display'] = 1;
}
catch (Exception $e) {
watchdog_exception('Feeds', $e, nl2br(check_plain($e)));
diff --git a/mappers/link.inc b/mappers/link.inc
index 90b5268..54254a1 100644
--- a/mappers/link.inc
+++ b/mappers/link.inc
@@ -20,6 +20,8 @@ function link_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam
'callback' => 'link_feeds_set_target',
'description' => t('The @label field of the entity.', array('@label' => $instance['label'])),
'real_target' => $name,
+ 'summary_callback' => 'feeds_mapper_summary_language',
+ 'form_callback' => 'feeds_mapper_form_language',
);
}
if (array_key_exists('title', $info['columns'])) {
@@ -28,6 +30,8 @@ function link_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam
'callback' => 'link_feeds_set_target',
'description' => t('The @label field of the entity.', array('@label' => $instance['label'])),
'real_target' => $name,
+ 'summary_callback' => 'feeds_mapper_summary_language',
+ 'form_callback' => 'feeds_mapper_form_language',
);
}
}
@@ -41,19 +45,22 @@ function link_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam
* user has decided to map to and $value contains the value of the feed item
* element the user has picked as a source.
*/
-function link_feeds_set_target($source, $entity, $target, array $values) {
+function link_feeds_set_target($source, $entity, $target, array $values, $mapping = array()) {
list($field_name, $column) = explode(':', $target);
$field = isset($entity->$field_name) ? $entity->$field_name : array('und' => array());
$delta = 0;
+ // Set the language of the field depending on the mapping configuration.
+ $langcode = isset($mapping['language']) ? $mapping['language'] : LANGUAGE_NONE;
+
foreach ($values as $value) {
if (is_object($value) && ($value instanceof FeedsElement)) {
$value = $value->getValue();
}
if (is_scalar($value)) {
- $field['und'][$delta][$column] = (string) $value;
+ $field[$langcode][$delta][$column] = (string) $value;
}
$delta++;
}
diff --git a/mappers/number.inc b/mappers/number.inc
index 338d569..7ed7e72 100644
--- a/mappers/number.inc
+++ b/mappers/number.inc
@@ -27,6 +27,8 @@ function number_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_n
'name' => check_plain($instance['label']),
'callback' => 'number_feeds_set_target',
'description' => t('The @label field of the entity.', array('@label' => $instance['label'])),
+ 'summary_callback' => 'feeds_mapper_summary_language',
+ 'form_callback' => 'feeds_mapper_form_language',
);
}
}
@@ -37,9 +39,17 @@ function number_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_n
*
* Ensure that $value is a numeric to avoid database errors.
*/
-function number_feeds_set_target($source, $entity, $target, array $values) {
+function number_feeds_set_target($source, $entity, $target, array $values, $mapping = array()) {
+ // Set the language of the field depending on the mapping configuration.
+ $langcode = isset($mapping['language']) ? $mapping['language'] : LANGUAGE_NONE;
+
// Iterate over all values.
- $field = isset($entity->$target) ? $entity->$target : array('und' => array());
+ $field = isset($entity->$target) ? $entity->$target : array($langcode => array());
+
+ // If it's a new language we need to add it to the field
+ if (!isset($field[$langcode])) {
+ $field[$langcode] = array();
+ }
foreach ($values as $value) {
@@ -48,7 +58,7 @@ function number_feeds_set_target($source, $entity, $target, array $values) {
}
if (is_numeric($value)) {
- $field['und'][] = array('value' => $value);
+ $field[$langcode][] = array('value' => $value);
}
}
diff --git a/mappers/taxonomy.inc b/mappers/taxonomy.inc
index 088a558..d513381 100644
--- a/mappers/taxonomy.inc
+++ b/mappers/taxonomy.inc
@@ -87,7 +87,10 @@ function taxonomy_feeds_set_target($source, $entity, $target, array $terms, $map
$mapping += array(
'term_search' => FEEDS_TAXONOMY_SEARCH_TERM_NAME,
'autocreate' => FALSE,
+ 'language' => LANGUAGE_NONE,
);
+ // Grab the language for convenience
+ $langcode = $mapping['language'];
$info = field_info_field($target);
@@ -110,10 +113,15 @@ function taxonomy_feeds_set_target($source, $entity, $target, array $terms, $map
->range(0, 1);
- $field = isset($entity->$target) ? $entity->$target : array('und' => array());
+ $field = isset($entity->$target) ? $entity->$target : array($langcode => array());
+
+ // If it's a new language we need to add it to the field
+ if (!isset($field[$langcode])) {
+ $field[$langcode] = array();
+ }
// Allow for multiple mappings to the same target.
- $delta = count($field['und']);
+ $delta = count($field[$langcode]);
// Iterate over all values.
foreach ($terms as $term) {
@@ -166,7 +174,7 @@ function taxonomy_feeds_set_target($source, $entity, $target, array $terms, $map
}
if ($tid && isset($cache['allowed_values'][$target][$tid])) {
- $field['und'][] = array('tid' => $tid);
+ $field[$langcode][] = array('tid' => $tid);
$delta++;
}
}
@@ -257,11 +265,21 @@ function taxonomy_feeds_term_lookup_term_by_guid($guid) {
* will be displayed.
*/
function taxonomy_feeds_summary_callback($mapping, $target, $form, $form_state) {
+ $output = '';
$options = _taxonomy_feeds_form_callback_options();
if (empty($mapping['term_search'])) {
- return t('Search taxonomy terms by: @search', array('@search' => $options[FEEDS_TAXONOMY_SEARCH_TERM_NAME]));
+ $output = t('Search taxonomy terms by: @search', array('@search' => $options[FEEDS_TAXONOMY_SEARCH_TERM_NAME]));
+ }
+ else {
+ $output = t('Search taxonomy terms by: @search', array('@search' => $options[$mapping['term_search']]));
+ }
+ if ($language_summary = feeds_mapper_summary_language($mapping, $target, $form, $form_state)) {
+ $output .= '
' . $language_summary;
}
- return t('Search taxonomy terms by: @search', array('@search' => $options[$mapping['term_search']]));
+ if (!empty($mapping['autocreate'])) {
+ $output .= '
' . t('Autocreate Terms: Yes');
+ }
+ return $output;
}
/**
@@ -272,7 +290,8 @@ function taxonomy_feeds_summary_callback($mapping, $target, $form, $form_state)
* be populated with the form values.
*/
function taxonomy_feeds_form_callback($mapping, $target, $form, $form_state) {
- return array(
+ $return = feeds_mapper_form_language($mapping, $target, $form, $form_state);
+ $return += array(
'term_search' => array(
'#type' => 'select',
'#title' => t('Search taxonomy terms by'),
@@ -291,6 +310,8 @@ function taxonomy_feeds_form_callback($mapping, $target, $form, $form_state) {
),
),
);
+
+ return $return;
}
/**
diff --git a/mappers/text.inc b/mappers/text.inc
index 235aea3..72d069b 100644
--- a/mappers/text.inc
+++ b/mappers/text.inc
@@ -25,6 +25,8 @@ function text_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam
'name' => check_plain($instance['label']),
'callback' => 'text_feeds_set_target',
'description' => t('The @label field of the entity.', array('@label' => $instance['label'])),
+ 'summary_callback' => 'feeds_mapper_summary_language',
+ 'form_callback' => 'feeds_mapper_form_language',
);
if ($info['type'] == 'text_with_summary') {
// Allow mapping to summary.
@@ -58,8 +60,16 @@ function text_feeds_set_target(FeedsSource $source, $entity, $target, array $val
);
}
- $field = isset($entity->$field_name) ? $entity->$field_name : array('und' => array());
+// Set the language of the field depending on the mapping configuration.
+ $langcode = isset($mapping['language']) ? $mapping['language'] : LANGUAGE_NONE;
+ $field = isset($entity->$target) ? $entity->$target : array($langcode => array());
+
+ // If it's a new language we need to add it to the field
+ if (!isset($field[$langcode])) {
+ $field[$langcode] = array();
+ }
+
// Iterate over all values.
$delta = 0;
foreach ($values as $value) {
@@ -70,10 +80,10 @@ function text_feeds_set_target(FeedsSource $source, $entity, $target, array $val
if (is_scalar($value) && strlen($value)) {
- $field['und'][$delta][$column] = (string) $value;
+ $field[$langcode][$delta][$column] = (string) $value;
if (isset($mapping['format'])) {
- $field['und'][$delta]['format'] = $mapping['format'];
+ $field[$langcode][$delta]['format'] = $format;
}
}
diff --git a/plugins/FeedsEntityProcessor.inc b/plugins/FeedsEntityProcessor.inc
index 833800f..725753a 100644
--- a/plugins/FeedsEntityProcessor.inc
+++ b/plugins/FeedsEntityProcessor.inc
@@ -135,6 +135,7 @@ class FeedsEntityProcessor extends FeedsProcessor {
'skip_hash_check' => FALSE,
'bundle' => NULL,
'values' => array(),
+ 'language' => LANGUAGE_NONE,
);
}
diff --git a/plugins/FeedsNodeProcessor.inc b/plugins/FeedsNodeProcessor.inc
index 8b63c53..a9eab29 100644
--- a/plugins/FeedsNodeProcessor.inc
+++ b/plugins/FeedsNodeProcessor.inc
@@ -34,7 +34,7 @@ class FeedsNodeProcessor extends FeedsProcessor {
$node->type = $this->bundle();
$node->changed = REQUEST_TIME;
$node->created = REQUEST_TIME;
- $node->language = LANGUAGE_NONE;
+ $node->language = module_exists('translation') ? $this->config['language'] : LANGUAGE_NONE;
$node->is_new = TRUE;
node_object_prepare($node);
// Populate properties that are set by node_object_prepare().
@@ -104,15 +104,8 @@ class FeedsNodeProcessor extends FeedsProcessor {
}
if (!$access) {
- $message = t('The user %name is not authorized to %op content of type %content_type. To import this item, either the user "@name" (author of the item) must be given the permission to @op content of type @content_type, or the option "Authorize" on the Node processor settings must be turned off.', array(
- '%name' => $author->name,
- '%op' => $op,
- '%content_type' => $entity->type,
- '@name' => $author->name,
- '@op' => $op,
- '@content_type' => $entity->type,
- ));
- throw new FeedsAccessException($message);
+ $message = 'User %name is not authorized to %op content type %content_type.';
+ throw new FeedsAccessException(t($message, array('%name' => $author->name, '%op' => $op, '%content_type' => $entity->type)));
}
}
}
@@ -141,12 +134,28 @@ class FeedsNodeProcessor extends FeedsProcessor {
}
/**
- * Overrides parent::expiryQuery().
+ * Implement expire().
+ *
+ * @todo: move to processor stage?
*/
- protected function expiryQuery(FeedsSource $source, $time) {
- $select = parent::expiryQuery($source, $time);
- $select->condition('e.created', REQUEST_TIME - $time, '<');
- return $select;
+ public function expire($time = NULL) {
+ if ($time === NULL) {
+ $time = $this->expiryTime();
+ }
+ if ($time == FEEDS_EXPIRE_NEVER) {
+ return;
+ }
+ $count = $this->getLimit();
+ $nodes = db_query_range("SELECT n.nid FROM {node} n JOIN {feeds_item} fi ON fi.entity_type = 'node' AND n.nid = fi.entity_id WHERE fi.id = :id AND n.created < :created", 0, $count, array(':id' => $this->id, ':created' => REQUEST_TIME - $time));
+ $nids = array();
+ foreach ($nodes as $node) {
+ $nids[$node->nid] = $node->nid;
+ }
+ $this->entityDeleteMultiple($nids);
+ if (db_query_range("SELECT 1 FROM {node} n JOIN {feeds_item} fi ON fi.entity_type = 'node' AND n.nid = fi.entity_id WHERE fi.id = :id AND n.created < :created", 0, 1, array(':id' => $this->id, ':created' => REQUEST_TIME - $time))->fetchField()) {
+ return FEEDS_BATCH_ACTIVE;
+ }
+ return FEEDS_BATCH_COMPLETE;
}
/**
@@ -160,11 +169,14 @@ class FeedsNodeProcessor extends FeedsProcessor {
* Override parent::configDefaults().
*/
public function configDefaults() {
- return array(
- 'expire' => FEEDS_EXPIRE_NEVER,
- 'author' => 0,
- 'authorize' => TRUE,
- ) + parent::configDefaults();
+ $configDefaults = array(
+ 'expire' => FEEDS_EXPIRE_NEVER,
+ 'author' => 0,
+ 'authorize' => TRUE,);
+ if (module_exists('entity_translation')) {
+ $configDefaults['language'] = language_default('language');
+ }
+ return $configDefaults + parent::configDefaults();
}
/**
@@ -174,6 +186,17 @@ class FeedsNodeProcessor extends FeedsProcessor {
$form = parent::configForm($form_state);
$author = user_load($this->config['author']);
+ if (module_exists('entity_translation')) {
+ $language_options = array(LANGUAGE_NONE => t('All languages')) + locale_language_list('name');
+ $form['language'] = array(
+ '#type' => 'select',
+ '#title' => t('Language'),
+ '#description' => t('Select the language for which the node will be imported.'),
+ '#options' => $language_options,
+ '#default_value' => $this->config['language'],
+ );
+ }
+
$form['author'] = array(
'#type' => 'textfield',
'#title' => t('Author'),
@@ -369,5 +392,4 @@ class FeedsNodeProcessor extends FeedsProcessor {
}
return 0;
}
-
}
diff --git a/plugins/FeedsProcessor.inc b/plugins/FeedsProcessor.inc
index 833cd2c..969b015 100755
--- a/plugins/FeedsProcessor.inc
+++ b/plugins/FeedsProcessor.inc
@@ -14,6 +14,9 @@ define('FEEDS_UPDATE_EXISTING', 2);
// processors.
define('FEEDS_PROCESS_LIMIT', 50);
+// Default Language trigger
+define('FEEDS_LANGUAGE_DEFAULT', 'xx_');
+
/**
* Thrown if a validation fails.
*/
@@ -77,6 +80,23 @@ abstract class FeedsProcessor extends FeedsPlugin {
}
/**
+ * Provides a list of language options for use in select lists.
+ *
+ * @return array
+ * A keyed array of langcode => language.
+ */
+ public function languageOptions() {
+ $options = array(
+ FEEDS_LANGUAGE_DEFAULT => t('Default Language'),
+ LANGUAGE_NONE => t('Language neutral'),
+ );
+ foreach (language_list() as $langcode => $language) {
+ $options[$langcode] = $language->name;
+ }
+ return $options;
+ }
+
+ /**
* Create a new entity.
*
* @param $source
@@ -216,11 +236,16 @@ abstract class FeedsProcessor extends FeedsPlugin {
// Build a new entity.
else {
$entity = $this->newEntity($source);
+ // Set the language if it wasn't set specifically by a processor
+ if (!isset($entity->language)) {
+ $entity->language = $this->getConfigLanguage();
+ }
$this->newItemInfo($entity, $source->feed_nid, $hash);
}
// Set property and field values.
$this->map($source, $parser_result, $entity);
+ $this->processEntityTitleReplacements($entity);
$this->entityValidate($entity);
// Allow modules to alter the entity before saving.
@@ -236,6 +261,7 @@ abstract class FeedsProcessor extends FeedsPlugin {
// This will throw an exception on failure.
$this->entitySaveAccess($entity);
+ $this->processTranslations($entity);
$this->entitySave($entity);
// Allow modules to perform operations using the saved entity data.
@@ -609,6 +635,7 @@ abstract class FeedsProcessor extends FeedsPlugin {
'input_format' => NULL,
'skip_hash_check' => FALSE,
'bundle' => $bundle,
+ 'language' => LANGUAGE_NONE,
);
}
@@ -635,6 +662,14 @@ abstract class FeedsProcessor extends FeedsPlugin {
);
}
+ $form['language'] = array(
+ '#type' => 'select',
+ '#options' => $this->languageOptions(),
+ '#title' => t('Language'),
+ '#required' => TRUE,
+ '#default_value' => $this->config['language'],
+ );
+
$tokens = array('@entities' => strtolower($info['label plural']));
$form['update_existing'] = array(
@@ -732,6 +767,101 @@ abstract class FeedsProcessor extends FeedsPlugin {
}
/**
+ * Returns the configured language for the processor
+ *
+ * @return
+ * The language code configured for the processor
+ */
+ public function getConfigLanguage() {
+ return ($this->config['language'] == FEEDS_LANGUAGE_DEFAULT) ? language_default('language') : $this->config['language'];
+ }
+
+ /**
+ * Returns the language for the entity.
+ *
+ * @param string $entity
+ * The entity for which to get the language.
+ *
+ * @return
+ * The language code for the entity, or the language code that's configured
+ * for the processor if the entity doesn't have any language support.
+ */
+ public function getEntityLanguage($entity) {
+ $language = entity_language($this->entityType(), $entity);
+ return $language ? $language : $this->getConfigLanguage();
+ }
+
+ /**
+ * Process entity properties that have been replaced with the title module
+ *
+ * @param object $entity
+ * The entity to check for replaced properties
+ */
+ public function processEntityTitleReplacements(&$entity) {
+ if (module_exists('title')) {
+ // Get the possible replacements for this entity type
+ if ($replacements = title_field_replacement_info($this->entityType())) {
+ // Loop through replacements
+ foreach ($replacements as $legacy_field => $field_info) {
+ // Populate legacy field with value from the field of the language
+ // for the entity.
+ $language = $this->getEntityLanguage($entity);
+ if (!empty($entity->{$field_info['field']['field_name']}[$language]) && empty($entity->{$legacy_field})) {
+ $entity->{$legacy_field} = $entity->{$field_info['field']['field_name']}[$language][0]['value'];
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Add translations to an entity for each mapped language
+ *
+ * @param object $entity
+ * The entity to add translations to
+ */
+ public function processTranslations(&$entity) {
+ // Add translations (if the entity_translation module exists) provided at
+ // least one field has a translation
+ if (module_exists('entity_translation')) {
+ $handler = entity_translation_get_handler($this->entityType(), $entity);
+ $languages = array();
+ $default_langcode = $this->getEntityLanguage($entity);
+
+ // Init the translations if there's not translation data yet
+ if (empty($entity->translations->data)) {
+ $handler->initTranslations();
+ }
+
+ // Loop through the mappings
+ foreach ($this->getMappings() as $mapping) {
+ if (!empty($mapping['language']) && $mapping['language'] != LANGUAGE_NONE && $mapping['language'] != $default_langcode && empty($entity->translations->data[$mapping['language']])) {
+ list($field_name) = explode(':', $mapping['target']);
+
+ // If this field's language has items we create a translation for it
+ if (!empty($entity->{$field_name}[$mapping['language']])) {
+ $translation = array(
+ 'translate' => 0,
+ 'status' => 1,
+ 'language' => $mapping['language'],
+ 'source' => $default_langcode,
+ );
+ $handler->setTranslation($translation, $entity);
+ }
+ }
+ }
+
+ // Loop through every language for the site, and remove translations for
+ // the one that hasn't got any values.
+ foreach (language_list() as $language) {
+ if (!isset($entity->translations->data[$language->language])) {
+ $handler->removeTranslation($language->language);
+ }
+ }
+ }
+ }
+
+ /**
* Retrieve the target entity's existing id if available. Otherwise return 0.
*
* @ingroup mappingapi
diff --git a/tests/feeds_tests.info b/tests/feeds_tests.info
index 0e1d123..fe21ea3 100644
--- a/tests/feeds_tests.info
+++ b/tests/feeds_tests.info
@@ -4,4 +4,12 @@ package = Testing
version = VERSION
core = 7.x
test_dependencies[] = entity
+test_dependencies[] = entity_translation
hidden = TRUE
+
+; Information added by Drupal.org packaging script on 2014-08-06
+version = "7.x-2.0-alpha8+44-dev"
+core = "7.x"
+project = "feeds"
+datestamp = "1407357366"
+