? MISC-FIELD-CHANGES-REAPPLY.patch
? Makefile
? d6-50-nodes.sql.gz
? d7-50-nodes-new.sql.gz
? d7-50-nodes.sql.gz
? head.kpf
? patches
? modules/field/field.bulk.update.inc
? scripts/OLD-generate-autoload.pl
? scripts/generate-autoload.pl
? sites/all/cck
? sites/all/modules/color
? sites/all/modules/combofield
? sites/all/modules/devel
? sites/all/modules/pbs
? sites/all/modules/taint
? sites/default/files
? sites/default/private
? sites/default/settings.php
Index: modules/field/field.attach.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.attach.inc,v
retrieving revision 1.86
diff -u -F '^[fc]' -r1.86 field.attach.inc
--- modules/field/field.attach.inc	4 Apr 2010 12:48:18 -0000	1.86
+++ modules/field/field.attach.inc	22 Apr 2010 23:46:08 -0000
@@ -1168,6 +1168,65 @@ function field_attach_query_revisions($f
 }
 
 /**
+ * Update entities matching a given set of conditions.
+ *
+ * Note that the query 'conditions' only apply to the stored values.
+ *
+ * @param $field_id
+ *   The id of the field to query.
+ * @param $conditions
+ *   An array of query conditions. @see field_attach_query().
+ * @param $fields
+ *   An associative array of fields to write into the database. The array keys
+ *   are the field names while the values are the values to which to set them.
+ * @param $options
+ *   An associative array of additional options:
+ *   - age: Internal use only. Use field_attach_query_revisions() instead of
+ *     passing FIELD_LOAD_REVISION.
+ *     - FIELD_LOAD_CURRENT (default): query the most recent revisions for all
+ *       entities. The results will be keyed by entity type and entity id.
+ *     - FIELD_LOAD_REVISION: query all revisions. The results will be keyed by
+ *       entity type and entity revision id.
+ */
+function field_attach_bulk_update($field_id, $conditions, $fields, $options = array()) {
+  // Merge in default options.
+  $default_options = array(
+    'age' => FIELD_LOAD_CURRENT,
+  );
+  $options += $default_options;
+
+  // Give a chance to 3rd party modules that bypass the storage engine to
+  // handle the query.
+  $skip_field = FALSE;
+  foreach (module_implements('field_storage_pre_bulk_update') as $module) {
+    $function = $module . '_field_storage_pre_bulk_update';
+    $results = $function($field_id, $conditions, $fields, $options, $skip_field);
+    // Stop as soon as a module claims it handled the query.
+    if ($skip_field) {
+      break;
+    }
+  }
+  // If the request hasn't been handled, let the storage engine handle it.
+  if (!$skip_field) {
+    $field = field_info_field_by_id($field_id);
+    $function = $field['storage']['module'] . '_field_storage_bulk_update';
+    $results = $function($field_id, $conditions, $fields, $options);
+  }
+
+  return $results;
+}
+
+/**
+ * Update entity revisions matching a given set of conditions.
+ *
+ * @see field_attach_bulk_update() for more information.
+ */
+function field_attach_bulk_update_revisions($field_id, $conditions, $fields, $options = array()) {
+  $options['age'] = FIELD_LOAD_REVISION;
+  return field_attach_query($field_id, $conditions, $fields, $options);
+}
+
+/**
  * Prepare field data prior to display.
  *
  * This function must be called before field_attach_view(). It lets field
Index: modules/field/modules/field_sql_storage/field_sql_storage.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/field_sql_storage/field_sql_storage.module,v
retrieving revision 1.44
diff -u -F '^[fc]' -r1.44 field_sql_storage.module
--- modules/field/modules/field_sql_storage/field_sql_storage.module	27 Mar 2010 05:52:49 -0000	1.44
+++ modules/field/modules/field_sql_storage/field_sql_storage.module	22 Apr 2010 23:46:08 -0000
@@ -470,20 +470,20 @@ function field_sql_storage_field_storage
 }
 
 /**
- * Implements hook_field_storage_query().
+ * Add conditions to a query.
+ *
+ * @param $field
+ *   The field that the query is querying.
+ * @param $query
+ *   The Query object.
+ * @param $conditions
+ *   The query conditions as passed to field_attach_query() or
+ *   field_attach_bulk_update().
  */
-function field_sql_storage_field_storage_query($field_id, $conditions, $options) {
-  $load_current = $options['age'] == FIELD_LOAD_CURRENT;
-
-  $field = field_info_field_by_id($field_id);
+function _field_sql_storage_add_conditions($field, $query, $conditions) {
   $field_name = $field['field_name'];
-  $table = $load_current ? _field_sql_storage_tablename($field) : _field_sql_storage_revision_tablename($field);
   $field_columns = array_keys($field['columns']);
 
-  // Build the query.
-  $query = db_select($table, 't');
-  $query->join('field_config_entity_type', 'e', 't.etid = e.etid');
-
   // Add conditions.
   foreach ($conditions as $condition) {
     // A condition is either a (column, value, operator) triple, or a
@@ -536,6 +536,24 @@ function field_sql_storage_field_storage
   if (!isset($condition_deleted)) {
     $query->condition('deleted', 0);
   }
+}
+
+/**
+ * Implements hook_field_storage_query().
+ */
+function field_sql_storage_field_storage_query($field_id, $conditions, $options) {
+  $load_current = $options['age'] == FIELD_LOAD_CURRENT;
+
+  $field = field_info_field_by_id($field_id);
+  $field_name = $field['field_name'];
+  $table = $load_current ? _field_sql_storage_tablename($field) : _field_sql_storage_revision_tablename($field);
+  $field_columns = array_keys($field['columns']);
+
+  // Build the query.
+  $query = db_select($table, 't');
+  $query->join('field_config_entity_type', 'e', 't.etid = e.etid');
+
+  _field_sql_storage_add_conditions($field, $query, $conditions);
 
   // For a count query, return the count now.
   if ($options['count']) {
@@ -596,6 +614,39 @@ function field_sql_storage_field_storage
 }
 
 /**
+ * Implements hook_field_storage_query().
+ */
+function field_sql_storage_field_storage_bulk_update($field_id, $conditions, $columns, $options) {
+  $load_current = $options['age'] == FIELD_LOAD_CURRENT;
+
+  $field = field_info_field_by_id($field_id);
+  $table = $load_current ? _field_sql_storage_tablename($field) : _field_sql_storage_revision_tablename($field);
+
+  // Build the query.
+  $query = db_update($table);
+
+  // TODO. _add_conditions assumes we've joined to f_c_e_t, but we
+  // can't on an update query, so we can't query on type.
+  // $query->join('field_config_entity_type', 'e', 't.etid = e.etid');
+
+  _field_sql_storage_add_conditions($field, $query, $conditions);
+
+  // Translate field columns into prefixed db columns.
+  $field_name = $field['field_name'];
+  $field_columns = array_keys($field['columns']);
+  $translated = array();
+  foreach ($columns as $column => $value) {
+    if (in_array($column, $field_columns)) {
+      $column = _field_sql_storage_columnname($field_name, $column);
+    }
+    $translated[$column] = $value;
+  }
+
+  $query->fields($translated);
+  $query->execute();
+}
+
+/**
  * Implements hook_field_storage_delete_revision().
  *
  * This function actually deletes the data from the database.
Index: modules/field/modules/text/text.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/text/text.module,v
retrieving revision 1.53
diff -u -F '^[fc]' -r1.53 text.module
--- modules/field/modules/text/text.module	13 Apr 2010 15:16:27 -0000	1.53
+++ modules/field/modules/text/text.module	22 Apr 2010 23:46:08 -0000
@@ -590,3 +590,32 @@ function text_field_widget_error($elemen
   form_error($error_element, $error['message']);
 }
 
+/**
+ * Implements hook_filter_format_update().
+ *
+ * When a text format is updated, invalidate the field data cache. We
+ * could try to be more clever and only invalid selected cache
+ * elements, but input formats are not deleted that often.
+ */
+function text_filter_format_update($format) {
+  field_cache_clear();
+}
+
+
+/**
+ * Implements hook_filter_format_delete().
+ *
+ * When a text format is deleted, update all text fields using the old
+ * format to use its replacement format.
+ */
+function text_filter_format_delete($format, $fallback) {
+  $fields = field_info_fields();
+  foreach ($fields as $field_name => $field) {
+    if ($field['module'] == 'text') {
+      field_attach_bulk_update($field['id'], array(array('format', $format->format)), array('format' => $fallback->format));
+      field_attach_bulk_update_revisions($field['id'], array(array('format', $format->format)), array('format' => $fallback->format));
+    }
+  }
+  field_cache_clear();
+}
+
Index: modules/field/modules/text/text.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/text/text.test,v
retrieving revision 1.22
diff -u -F '^[fc]' -r1.22 text.test
--- modules/field/modules/text/text.test	10 Apr 2010 10:01:15 -0000	1.22
+++ modules/field/modules/text/text.test	22 Apr 2010 23:46:08 -0000
@@ -216,6 +216,14 @@ class TextFieldTestCase extends DrupalWe
     $entity->content = field_attach_view($entity_type, $entity);
     $this->content = drupal_render($entity->content);
     $this->assertRaw($value, t('Value is displayed unfiltered'));
+
+    // Delete the text format and verify the field content renders in
+    // plain text.
+    filter_format_delete(filter_format_load($format_id));
+    $entity = field_test_entity_test_load($id);
+    $entity->content = field_attach_view($entity_type, $entity);
+    $this->content = drupal_render($entity->content);
+    $this->assertRaw(check_plain($value), t('Value is displayed in plain text when text format is deleted'));
   }
 }
 
