diff --git a/feeds.info b/feeds.info index 11934e0..04d3b69 100644 --- a/feeds.info +++ b/feeds.info @@ -38,6 +38,7 @@ files[] = tests/feeds_mapper_field.test files[] = tests/feeds_mapper_file.test files[] = tests/feeds_mapper_hooks.test files[] = tests/feeds_mapper_link.test +files[] = tests/feeds_mapper_multilingual_fields.test files[] = tests/feeds_mapper_path.test files[] = tests/feeds_mapper_profile.test files[] = tests/feeds_mapper_unique.test diff --git a/mappers/date.inc b/mappers/date.inc index d5ea81f..c75f125 100644 --- a/mappers/date.inc +++ b/mappers/date.inc @@ -37,7 +37,7 @@ function date_feeds_processor_targets($entity_type, $bundle_name) { /** * Callback for setting date values. */ -function date_feeds_set_target(FeedsSource $source, $entity, $target, array $values) { +function date_feeds_set_target(FeedsSource $source, $entity, $target, array $values, array $mapping) { list($field_name, $sub_field) = explode(':', $target, 2); $delta = 0; @@ -56,7 +56,7 @@ function date_feeds_set_target(FeedsSource $source, $entity, $target, array $val } } - $value->buildDateField($entity, $field_name, $delta); + $value->buildDateField($entity, $field_name, $delta, $mapping['language']); $delta++; } } diff --git a/mappers/entity_translation.inc b/mappers/entity_translation.inc new file mode 100644 index 0000000..2ea5abc --- /dev/null +++ b/mappers/entity_translation.inc @@ -0,0 +1,82 @@ +feeds_item->entity_type; + + // Check that it's a real entity type, and translation is enabled. + if (!entity_get_info($entity_type) || !entity_translation_enabled($entity_type, $entity)) { + return; + } + + if (!$handler = entity_translation_get_handler($entity_type, $entity)) { + return; + } + + list(, , $bundle) = entity_extract_ids($entity_type, $entity); + + $languages_seen = array(); + + foreach (field_info_instances($entity_type, $bundle) as $instance) { + $field_name = $instance['field_name']; + + // No values in this field, skip it. + if (empty($entity->$field_name)) { + continue; + } + + // Not translatable. + if (($info = field_info_field($field_name)) && !$info['translatable']) { + continue; + } + + // Init the translation handler. + if (empty($handler->getTranslations()->original)) { + $handler->initTranslations(); + } + + // Avoid invalid user configuration. Entity translation does this when + // loading the translation overview page. + if (count($entity->$field_name) === 1 && key($entity->$field_name) === LANGUAGE_NONE) { + $entity->{$field_name}[$handler->getLanguage()] = $entity->{$field_name}[LANGUAGE_NONE]; + $entity->{$field_name}[LANGUAGE_NONE] = array(); + } + + // Look for languages we haven't created a translation for yet. + foreach (array_diff_key($entity->$field_name, $languages_seen) as $language => $v) { + if ($language === LANGUAGE_NONE) { + continue; + } + + $languages_seen[$language] = TRUE; + + if ($language === $handler->getLanguage()) { + continue; + } + + $translation = array( + 'translate' => 0, + 'status' => 1, + 'language' => $language, + 'source' => $handler->getLanguage(), + ); + + $handler->setTranslation($translation, $entity); + } + } + + // Loop through every language for the site, and remove translations for the + // ones that don't have any values. + foreach (language_list() as $language) { + if (!isset($languages_seen[$language->language])) { + $handler->removeTranslation($language->language); + } + } +} diff --git a/mappers/file.inc b/mappers/file.inc index d46c319..07349f2 100644 --- a/mappers/file.inc +++ b/mappers/file.inc @@ -54,7 +54,9 @@ function file_feeds_processor_targets($entity_type, $bundle_name) { /** * Callback for mapping file fields. */ -function file_feeds_set_target(FeedsSource $source, $entity, $target, array $values) { +function file_feeds_set_target(FeedsSource $source, $entity, $target, array $values, array $mapping) { + $language = $mapping['language']; + // Add default of uri for backwards compatibility. list($field_name, $sub_field) = explode(':', $target . ':uri'); $info = field_info_field($field_name); @@ -90,22 +92,22 @@ 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($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[$language][$delta])) { + $field[$language][$delta] = array(); } switch ($sub_field) { case 'alt': case 'title': case 'description': - $field[LANGUAGE_NONE][$delta][$sub_field] = $v; + $field[$language][$delta][$sub_field] = $v; break; case 'uri': @@ -113,9 +115,9 @@ function file_feeds_set_target(FeedsSource $source, $entity, $target, array $val try { $v->setAllowedExtensions($instance_info['settings']['file_extensions']); $file = $v->getFile($destination); - $field[LANGUAGE_NONE][$delta] += (array) $file; + $field[$language][$delta] += (array) $file; // @todo: Figure out how to properly populate this field. - $field[LANGUAGE_NONE][$delta]['display'] = 1; + $field[$language][$delta]['display'] = 1; } catch (Exception $e) { watchdog('feeds', check_plain($e->getMessage())); diff --git a/mappers/link.inc b/mappers/link.inc index e9c3632..1dc19dc 100644 --- a/mappers/link.inc +++ b/mappers/link.inc @@ -39,10 +39,12 @@ function link_feeds_processor_targets($entity_type, $bundle_name) { /** * Callback for mapping link fields. */ -function link_feeds_set_target(FeedsSource $source, $entity, $target, array $values) { +function link_feeds_set_target(FeedsSource $source, $entity, $target, array $values, array $mapping) { + $language = $mapping['language']; + 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($language => array()); $delta = 0; foreach ($values as $value) { @@ -51,7 +53,7 @@ function link_feeds_set_target(FeedsSource $source, $entity, $target, array $val } if (is_scalar($value)) { - $field['und'][$delta][$column] = (string) $value; + $field[$language][$delta][$column] = (string) $value; } $delta++; } diff --git a/mappers/list.inc b/mappers/list.inc index 8c5dc36..6a30829 100644 --- a/mappers/list.inc +++ b/mappers/list.inc @@ -49,8 +49,10 @@ function list_feeds_processor_targets($entity_type, $bundle_name) { /** * Callback for setting list_boolean fields. */ -function list_feeds_set_boolean_target(FeedsSource $source, $entity, $target, array $values) { - $field = isset($entity->$target) ? $entity->$target : array(LANGUAGE_NONE => array()); +function list_feeds_set_boolean_target(FeedsSource $source, $entity, $target, array $values, array $mapping) { + $language = $mapping['language']; + + $field = isset($entity->$target) ? $entity->$target : array($language => array()); foreach ($values as $value) { @@ -58,7 +60,7 @@ function list_feeds_set_boolean_target(FeedsSource $source, $entity, $target, ar $value = $value->getValue(); } - $field[LANGUAGE_NONE][] = array('value' => (int) (bool) $value); + $field[$language][] = array('value' => (int) (bool) $value); } $entity->$target = $field; diff --git a/mappers/locale.inc b/mappers/locale.inc new file mode 100644 index 0000000..4d18dcc --- /dev/null +++ b/mappers/locale.inc @@ -0,0 +1,90 @@ +processor->entityType(); + $translatable = _locale_feeds_target_is_translatable($entity_type, $mapping['target']); + + $mapping += array('field_language' => LANGUAGE_NONE); + + // This is an invalid configuration that can come from disabling + // entity_translation. + $error = $mapping['field_language'] !== LANGUAGE_NONE && !$translatable; + + // Nothing to see here. + if (!$error && !$translatable) { + return; + } + + if ($error) { + return t('Language: @error', array('@error' => t('Error'))); + } + + $language_options = array(LANGUAGE_NONE => t('Language neutral')) + locale_language_list('name'); + + return t('Language: %lang', array('%lang' => $language_options[$mapping['field_language']])); +} + +function locale_feeds_form_callback(array $mapping, array $target, array $form, array $form_state) { + $form = array(); + + $entity_type = $form_state['build_info']['args'][0]->processor->entityType(); + + $translatable = _locale_feeds_target_is_translatable($entity_type, $mapping['target']); + $mapping += array('field_language' => LANGUAGE_NONE); + + // This is an invalid configuration that can come from disabling + // entity_translation. + $error = $mapping['field_language'] !== LANGUAGE_NONE && !$translatable; + + // Nothing to see here. + if (!$error && !$translatable) { + return $form; + } + + $language_options = array(LANGUAGE_NONE => t('Language neutral')); + + if (!$error) { + $language_options += locale_language_list('name'); + } + + $form['field_language'] = array( + '#type' => 'select', + '#title' => t('Language'), + '#options' => $language_options, + '#default_value' => $mapping['field_language'], + ); + + return $form; +} + +function _locale_feeds_target_is_translatable($entity_type, $target) { + list($field_name) = explode(':', $target, 2); + + $info = field_info_field($field_name); + + return !empty($info) && field_is_translatable($entity_type, $info); +} diff --git a/mappers/number.inc b/mappers/number.inc index 7f9a0d8..406b4f8 100644 --- a/mappers/number.inc +++ b/mappers/number.inc @@ -34,9 +34,11 @@ function number_feeds_processor_targets($entity_type, $bundle_name) { /** * Callback for mapping number fields. */ -function number_feeds_set_target(FeedsSource $source, $entity, $target, array $values) { +function number_feeds_set_target(FeedsSource $source, $entity, $target, array $values, array $mapping) { + $language = $mapping['language']; + // Iterate over all values. - $field = isset($entity->$target) ? $entity->$target : array('und' => array()); + $field = isset($entity->$target) ? $entity->$target : array($language => array()); foreach ($values as $value) { @@ -45,7 +47,7 @@ function number_feeds_set_target(FeedsSource $source, $entity, $target, array $v } if (is_numeric($value)) { - $field['und'][] = array('value' => $value); + $field[$language][] = array('value' => $value); } } diff --git a/mappers/taxonomy.inc b/mappers/taxonomy.inc index 6fbdec6..6fbe3e6 100644 --- a/mappers/taxonomy.inc +++ b/mappers/taxonomy.inc @@ -85,6 +85,8 @@ function taxonomy_feeds_processor_targets($entity_type, $bundle_name) { * Callback for mapping taxonomy terms. */ function taxonomy_feeds_set_target(FeedsSource $source, $entity, $target, array $terms, array $mapping) { + $language = $mapping['language']; + // Add in default values. $mapping += array( 'term_search' => FEEDS_TAXONOMY_SEARCH_TERM_NAME, @@ -118,10 +120,14 @@ function taxonomy_feeds_set_target(FeedsSource $source, $entity, $target, array ->range(0, 1); - $field = isset($entity->$target) ? $entity->$target : array('und' => array()); + $field = isset($entity->$target) ? $entity->$target : array($language => array()); + + if (!isset($field[$language])) { + $field[$language] = array(); + } // Allow for multiple mappings to the same target. - $delta = count($field['und']); + $delta = count($field[$language]); // Iterate over all values. foreach ($terms as $term) { @@ -181,7 +187,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[$language][] = array('tid' => $tid); $delta++; } } diff --git a/mappers/text.inc b/mappers/text.inc index aa9c2e1..1cf76bf 100644 --- a/mappers/text.inc +++ b/mappers/text.inc @@ -49,6 +49,8 @@ function text_feeds_processor_targets($entity_type, $bundle_name) { * Callback for mapping text fields. */ function text_feeds_set_target(FeedsSource $source, $entity, $target, array $values, array $mapping) { + $language = $mapping['language']; + list($field_name, $column) = explode(':', $target . ':value'); if ($column === 'value' && isset($source->importer->processor->config['input_format'])) { @@ -59,7 +61,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($language => array()); // Iterate over all values. $delta = 0; @@ -71,10 +73,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[$language][$delta][$column] = (string) $value; if (isset($mapping['format'])) { - $field['und'][$delta]['format'] = $mapping['format']; + $field[$language][$delta]['format'] = $mapping['format']; } } diff --git a/plugins/FeedsNodeProcessor.inc b/plugins/FeedsNodeProcessor.inc index 2cfdf30..d04d546 100644 --- a/plugins/FeedsNodeProcessor.inc +++ b/plugins/FeedsNodeProcessor.inc @@ -40,7 +40,7 @@ class FeedsNodeProcessor extends FeedsProcessor { $node->type = $this->bundle(); $node->changed = REQUEST_TIME; $node->created = REQUEST_TIME; - $node->language = LANGUAGE_NONE; + $node->language = $this->config['language']; $node->is_new = TRUE; node_object_prepare($node); // Populate properties that are set by node_object_prepare(). diff --git a/plugins/FeedsParser.inc b/plugins/FeedsParser.inc index 8b430c0..7e86e9e 100644 --- a/plugins/FeedsParser.inc +++ b/plugins/FeedsParser.inc @@ -548,13 +548,13 @@ class FeedsDateTimeElement extends FeedsElement { * Helper method for buildDateField(). Build a FeedsDateTimeElement object * from a standard formatted node. */ - protected static function readDateField($entity, $field_name, $delta = 0) { + protected static function readDateField($entity, $field_name, $delta = 0, $language = LANGUAGE_NONE) { $ret = new FeedsDateTimeElement(); - if (isset($entity->{$field_name}['und'][$delta]['date']) && $entity->{$field_name}['und'][$delta]['date'] instanceof FeedsDateTime) { - $ret->start = $entity->{$field_name}['und'][$delta]['date']; + if (isset($entity->{$field_name}[$language][$delta]['date']) && $entity->{$field_name}[$language][$delta]['date'] instanceof FeedsDateTime) { + $ret->start = $entity->{$field_name}[$language][$delta]['date']; } - if (isset($entity->{$field_name}['und'][$delta]['date2']) && $entity->{$field_name}['und'][$delta]['date2'] instanceof FeedsDateTime) { - $ret->end = $entity->{$field_name}['und'][$delta]['date2']; + if (isset($entity->{$field_name}[$language][$delta]['date2']) && $entity->{$field_name}[$language][$delta]['date2'] instanceof FeedsDateTime) { + $ret->end = $entity->{$field_name}[$language][$delta]['date2']; } return $ret; } @@ -569,10 +569,10 @@ class FeedsDateTimeElement extends FeedsElement { * @param int $delta * The delta in the field. */ - public function buildDateField($entity, $field_name, $delta = 0) { + public function buildDateField($entity, $field_name, $delta = 0, $language = LANGUAGE_NONE) { $info = field_info_field($field_name); - $oldfield = FeedsDateTimeElement::readDateField($entity, $field_name, $delta); + $oldfield = FeedsDateTimeElement::readDateField($entity, $field_name, $delta, $language); // Merge with any preexisting objects on the field; we take precedence. $oldfield = $this->merge($oldfield); $use_start = $oldfield->start; @@ -605,27 +605,27 @@ class FeedsDateTimeElement extends FeedsElement { $db_tz = new DateTimeZone($db_tz); if (!isset($entity->{$field_name})) { - $entity->{$field_name} = array('und' => array()); + $entity->{$field_name} = array($language => array()); } if ($use_start) { - $entity->{$field_name}['und'][$delta]['timezone'] = $use_start->getTimezone()->getName(); - $entity->{$field_name}['und'][$delta]['offset'] = $use_start->getOffset(); + $entity->{$field_name}[$language][$delta]['timezone'] = $use_start->getTimezone()->getName(); + $entity->{$field_name}[$language][$delta]['offset'] = $use_start->getOffset(); $use_start->setTimezone($db_tz); - $entity->{$field_name}['und'][$delta]['date'] = $use_start; + $entity->{$field_name}[$language][$delta]['date'] = $use_start; /** * @todo the date_type_format line could be simplified based upon a patch * DO issue #259308 could affect this, follow up on at some point. * Without this, all granularity info is lost. * $use_start->format(date_type_format($field['type'], $use_start->granularity)); */ - $entity->{$field_name}['und'][$delta]['value'] = $use_start->format(date_type_format($info['type'])); + $entity->{$field_name}[$language][$delta]['value'] = $use_start->format(date_type_format($info['type'])); } if ($use_end) { // Don't ever use end to set timezone (for now) - $entity->{$field_name}['und'][$delta]['offset2'] = $use_end->getOffset(); + $entity->{$field_name}[$language][$delta]['offset2'] = $use_end->getOffset(); $use_end->setTimezone($db_tz); - $entity->{$field_name}['und'][$delta]['date2'] = $use_end; - $entity->{$field_name}['und'][$delta]['value2'] = $use_end->format(date_type_format($info['type'])); + $entity->{$field_name}[$language][$delta]['date2'] = $use_end; + $entity->{$field_name}[$language][$delta]['value2'] = $use_end->format(date_type_format($info['type'])); } } } diff --git a/plugins/FeedsProcessor.inc b/plugins/FeedsProcessor.inc index ab0df88..662f595 100644 --- a/plugins/FeedsProcessor.inc +++ b/plugins/FeedsProcessor.inc @@ -719,10 +719,15 @@ abstract class FeedsProcessor extends FeedsPlugin { if (isset($targets[$target]['preprocess_callbacks'])) { foreach ($targets[$target]['preprocess_callbacks'] as $callback) { - call_user_func_array($callback, array($source, $target_item, $target, &$mapping)); + call_user_func_array($callback, array($source, $target_item, $targets[$target], &$mapping)); } } + // Ensure there's always a language set. + if (empty($mapping['language'])) { + $mapping['language'] = LANGUAGE_NONE; + } + // Map the source element's value to the target. // If the mapping specifies a callback method, use the callback instead of // setTargetElement(). @@ -765,6 +770,7 @@ abstract class FeedsProcessor extends FeedsPlugin { 'input_format' => NULL, 'skip_hash_check' => FALSE, 'bundle' => $bundle, + 'language' => LANGUAGE_NONE, ); } @@ -791,6 +797,16 @@ abstract class FeedsProcessor extends FeedsPlugin { ); } + if (module_exists('locale') && !empty($info['entity keys']['language'])) { + $form['language'] = array( + '#type' => 'select', + '#options' => array(LANGUAGE_NONE => t('Language neutral')) + locale_language_list('name'), + '#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/multilingual.csv b/tests/feeds/multilingual.csv new file mode 100644 index 0000000..902dec7 --- /dev/null +++ b/tests/feeds/multilingual.csv @@ -0,0 +1,2 @@ +"guid","title","title_fr","body","body_fr","link","link_fr","number","number_fr","image","image_fr","category","category_fr" +1,"Testing Multilingual Feeds 1","Teste Feeds Multilingue 1","This is the body","Ceci est la corps","http://google.ca","http://google.fr",1000,2000,"public://images/foosball.jpeg","public://images/la fayette.jpeg","News","Nouvelles" diff --git a/tests/feeds_mapper_multilingual_fields.test b/tests/feeds_mapper_multilingual_fields.test new file mode 100644 index 0000000..3620c31 --- /dev/null +++ b/tests/feeds_mapper_multilingual_fields.test @@ -0,0 +1,223 @@ + 'Mapper: Multilingual fields', + 'description' => 'Tests Feeds multilingual support.', + 'group' => 'Feeds', + 'dependencies' => array('entity_translation'), + ); + } + + public function setUp() { + $modules = array( + 'locale', + 'entity_translation', + 'link', + 'number', + ); + + $permissions = array( + 'administer entity translation', + 'translate any entity', + 'administer languages', + ); + + parent::setUp($modules, $permissions); + + // Add Categories vocabulary. + $edit = array( + 'name' => 'Categories', + 'machine_name' => 'categories', + ); + $this->drupalPost('admin/structure/taxonomy/add', $edit, 'Save'); + + // Create content type. + $typename = $this->createContentType(array(), + array( + 'number' => 'number_integer', + 'link' => 'link_field', + 'image' => 'image', + ) + ); + + // Create term reference field. + $field = array( + 'field_name' => 'field_category', + 'type' => 'taxonomy_term_reference', + 'cardinality' => FIELD_CARDINALITY_UNLIMITED, + 'settings' => array( + 'allowed_values' => array( + array( + 'vocabulary' => 'categories', + 'parent' => 0, + ), + ), + ), + ); + field_create_field($field); + + // Add term reference field to article bundle. + $this->instance = array( + 'field_name' => 'field_category', + 'bundle' => $typename, + 'entity_type' => 'node', + 'widget' => array( + 'type' => 'options_select', + ), + 'display' => array( + 'default' => array( + 'type' => 'taxonomy_term_reference_link', + ), + ), + ); + field_create_instance($this->instance); + + $this->setupMultilingual($typename); + + // Copy directory of source files, CSV file expects them in public://images. + $this->copyDir($this->absolutePath() . '/tests/feeds/assets', 'public://images'); + + // Create an importer configuration with basic mapping. + $this->createImporterConfiguration('Test multilingual fields import from CSV', 'node'); + $this->setPlugin('node', 'FeedsCSVParser'); + $this->setPlugin('node', 'FeedsFileFetcher'); + $this->setSettings('node', NULL, array('content_type' => '')); + $this->setSettings('node', 'FeedsNodeProcessor', array('bundle' => $typename, 'language' => 'en')); + $this->addMappings('node', array( + 0 => array( + 'source' => 'guid', + 'target' => 'guid', + 'unique' => TRUE, + ), + 1 => array( + 'source' => 'title', + 'target' => 'title', + ), + 2 => array( + 'source' => 'body', + 'target' => 'body', + 'field_language' => 'en', + ), + 3 => array( + 'source' => 'body_fr', + 'target' => 'body', + 'field_language' => 'fr', + ), + 4 => array( + 'source' => 'number', + 'target' => 'field_number', + 'field_language' => 'en', + ), + 5 => array( + 'source' => 'number_fr', + 'target' => 'field_number', + 'field_language' => 'fr', + ), + 6 => array( + 'source' => 'link', + 'target' => 'field_link:url', + 'field_language' => 'en', + ), + 7 => array( + 'source' => 'link_fr', + 'target' => 'field_link:url', + 'field_language' => 'fr', + ), + 8 => array( + 'source' => 'image', + 'target' => 'field_image:uri', + 'field_language' => 'en', + ), + 9 => array( + 'source' => 'image_fr', + 'target' => 'field_image:uri', + 'field_language' => 'fr', + ), + 10 => array( + 'source' => 'category', + 'target' => 'field_category', + 'field_language' => 'en', + 'autocreate' => TRUE, + ), + 11 => array( + 'source' => 'category_fr', + 'target' => 'field_category', + 'field_language' => 'fr', + 'autocreate' => TRUE, + ), + )); + } + + /** + * Tests multilingual mappings to translatable fields (entity translation) + */ + public function testMultilingualFieldMappings() { + $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual.csv'); + $this->assertText(t('Created 1 node')); + + // @todo Figure out why this is required for the node to contain the French + // translation. + $this->drupalGet('node/1/translate'); + + $node = node_load(1); + + $this->assertEqual('This is the body', $node->body['en'][0]['value'], 'English body field has expected value.'); + $this->assertEqual(1000, $node->field_number['en'][0]['value'], 'English field_number field has expected value.'); + $this->assertEqual('http://google.ca', $node->field_link['en'][0]['url'], 'English field_link field has expected value.'); + $this->assertEqual('foosball.jpeg', $node->field_image['en'][0]['filename'], 'English field_image field has expected value.'); + $this->assertEqual(1, $node->field_category['en'][0]['tid'], 'English field_category field has expected value.'); + + $this->assertEqual('Ceci est la corps', $node->body['fr'][0]['value'], 'French body field has expected value.'); + $this->assertEqual(2000, $node->field_number['fr'][0]['value'], 'French field_number field has expected value.'); + $this->assertEqual('http://google.fr', $node->field_link['fr'][0]['url'], 'French field_link field has expected value.'); + $this->assertEqual('la fayette.jpeg', $node->field_image['fr'][0]['filename'], 'French field_image field has expected value.'); + $this->assertEqual(2, $node->field_category['fr'][0]['tid'], 'French field_category field has expected value.'); + } + + /** + * Configures Drupal to be multilingual. + */ + public function setupMultilingual($typename) { + // Setup Other Language (french). + $edit = array( + 'langcode' => 'fr', + ); + $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language')); + $this->assertText(t('The language French has been created and can now be used.')); + + // Enable entity field translation for content type. + $edit = array( + 'language_content_type' => 4, + 'entity_translation_hide_translation_links' => 1, + 'entity_translation_node_metadata' => 0, + ); + $this->drupalPost('admin/structure/types/manage/' . $typename, $edit, t('Save content type')); + + // Enable field translation on fields. + $edit = array( + 'field[translatable]' => 1, + ); + $field_names = array( + 'body' => 'body', + 'field_number' => 'field_number', + 'field_link' => 'field_link', + 'field_image' => 'field_image', + 'field_category' => 'field_category', + ); + foreach ($field_names as $field_name) { + $this->drupalPost("admin/structure/types/manage/{$typename}/fields/{$field_name}", $edit, t('Save settings')); + } + } + +} diff --git a/tests/feeds_mapper_taxonomy.test b/tests/feeds_mapper_taxonomy.test index 231235e..801b2d0 100644 --- a/tests/feeds_mapper_taxonomy.test +++ b/tests/feeds_mapper_taxonomy.test @@ -234,6 +234,7 @@ class FeedsMapperTaxonomyTestCase extends FeedsMapperTestCase { $target = 'field_tags'; $mapping = array( 'term_search' => FEEDS_TAXONOMY_SEARCH_TERM_ID, + 'language' => LANGUAGE_NONE, ); $source = FeedsSource::instance('tmp', 0); @@ -284,6 +285,7 @@ class FeedsMapperTaxonomyTestCase extends FeedsMapperTestCase { $target = 'field_tags'; $mapping = array( 'term_search' => FEEDS_TAXONOMY_SEARCH_TERM_GUID, + 'language' => LANGUAGE_NONE, ); $source = FeedsSource::instance('tmp', 0); diff --git a/tests/feeds_tests.info b/tests/feeds_tests.info index df368ca..13fef97 100644 --- a/tests/feeds_tests.info +++ b/tests/feeds_tests.info @@ -6,4 +6,5 @@ core = 7.x test_dependencies[] = date test_dependencies[] = feeds_xpathparser test_dependencies[] = link +test_dependencies[] = entity_translation hidden = TRUE diff --git a/tests/feeds_tests.module b/tests/feeds_tests.module index 1ddd2a6..a083df0 100644 --- a/tests/feeds_tests.module +++ b/tests/feeds_tests.module @@ -307,7 +307,7 @@ class FeedsTestsPreprocess { * * @see feeds_tests_feeds_processor_targets() */ - public static function callback(FeedsSource $source, $target_item, $target, array &$mapping) { + public static function callback(FeedsSource $source, $target_item, array $target, array &$mapping) { $mapping['required_value'] = TRUE; }