diff --git a/mappers/locale.inc b/mappers/locale.inc
index d23ad93..bc0799b 100644
--- a/mappers/locale.inc
+++ b/mappers/locale.inc
@@ -17,7 +17,7 @@ function locale_feeds_processor_targets_alter(array &$targets, $entity_type, $bu
}
/**
- * Preprocess callback that set's the configured mapping language.
+ * Preprocess callback that sets the configured mapping language.
*/
function locale_feeds_preprocess_callback(FeedsSource $source, $target_item, array $target, array &$mapping) {
if (empty($mapping['field_language'])) {
@@ -36,9 +36,19 @@ function locale_feeds_summary_callback(array $mapping, array $target, array $for
$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;
+ $language_options = array(LANGUAGE_NONE => t('Language neutral')) + locale_language_list('name');
+
+ $error = NULL;
+ if ($mapping['field_language'] !== LANGUAGE_NONE && !$translatable) {
+ // This is an invalid configuration that can come from disabling
+ // entity_translation.
+ $error = t('Field not translatable');
+ }
+ if (!isset($language_options[$mapping['field_language']])) {
+ // This is an invalid configuration that can be caused by disabling or
+ // removing the language in question.
+ $error = t('Language @lang not available', array('@lang' => $mapping['field_language']));
+ }
// Nothing to see here.
if (!$error && !$translatable) {
@@ -46,11 +56,9 @@ function locale_feeds_summary_callback(array $mapping, array $target, array $for
}
if ($error) {
- return t('Language: @error', array('@error' => t('Error')));
+ return t('Language: Error: @error', array('@error' => $error));
}
- $language_options = array(LANGUAGE_NONE => t('Language neutral')) + locale_language_list('name');
-
return t('Language: %lang', array('%lang' => $language_options[$mapping['field_language']]));
}
diff --git a/plugins/FeedsProcessor.inc b/plugins/FeedsProcessor.inc
index 12f2e65..9e9d081 100644
--- a/plugins/FeedsProcessor.inc
+++ b/plugins/FeedsProcessor.inc
@@ -786,6 +786,13 @@ abstract class FeedsProcessor extends FeedsPlugin {
if (empty($mapping['language'])) {
$mapping['language'] = LANGUAGE_NONE;
}
+ else {
+ // Check if the configured language is available. If not, fallback to LANGUAGE_NONE.
+ $languages = language_list('enabled');
+ if (!isset($languages[1][$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
diff --git a/tests/feeds/multilingual.csv b/tests/feeds/multilingual.csv
deleted file mode 100644
index 8bf5b99..0000000
--- a/tests/feeds/multilingual.csv
+++ /dev/null
@@ -1 +0,0 @@
-"guid","title_en","title_fr","body_en","body_fr","date_en","date_fr","datestamp_en","datestamp_fr","datetime_en","datetime_fr","image_en","image_fr","image_alt_en","image_alt_fr","image_title_en","image_title_fr","link_en","link_fr","number_decimal_en","number_decimal_fr","number_float_en","number_float_fr","number_integer_en","number_integer_fr","term_en","term_fr","text_en","text_fr"
1,"Testing Multilingual Feeds 1","Teste Feeds Multilingue 1","This is the body","Ceci est la corps","21-10-2015","05-11-1955",1445470140,-446731187,"21-10-2015 23:29","1955-11-05 12:00:13","public://images/foosball.jpeg","public://images/la fayette.jpeg","Foosball","La Fayette","Foosball played by two guys","la Fayette dans les bois","http://google.ca","http://google.fr",4.2,1.2,3.1416,5.6295,1000,2000,"News","Nouvelles","Carrots","Carottes"
\ No newline at end of file
diff --git a/tests/feeds/multilingual_empty.csv b/tests/feeds/multilingual_empty.csv
new file mode 100644
index 0000000..33e5706
--- /dev/null
+++ b/tests/feeds/multilingual_empty.csv
@@ -0,0 +1,2 @@
+"guid","title","body","date","datestamp","datetime","image","image_alt","image_title","link","number_decimal","number_float","number_integer","term","text"
+1,,,,,,,,,,,,,,
\ No newline at end of file
diff --git a/tests/feeds/multilingual_en_fr.csv b/tests/feeds/multilingual_en_fr.csv
new file mode 100644
index 0000000..8bf5b99
--- /dev/null
+++ b/tests/feeds/multilingual_en_fr.csv
@@ -0,0 +1 @@
+"guid","title_en","title_fr","body_en","body_fr","date_en","date_fr","datestamp_en","datestamp_fr","datetime_en","datetime_fr","image_en","image_fr","image_alt_en","image_alt_fr","image_title_en","image_title_fr","link_en","link_fr","number_decimal_en","number_decimal_fr","number_float_en","number_float_fr","number_integer_en","number_integer_fr","term_en","term_fr","text_en","text_fr"
1,"Testing Multilingual Feeds 1","Teste Feeds Multilingue 1","This is the body","Ceci est la corps","21-10-2015","05-11-1955",1445470140,-446731187,"21-10-2015 23:29","1955-11-05 12:00:13","public://images/foosball.jpeg","public://images/la fayette.jpeg","Foosball","La Fayette","Foosball played by two guys","la Fayette dans les bois","http://google.ca","http://google.fr",4.2,1.2,3.1416,5.6295,1000,2000,"News","Nouvelles","Carrots","Carottes"
\ No newline at end of file
diff --git a/tests/feeds/multilingual_en_fr_empty.csv b/tests/feeds/multilingual_en_fr_empty.csv
new file mode 100644
index 0000000..223548e
--- /dev/null
+++ b/tests/feeds/multilingual_en_fr_empty.csv
@@ -0,0 +1 @@
+"guid","title_en","title_fr","body_en","body_fr","date_en","date_fr","datestamp_en","datestamp_fr","datetime_en","datetime_fr","image_en","image_fr","image_alt_en","image_alt_fr","image_title_en","image_title_fr","link_en","link_fr","number_decimal_en","number_decimal_fr","number_float_en","number_float_fr","number_integer_en","number_integer_fr","term_en","term_fr","text_en","text_fr"
1,,"Teste Feeds Multilingue 1",,"Ceci est la corps",,"05-11-1955",,-446731187,,"1955-11-05 12:00:13",,"public://images/la fayette.jpeg",,"La Fayette",,"la Fayette dans les bois",,"http://google.fr",,1.2,,5.6295,,2000,,"Nouvelles",,"Carottes"
\ No newline at end of file
diff --git a/tests/feeds_mapper_multilingual_fields.test b/tests/feeds_mapper_multilingual_fields.test
index a37389a..28b6e29 100644
--- a/tests/feeds_mapper_multilingual_fields.test
+++ b/tests/feeds_mapper_multilingual_fields.test
@@ -5,19 +5,10 @@
* Contains FeedsMapperMultilingualFieldsTestCase.
*
* @todo
- * - All tests
+ * - testAutocreatedTermLanguage()
* - Language for created terms is not set.
- * - Figure out why going to node/1/translate is required for translations to
- * be available.
- * - testChangedLanguageImport()
- * - Dutch values are removed after importing French values.
- * - testChangedLanguageImportForExistingNode()
- * - Dutch values are removed after importing French values.
- * - testDisabledLanguage()
- * - Values are not imported in LANGUAGE_NONE after disabling French language.
- * - Error messages on the mapping screen.
- * - testRemovedLanguage()
- * - Values are not imported in LANGUAGE_NONE after removing French language.
+ * - testClearOutValuesWithDisabledLanguage()
+ * - Values aren't cleared when configured language is no longer available.
*/
/**
@@ -206,13 +197,9 @@ class FeedsMapperMultilingualFieldsTestCase extends FeedsMapperTestCase {
$this->addMappings('node', $mappings);
// Import file that has items with both English and French field values.
- $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual.csv');
+ $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_en_fr.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');
-
// Load node.
$node = node_load(1, NULL, TRUE);
@@ -257,7 +244,6 @@ class FeedsMapperMultilingualFieldsTestCase extends FeedsMapperTestCase {
$this->assertText(t('Created 1 node'));
// Assert that Dutch values were created.
- $this->drupalGet('node/1/translate');
$node = node_load(1, NULL, TRUE);
$dutch = $this->getDutchValues($node) + array(
'field_category' => array(
@@ -287,7 +273,6 @@ class FeedsMapperMultilingualFieldsTestCase extends FeedsMapperTestCase {
$this->assertText(t('Updated 1 node'));
// Assert that French values were created.
- $this->drupalGet('node/1/translate');
$node = node_load(1, NULL, TRUE);
$french = $this->getFrenchValues($node) + array(
'field_category' => array(
@@ -403,7 +388,6 @@ class FeedsMapperMultilingualFieldsTestCase extends FeedsMapperTestCase {
$this->assertText(t('Updated 1 node'));
// Assert that French values were created.
- $this->drupalGet('node/1/translate');
$node = node_load(1, NULL, TRUE);
$french = $this->getFrenchValues($node) + array(
'field_category' => array(
@@ -452,7 +436,6 @@ class FeedsMapperMultilingualFieldsTestCase extends FeedsMapperTestCase {
$this->assertText(t('Created 1 node'));
// Assert that the fields were all created in French.
- $this->drupalGet('node/1/translate');
$node = node_load(1, NULL, TRUE);
$french = $this->getFrenchValues($node) + array(
'field_category' => array(
@@ -489,7 +472,6 @@ class FeedsMapperMultilingualFieldsTestCase extends FeedsMapperTestCase {
$this->assertText(t('Created 1 node'));
// Assert that the fields were all created in French.
- $this->drupalGet('node/1/translate');
$node = node_load(1, NULL, TRUE);
$french = $this->getFrenchValues($node) + array(
'field_category' => array(
@@ -528,7 +510,6 @@ class FeedsMapperMultilingualFieldsTestCase extends FeedsMapperTestCase {
$this->assertText(t('Created 1 node'));
// Assert that the fields were all created in LANGUAGE_NONE.
- $this->drupalGet('node/1/translate');
$node = node_load(1, NULL, TRUE);
$french = $this->getFrenchValues($node, LANGUAGE_NONE) + array(
'field_category' => array(
@@ -561,7 +542,6 @@ class FeedsMapperMultilingualFieldsTestCase extends FeedsMapperTestCase {
$this->assertText(t('Created 1 node'));
// Assert that the fields were all created in LANGUAGE_NONE.
- $this->drupalGet('node/1/translate');
$node = node_load(1, NULL, TRUE);
$french = $this->getFrenchValues($node, LANGUAGE_NONE) + array(
'field_category' => array(
@@ -611,6 +591,136 @@ class FeedsMapperMultilingualFieldsTestCase extends FeedsMapperTestCase {
}
/**
+ * Tests if values are cleared out when an empty value or no value is
+ * provided.
+ */
+ public function testClearOutValues() {
+ // Set to update existing nodes.
+ $this->setSettings('node', 'FeedsNodeProcessor', array(
+ 'update_existing' => FEEDS_UPDATE_EXISTING,
+ ));
+
+ // Add English mappers.
+ $index = 2;
+ $mappings = $this->getMappingsInLanguage('en', $index);
+ // Append "_en" to each source name.
+ foreach ($mappings as &$mapping) {
+ $mapping['source'] .= '_en';
+ }
+ $this->addMappings('node', $mappings);
+ $index += count($mappings);
+
+ // Add French mappers.
+ $mappings = $this->getMappingsInLanguage('fr', $index);
+ // Append "_fr" to each source name.
+ foreach ($mappings as &$mapping) {
+ $mapping['source'] .= '_fr';
+ }
+ $this->addMappings('node', $mappings);
+
+ // Import file that has items with both English and French field values.
+ $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_en_fr.csv');
+ $this->assertText(t('Created 1 node'));
+
+ // Now import a file where the French remained, but the English values were
+ // removed.
+ $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_en_fr_empty.csv');
+ $this->assertText(t('Updated 1 node'));
+
+ // Load node.
+ $node = node_load(1, NULL, TRUE);
+
+ // Check that the English values are gone, but the French values are still
+ // there.
+ $fields = array(
+ 'body',
+ 'field_date',
+ 'field_datestamp',
+ 'field_datetime',
+ 'field_image',
+ 'field_link',
+ 'field_number_decimal',
+ 'field_number_float',
+ 'field_number_integer',
+ 'field_category',
+ 'field_text',
+ );
+ foreach ($fields as $field_name) {
+ $this->assertTrue(empty($node->{$field_name}['en']), format_string('The field %field is empty.', array('%field' => $field_name)));
+ }
+
+ // Inspect availability of French values.
+ // @todo field_image has "la fayette_0.jpeg."
+ $french = $this->getFrenchValues($node) + array(
+ 'field_category' => array(
+ 'expected' => 2,
+ 'actual' => $node->field_category['fr'][0]['tid'],
+ ),
+ );
+ foreach ($french as $field_name => $value) {
+ $this->assertEqual($value['expected'], $value['actual'], format_string('The French field %field has the expected value (actual: @actual).', array('%field' => $field_name, '@actual' => $value['actual'])));
+ }
+ }
+
+ /**
+ * Tests if values are cleared out when an empty value is provided for a
+ * language that got disabled.
+ */
+ public function testClearOutValuesWithDisabledLanguage() {
+ // Set to update existing nodes.
+ $this->setSettings('node', 'FeedsNodeProcessor', array(
+ 'update_existing' => FEEDS_UPDATE_EXISTING,
+ ));
+
+ // Configure importer to import in French language.
+ $this->setSettings('node', 'FeedsNodeProcessor', array(
+ 'language' => 'fr',
+ ));
+ $this->addMappings('node', $this->getMappingsInLanguage('fr'));
+
+ // Now disable the French language.
+ $path = 'admin/config/regional/language';
+ $edit = array(
+ 'enabled[fr]' => FALSE,
+ );
+ $this->drupalPost($path, $edit, t('Save configuration'));
+
+ // Ensure no error messages are shown on the mappings page.
+ $this->drupalGet('admin/structure/feeds/node/mapping');
+
+ // Import content. Since the French language was disabled, the content
+ // should be imported as LANGUAGE_NONE.
+ // @see ::testDisabledLanguage()
+ $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_fr.csv');
+ $this->assertText(t('Created 1 node'));
+
+ // Now import a file with empty values.
+ $this->importFile('node', $this->absolutePath() . '/tests/feeds/multilingual_empty.csv');
+ $this->assertText(t('Updated 1 node'));
+
+ // Load node.
+ $node = node_load(1, NULL, TRUE);
+
+ // Check that the values in LANGUAGE_NONE are gone.
+ $fields = array(
+ 'body',
+ 'field_date',
+ 'field_datestamp',
+ 'field_datetime',
+ 'field_image',
+ 'field_link',
+ 'field_number_decimal',
+ 'field_number_float',
+ 'field_number_integer',
+ 'field_category',
+ 'field_text',
+ );
+ foreach ($fields as $field_name) {
+ $this->assertTrue(empty($node->{$field_name}[LANGUAGE_NONE]), format_string('The field %field is empty.', array('%field' => $field_name)));
+ }
+ }
+
+ /**
* Adds a language to test with.
*
* @param string $langcode
@@ -650,6 +760,10 @@ class FeedsMapperMultilingualFieldsTestCase extends FeedsMapperTestCase {
foreach ($field_names as $field_name) {
$this->drupalPost("admin/structure/types/manage/{$typename}/fields/{$field_name}", $edit, t('Save settings'));
}
+
+ // Reset static cache so that all languages are available when
+ // field_available_languages() is called during node_load().
+ drupal_static_reset();
}
/**