'Stores information about field collection items.', 'fields' => array( 'item_id' => array( 'type' => 'serial', 'not null' => TRUE, 'description' => 'Primary Key: Unique field collection item ID.', ), 'revision_id' => array( 'type' => 'int', 'not null' => TRUE, 'description' => 'Default revision ID.', ), 'field_name' => array( 'description' => 'The name of the field on the host entity embedding this entity.', 'type' => 'varchar', 'length' => 32, 'not null' => TRUE, ), 'archived' => array( 'description' => 'Boolean indicating whether the field collection item is archived.', 'type' => 'int', 'not null' => TRUE, 'default' => 0, ), ), 'primary key' => array('item_id'), ); $schema['field_collection_item_revision'] = array( 'description' => 'Stores revision information about field collection items.', 'fields' => array( 'revision_id' => array( 'type' => 'serial', 'not null' => TRUE, 'description' => 'Primary Key: Unique revision ID.', ), 'item_id' => array( 'type' => 'int', 'not null' => TRUE, 'description' => 'Field collection item ID.', ), ), 'primary key' => array('revision_id'), 'indexes' => array( 'item_id' => array('item_id'), ), 'foreign keys' => array( 'versioned_field_collection_item' => array( 'table' => 'field_collection_item', 'columns' => array('item_id' => 'item_id'), ), ), ); return $schema; } /** * Implements hook_field_schema(). */ function field_collection_field_schema($field) { $columns = array( 'value' => array( 'type' => 'int', 'not null' => FALSE, 'description' => 'The field collection item id.', ), 'revision_id' => array( 'type' => 'int', 'not null' => FALSE, 'description' => 'The field collection item revision id.', ), ); return array( 'columns' => $columns, 'indexes' => array( 'value' => array('value'), 'revision_id' => array('revision_id'), ), ); } /** * Update the administer field collection permission machine name. */ function field_collection_update_7000() { db_update('role_permission') ->fields(array('permission' => 'administer field collections')) ->condition('permission', 'administer field-collections') ->execute(); } /** * Add revision support. */ function field_collection_update_7001() { // Add revision_id column to field_collection_item table. $revision_id_spec = array( 'type' => 'int', 'not null' => TRUE, 'description' => 'Default revision ID.', // Set default to 0 temporarily. 'initial' => 0, ); // Field may already exist due to bug in 7.x-1.0-beta5. if (!db_field_exists('field_collection_item', 'revision_id')) { db_add_field('field_collection_item', 'revision_id', $revision_id_spec); } // Initialize the revision_id to be the same as the item_id. db_update('field_collection_item') ->expression('revision_id', 'item_id') ->execute(); // Add the archived column $archived_spec = array( 'description' => 'Boolean indicating whether the field collection item is archived.', 'type' => 'int', 'not null' => TRUE, 'default' => 0, ); // Field may already exist due to bug in 7.x-1.0-beta5. if (!db_field_exists('field_collection_item', 'archived')) { db_add_field('field_collection_item', 'archived', $archived_spec); } // Create the new table. It is important to explicitly define the schema here // rather than use the hook_schema definition: http://drupal.org/node/150220. $schema['field_collection_item_revision'] = array( 'description' => 'Stores revision information about field collection items.', 'fields' => array( 'revision_id' => array( 'type' => 'serial', 'not null' => TRUE, 'description' => 'Primary Key: Unique revision ID.', ), 'item_id' => array( 'type' => 'int', 'not null' => TRUE, 'description' => 'Field collection item ID.', ), ), 'primary key' => array('revision_id'), 'indexes' => array( 'item_id' => array('item_id'), ), 'foreign keys' => array( 'versioned_field_collection_item' => array( 'table' => 'field_collection_item', 'columns' => array('item_id' => 'item_id'), ), ), ); // Table may already exist due to bug in 7.x-1.0-beta5. if (db_table_exists('field_collection_item_revision')) { db_drop_table('field_collection_item_revision'); } db_create_table('field_collection_item_revision', $schema['field_collection_item_revision']); // Fill the new table with the correct data. $items = db_select('field_collection_item', 'fci') ->fields('fci') ->execute(); foreach ($items as $item) { // Update field_collection_item_revision table. db_insert('field_collection_item_revision') ->fields(array( 'revision_id' => $item->item_id, 'item_id' => $item->item_id, )) ->execute(); } // Update the field_collection_field_schema columns for all tables. // Add a revision_id column. $revision_id_spec['description'] = 'The field collection item revision id.'; // Because $value_column below can be null, so must $revision_id_column. $revision_id_spec['not null'] = FALSE; foreach (field_read_fields(array('type' => 'field_collection')) as $field_name => $field) { $table_prefixes = array('field_data', 'field_revision'); foreach ($table_prefixes as $table_prefix) { $table = sprintf('%s_%s', $table_prefix, $field_name); $value_column = sprintf('%s_value', $field_name); $revision_id_column = sprintf('%s_revision_id', $field_name); // Field may already exist due to bug in 7.x-1.0-beta5. if (!db_field_exists($table, $revision_id_column)) { db_add_field($table, $revision_id_column, $revision_id_spec); } else { db_change_field($table, $revision_id_column, $revision_id_column, $revision_id_spec); } // Initialize the revision_id to be the same as the item_id. db_update($table) ->expression($revision_id_column, $value_column) ->execute(); } } // Need to get the system up-to-date so drupal_schema_fields_sql() will work. $schema = drupal_get_schema('field_collection_item_revision', TRUE); } /** * Remove orphaned field collection item entities. */ function field_collection_update_7002() { // Loop over all fields and delete any orphaned field collection items. foreach (field_read_fields(array('type' => 'field_collection')) as $field_name => $field) { $select = db_select('field_collection_item', 'fci') ->fields('fci', array('item_id')) ->condition('field_name', $field_name) ->condition('archived', 0); $select->leftJoin('field_data_' . $field_name, 'field', "field.{$field_name}_value = fci.item_id "); $select->isNull('field.entity_id'); $ids = $select->execute()->fetchCol(0); entity_delete_multiple('field_collection_item', $ids); drupal_set_message(t('Deleted @count orphaned field collection items.', array('@count' => count($ids)))); } } /** * Update field_collection_field_schema columns for all tables. */ function field_collection_update_7003() { // Revision_id column. $revision_id_spec = array( 'type' => 'int', 'not null' => FALSE, 'description' => 'The field collection item revision id.', 'initial' => 0, ); // Update the field_collection_field_schema columns for all tables, // in case the buggy beta5 version of field_collection_update_7001() // completed without complaint. foreach (field_read_fields(array('type' => 'field_collection')) as $field_name => $field) { $table_prefixes = array('field_data', 'field_revision'); foreach ($table_prefixes as $table_prefix) { $table = sprintf('%s_%s', $table_prefix, $field_name); $value_column = sprintf('%s_value', $field_name); $revision_id_column = sprintf('%s_revision_id', $field_name); db_change_field($table, $revision_id_column, $revision_id_column, $revision_id_spec); } } // Need to get the system up-to-date so drupal_schema_fields_sql() will work. $schema = drupal_get_schema('field_collection_item_revision', TRUE); } /** * Add index on {$field_collection_field}_revision_id column for all tables. */ function field_collection_update_7004() { // Update the field_collection_field_schema columns for all tables. foreach (field_read_fields(array('type' => 'field_collection')) as $field_name => $field) { $table_prefixes = array('field_data', 'field_revision'); foreach ($table_prefixes as $table_prefix) { $table = sprintf('%s_%s', $table_prefix, $field_name); $revision_id_column = sprintf('%s_revision_id', $field_name); // Add index on revision_id column. if (!db_index_exists($table, $revision_id_column)) { db_add_index($table, $revision_id_column, array($revision_id_column)); } } } } /** * Force the creation of the table cache_entity_field_collection_item. * * entity_update_7003 will attempt to install entitycache tables for existing * modules, but it uses module_list() to get the list of available modules, * which, when called from a database update, may not return field_collection * since drupal is bootstrapped at a lower level. */ function field_collection_update_7005() { if (module_exists('entitycache')) { $entity_type = 'field_collection_item'; $table = 'cache_entity_' . $entity_type; if (!db_table_exists($table)) { $schema = drupal_get_schema_unprocessed('system', 'cache'); $schema['description'] = 'Cache table used to store' . $entity_type . ' entity records.'; db_create_table($table, $schema); } } } /** * Ensures revision_id indexes are present at field_config table. */ function field_collection_update_7006() { $result = db_query("SELECT id, field_name, data FROM {field_config} WHERE type = 'field_collection'"); foreach ($result as $field_config) { $data = unserialize($field_config->data); // Skip this record if the revision_id index is already present. if (isset($data['indexes']['revision_id'])) { continue; } // Otherwise, add the revision_id index and update the record. $data['indexes']['revision_id'] = array('revision_id'); $data = serialize($data); $num_updated = db_update('field_config') ->fields(array('data' => $data)) ->condition('id', $field_config->id) ->execute(); // If for some reason the update failed, throw an exception. if ($num_updated != 1) { $t_args['@field'] = $field_config->field_name; throw new DrupalUpdateException(t('An error was detected when attempting to update field configuration for field @field.', $t_args)); } } } /** * Add index on {$field_collection_field}_value column for all tables. */ function field_collection_update_7007() { foreach (field_read_fields(array('type' => 'field_collection')) as $field_name => $field) { if (!isset($field['indexes']['value'])) { // Add index on the value column and update the field. $field['indexes']['value'] = array('value'); field_update_field($field); } $table_prefixes = array('field_data', 'field_revision'); foreach ($table_prefixes as $table_prefix) { $table = "{$table_prefix}_{$field_name}"; $value_column = "{$field_name}_value"; if (!db_index_exists($table, $value_column)) { // Add index on the value column. db_add_index($table, $value_column, array($value_column)); } } } } /** * Update fields in field collections already set to use Entity Translation. */ function field_collection_update_7008() { // Include FieldCollectionItemEntity class. module_load_include('inc', 'field_collection', 'field_collection.entity'); $results = array(); foreach (field_info_fields() as $f_name => $field) { if ($field['translatable'] == 1 && isset($field['bundles']['field_collection_item'])) { $query = new EntityFieldQuery(); $query->entityCondition('entity_type', 'field_collection_item') ->fieldLanguageCondition($f_name, LANGUAGE_NONE); $query_result = $query->execute(); if (isset($query_result['field_collection_item'])) { $results = $results + $query_result['field_collection_item']; } } } if (count($results)) { $ids = array_keys($results); $field_collection_items = entity_load('field_collection_item', $ids); foreach ($field_collection_items as $item) { $item->copyTranslations(LANGUAGE_NONE); $item->save(); } } }