Origin: vendor
Forwarded: not-needed
From: Gunnar Wolf <gwolf@debian.org>
Last-Update: 2014-11-21
Description: Avoid data loss on entities with revisions due to wrong return code
 Fixed a bug in which field_has_data() did not return TRUE for fields that
 only had data in older entity revisions, leading to loss of the field's data
 when the field configuration was edited.
 .
 Fixes Drupal issue #2278583
 .
 Backported from 7.33.
Index: drupal7/modules/field/field.module
===================================================================
--- drupal7.orig/modules/field/field.module
+++ drupal7/modules/field/field.module
@@ -947,14 +947,17 @@ function field_get_items($entity_type, $
  */
 function field_has_data($field) {
   $query = new EntityFieldQuery();
-  return (bool) $query
-    ->fieldCondition($field)
+  $query = $query->fieldCondition($field)
     ->range(0, 1)
     ->count()
     // Neutralize the 'entity_field_access' query tag added by
     // field_sql_storage_field_storage_query(). The result cannot depend on the
     // access grants of the current user.
-    ->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT')
+    ->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT');
+
+  return (bool) $query
+    ->execute() || (bool) $query
+    ->age(FIELD_LOAD_REVISION)
     ->execute();
 }
 
Index: drupal7/modules/field/tests/field.test
===================================================================
--- drupal7.orig/modules/field/tests/field.test
+++ drupal7/modules/field/tests/field.test
@@ -485,6 +485,66 @@ class FieldAttachStorageTestCase extends
   }
 
   /**
+   * Test field_has_data().
+   */
+  function testFieldHasData() {
+    $entity_type = 'test_entity';
+    $langcode = LANGUAGE_NONE;
+
+    $field_name = 'field_1';
+    $field = array('field_name' => $field_name, 'type' => 'test_field');
+    $field = field_create_field($field);
+
+    $this->assertFalse(field_has_data($field), "No data should be detected.");
+
+    $instance = array(
+      'field_name' => $field_name,
+      'entity_type' => 'test_entity',
+      'bundle' => 'test_bundle'
+    );
+    $instance = field_create_instance($instance);
+    $table = _field_sql_storage_tablename($field);
+    $revision_table = _field_sql_storage_revision_tablename($field);
+
+    $columns = array('entity_type', 'entity_id', 'revision_id', 'delta', 'language', $field_name . '_value');
+
+    $eid = 0;
+
+    // Insert values into the field revision table.
+    $query = db_insert($revision_table)->fields($columns);
+    $query->values(array($entity_type, $eid, 0, 0, $langcode, 1));
+    $query->execute();
+
+    $this->assertTrue(field_has_data($field), "Revision data only should be detected.");
+
+    $field_name = 'field_2';
+    $field = array('field_name' => $field_name, 'type' => 'test_field');
+    $field = field_create_field($field);
+
+    $this->assertFalse(field_has_data($field), "No data should be detected.");
+
+    $instance = array(
+      'field_name' => $field_name,
+      'entity_type' => 'test_entity',
+      'bundle' => 'test_bundle'
+    );
+    $instance = field_create_instance($instance);
+    $table = _field_sql_storage_tablename($field);
+    $revision_table = _field_sql_storage_revision_tablename($field);
+
+    $columns = array('entity_type', 'entity_id', 'revision_id', 'delta', 'language', $field_name . '_value');
+
+    $eid = 1;
+
+    // Insert values into the field table.
+    $query = db_insert($table)->fields($columns);
+    $query->values(array($entity_type, $eid, 0, 0, $langcode, 1));
+    $query->execute();
+
+    $this->assertTrue(field_has_data($field), "Values only in field table should be detected.");
+  }
+
+  /**
    * Test field_attach_delete().
    */
   function testFieldAttachDelete() {
