diff --git a/feeds.module b/feeds.module index 4418e9c..8f51dac 100644 --- a/feeds.module +++ b/feeds.module @@ -485,7 +485,7 @@ function feeds_exit() { foreach ($jobs as $job) { if (!isset($job['fetcher']) || !isset($job['source'])) { continue; - } + } $job['fetcher']->subscribe($job['source']); } @@ -905,13 +905,81 @@ function feeds_item_info_save($entity, $entity_id) { } /** - * @} + * Implements hook_feeds_processor_targets_alter(). */ +function locale_feeds_processor_targets_alter(array &$targets, $entity_type, $bundle_name) { + $language_options = feeds_mapper_options_language(); + + foreach ($targets as $target => $target_config) { + list($field_name) = explode(':', $target); + if (!$info = field_info_field($field_name)) { + continue; + } + if (!$info['translatable']) { + continue; + } + + $targets[$target]['summary_callback'][] = 'feeds_mapper_locale_summary'; + $targets[$target]['form_callback'][] = 'feeds_mapper_locale_form'; + $targets[$target]['preprocess_callbacks'][] = 'feeds_mapper_locale_preprocess'; + } +} /** - * @defgroup instantiators Instantiators - * @{ + * Summary callback for language configuration. + */ +function feeds_mapper_locale_summary(array $mapping, array $target, array $form, array &$form_state) { + list($field_name) = explode(':', $mapping['target']); + $info = field_info_field($field_name); + + if ($info['translatable']) { + $language_options = feeds_mapper_options_language(); + if (empty($mapping['language'])) { + return t('Language: @search', array('@search' => $language_options[LANGUAGE_NONE])); + } + return t('Language: @search', array('@search' => $language_options[$mapping['language']])); + } +} + +/** + * Callback for language mapper configuration form. */ +function feeds_mapper_locale_form(array $mapping, array $target, array $form, array &$form_state) { + list($field_name) = explode(':', $mapping['target']); + $info = field_info_field($field_name); + if ($info['translatable']) { + $form['language'] = array( + '#type' => 'select', + '#title' => t('Language'), + '#options' => feeds_mapper_options_language(), + '#default_value' => !empty($mapping['language']) ? $mapping['language'] : LANGUAGE_NONE, + '#description' => t('You can select a particular field language (or language nautral) or use language code saved in entity\'s language property (e.g. $node->language) you set by some mapper above.'), + ); + } + return $form; +} + +/** + * Callback for processing the mapping configuration. + */ +function feeds_mapper_locale_preprocess(FeedsSource $source, $entity, $target, array &$mapping) { + // Set the language of the field depending on the mapping configuration. + $mapping['language'] = !empty($mapping['language']) ? $mapping['language'] : LANGUAGE_NONE; + $mapping['language'] = $mapping['language'] === 'from_property' ? $entity->language : $mapping['language']; +} + +/** + * Return the options list of language options for target configuration. + * + * @return array + * A list of available language options. + */ +function feeds_mapper_options_language() { + return array( + 'from_property' => t('Inherit language'), + LANGUAGE_NONE => t('Language neutral'), + ) + locale_language_list('name'); +} /** * Gets an importer instance. @@ -1053,7 +1121,7 @@ function feeds_library_exists($file, $library) { return FALSE; } - /** +/** * Checks whether simplepie exists. */ function feeds_simplepie_exists() { @@ -1219,7 +1287,7 @@ function feeds_file_download($uri) { return; } - // Get the file record based on the URI. If not in the database just return. + // Get the file record based on the URI. If not in the database just return. $files = file_load_multiple(array(), array('uri' => $uri)); foreach ($files as $item) { // Since some database servers sometimes use a case-insensitive comparison diff --git a/mappers/file.inc b/mappers/file.inc index d761ba6..e6a1bab 100644 --- a/mappers/file.inc +++ b/mappers/file.inc @@ -80,30 +80,30 @@ function file_feeds_set_target(FeedsSource $source, $entity, $target, array $val } // Populate entity. - $field = isset($entity->$field_name) ? $entity->$field_name : array(LANGUAGE_NONE => array()); + $field = isset($entity->$field_name) ? $entity->$field_name : array($mapping['language'] => 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[$mapping['language']][$delta])) { + $field[$mapping['language']][$delta] = array(); } switch ($sub_field) { case 'alt': case 'title': - $field[LANGUAGE_NONE][$delta][$sub_field] = $v; + $field[$mapping['language']][$delta][$sub_field] = $v; break; case 'uri': if ($v) { try { $file = $v->getFile($destination); - $field[LANGUAGE_NONE][$delta] += (array) $file; + $field[$mapping['language']][$delta] += (array) $file; // @todo: Figure out how to properly populate this field. - $field[LANGUAGE_NONE][$delta]['display'] = 1; + $field[$mapping['language']][$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 4d3d0e9..6edac63 100644 --- a/mappers/link.inc +++ b/mappers/link.inc @@ -40,7 +40,7 @@ function link_feeds_processor_targets($entity_type, $bundle_name) { function link_feeds_set_target(FeedsSource $source, $entity, $target, array $values, array $mapping) { list($field_name, $column) = explode(':', $target); - $field = isset($entity->$field_name) ? $entity->$field_name : array('und' => array()); + $field = isset($entity->$field_name) ? $entity->$field_name : array($mapping['language'] => array()); $delta = 0; foreach ($values as $value) { @@ -49,7 +49,7 @@ function link_feeds_set_target(FeedsSource $source, $entity, $target, array $val } if (is_scalar($value)) { - $field['und'][$delta][$column] = (string) $value; + $field[$mapping['language']][$delta][$column] = (string) $value; } $delta++; } diff --git a/mappers/number.inc b/mappers/number.inc index d2c2d76..e7731f9 100644 --- a/mappers/number.inc +++ b/mappers/number.inc @@ -37,7 +37,7 @@ function number_feeds_processor_targets($entity_type, $bundle_name) { */ function number_feeds_set_target(FeedsSource $source, $entity, $target, array $values, array $mapping) { // Iterate over all values. - $field = isset($entity->$target) ? $entity->$target : array('und' => array()); + $field = isset($entity->$target) ? $entity->$target : array($mapping['language'] => array()); foreach ($values as $value) { @@ -46,7 +46,7 @@ function number_feeds_set_target(FeedsSource $source, $entity, $target, array $v } if (is_numeric($value)) { - $field['und'][] = array('value' => $value); + $field[$mapping['language']][] = array('value' => $value); } } diff --git a/mappers/taxonomy.inc b/mappers/taxonomy.inc index 1e455da..21d6132 100644 --- a/mappers/taxonomy.inc +++ b/mappers/taxonomy.inc @@ -172,7 +172,7 @@ function taxonomy_feeds_set_target(FeedsSource $source, $entity, $target, array } if ($tid && isset($cache['allowed_values'][$target][$tid])) { - $field['und'][] = array('tid' => $tid); + $field[$mapping['language']][] = array('tid' => $tid); $delta++; } } diff --git a/mappers/text.inc b/mappers/text.inc index 21ee8f9..7d4c60d 100644 --- a/mappers/text.inc +++ b/mappers/text.inc @@ -58,7 +58,7 @@ function text_feeds_set_target(FeedsSource $source, $entity, $target, array $val ); } - $field = isset($entity->$field_name) ? $entity->$field_name : array('und' => array()); + $field = isset($entity->$field_name) ? $entity->$field_name : array($mapping['language'] => array()); // Iterate over all values. $delta = 0; @@ -70,10 +70,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[$mapping['language']][$delta][$column] = (string) $value; if (isset($mapping['format'])) { - $field['und'][$delta]['format'] = $mapping['format']; + $field[$mapping['language']][$delta]['format'] = $mapping['format']; } } diff --git a/plugins/FeedsProcessor.inc b/plugins/FeedsProcessor.inc index 473dffb..5824834 100755 --- a/plugins/FeedsProcessor.inc +++ b/plugins/FeedsProcessor.inc @@ -80,6 +80,21 @@ 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() { + if (!module_exists('locale')) { + return array(); + } + return array( + LANGUAGE_NONE => t('Language neutral'), + ) + locale_language_list('name') ; + } + + /** * Create a new entity. * * @param $source @@ -261,7 +276,7 @@ abstract class FeedsProcessor extends FeedsPlugin { } } - // Something bad happened, log it. + // Something bad happened, log it. catch (Exception $e) { $state->failed++; drupal_set_message($e->getMessage(), 'warning'); @@ -286,7 +301,7 @@ abstract class FeedsProcessor extends FeedsPlugin { $messages = array(); if ($state->created) { $messages[] = array( - 'message' => format_plural( + 'message' => format_plural( $state->created, 'Created @number @entity.', 'Created @number @entities.', @@ -296,7 +311,7 @@ abstract class FeedsProcessor extends FeedsPlugin { } if ($state->updated) { $messages[] = array( - 'message' => format_plural( + 'message' => format_plural( $state->updated, 'Updated @number @entity.', 'Updated @number @entities.', @@ -307,16 +322,16 @@ abstract class FeedsProcessor extends FeedsPlugin { if ($state->unpublished) { $messages[] = array( 'message' => format_plural( - $state->unpublished, - 'Unpublished @number @entity.', - 'Unpublished @number @entities.', - array('@number' => $state->unpublished) + $tokens + $state->unpublished, + 'Unpublished @number @entity.', + 'Unpublished @number @entities.', + array('@number' => $state->unpublished) + $tokens ), ); } if ($state->deleted) { $messages[] = array( - 'message' => format_plural( + 'message' => format_plural( $state->deleted, 'Removed @number @entity.', 'Removed @number @entities.', @@ -326,7 +341,7 @@ abstract class FeedsProcessor extends FeedsPlugin { } if ($state->failed) { $messages[] = array( - 'message' => format_plural( + 'message' => format_plural( $state->failed, 'Failed importing @number @entity.', 'Failed importing @number @entities.', @@ -371,7 +386,7 @@ abstract class FeedsProcessor extends FeedsPlugin { 'fi', 'e.' . $id_key . ' = fi.entity_id AND fi.entity_type = :entity_type', array( ':entity_type' => $this->entityType(), - )); + )); $select->condition('fi.id', $this->id); $select->condition('fi.feed_nid', $source->feed_nid); @@ -569,7 +584,7 @@ abstract class FeedsProcessor extends FeedsPlugin { 'fi', "e.$id_key = fi.entity_id AND fi.entity_type = :entity_type", array( ':entity_type' => $this->entityType(), - )); + )); $select->condition('fi.id', $this->id); $select->condition('fi.feed_nid', $source->feed_nid); @@ -671,9 +686,9 @@ abstract class FeedsProcessor extends FeedsPlugin { } if (isset($sources[$this->id][$source_key]) && - is_array($sources[$this->id][$source_key]) && - isset($sources[$this->id][$source_key]['callback']) && - function_exists($sources[$this->id][$source_key]['callback'])) { + is_array($sources[$this->id][$source_key]) && + isset($sources[$this->id][$source_key]['callback']) && + function_exists($sources[$this->id][$source_key]['callback'])) { $callback = $sources[$this->id][$source_key]['callback']; return $callback($source, $result, $source_key); @@ -706,9 +721,9 @@ abstract class FeedsProcessor extends FeedsPlugin { // If the mapping specifies a callback method, use the callback instead of // setTargetElement(). if (isset($targets[$target]) && - is_array($targets[$target]) && - isset($targets[$target]['callback']) && - function_exists($targets[$target]['callback'])) { + is_array($targets[$target]) && + isset($targets[$target]['callback']) && + function_exists($targets[$target]['callback'])) { $callback = $targets[$target]['callback']; // All target callbacks expect an array. @@ -766,6 +781,7 @@ abstract class FeedsProcessor extends FeedsPlugin { 'input_format' => NULL, 'skip_hash_check' => FALSE, 'bundle' => $bundle, + 'language' => LANGUAGE_NONE, ); } @@ -792,6 +808,16 @@ abstract class FeedsProcessor extends FeedsPlugin { ); } + if (module_exists('locale')) { + $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( diff --git a/tests/feeds_tests.module b/tests/feeds_tests.module index 5ce8961..d0d2ce1 100644 --- a/tests/feeds_tests.module +++ b/tests/feeds_tests.module @@ -129,7 +129,7 @@ function feeds_tests_feeds_processor_targets($entity_type, $bundle) { * @see my_module_set_target() */ function feeds_tests_mapper_set_target($source, $entity, $target, $value, $mapping) { - $entity->body['und'][0]['value'] = serialize($mapping); + $entity->body[$mapping['language']][0]['value'] = serialize($mapping); } /**