function field_collection_update_7009 in Field collection 7
Update revisions created before revision support was implemented.
File
- ./
field_collection.install, line 406 - Install, update and uninstall functions for the field_collection module.
Code
function field_collection_update_7009(&$sandbox) {
$items_per_pass = 10;
$field_collection_fields = field_read_fields(array(
'type' => 'field_collection',
));
// If you don't have any field_collecton fields then skip this update.
if (empty($field_collection_fields)) {
return;
}
if (!isset($sandbox['current_field'])) {
$sandbox['field_collection_fields'] = array_keys($field_collection_fields);
$sandbox['current_field'] = 0;
$sandbox['current_field_collection_item'] = 0;
$sandbox['field_name'] = $sandbox['field_collection_fields'][$sandbox['current_field']];
$sandbox['inner_fields'] = field_read_instances(array(
'entity_type' => 'field_collection_item',
'bundle' => $sandbox['field_name'],
));
}
// Find field collection items with duplicate revision ids.
$query = db_select("field_revision_{$sandbox['field_name']}", 't')
->fields('t', array(
"{$sandbox['field_name']}_revision_id",
))
->range($sandbox['current_field_collection_item'], $items_per_pass)
->groupBy("t.{$sandbox['field_name']}_revision_id");
$query
->having("COUNT(t.{$sandbox['field_name']}_revision_id) >= 2");
$vids = $query
->execute()
->fetchCol();
// Each revision ID that occurs more than once.
foreach ($vids as $field_collection_duplicated_revision_id) {
// Find every instance of this revision ID.
$copies = db_select("field_revision_{$sandbox['field_name']}", 't')
->fields('t')
->condition("{$sandbox['field_name']}_revision_id", $field_collection_duplicated_revision_id)
->execute()
->fetchAllAssoc('revision_id');
$first_copy = reset($copies);
$field_collection_item_id = $first_copy->{"{$sandbox['field_name']}_value"};
// Find the currently used revision of this field collection item.
$field_collection_item_current_revision = db_select('field_collection_item', 'fci')
->fields('fci', array(
'revision_id',
))
->condition('item_id', $field_collection_item_id)
->execute()
->fetchField();
// Find new revisions of this field collection item that were made after
// revisions were enabled in update_7003.
$modern_revisions = db_select("field_revision_{$sandbox['field_name']}", 't')
->fields('t')
->condition("{$sandbox['field_name']}_revision_id", $field_collection_duplicated_revision_id, '<>')
->condition("{$sandbox['field_name']}_value", $field_collection_item_id)
->orderBy('revision_id')
->execute()
->fetchAllAssoc('revision_id');
// Intentionally skip the first instance as it doesn't need to be modified.
while (FALSE !== ($row_to_replace = next($copies))) {
$new_revision_id = _field_collection_update_7009_new_revision($field_collection_item_id, $row_to_replace, $sandbox['inner_fields'], $sandbox['field_name']);
// Create copies of inner fields with new revision number.
foreach ($sandbox['inner_fields'] as $field) {
// Get the data to copy.
$data_rows = db_select("field_revision_{$field['field_name']}", 't')
->fields('t')
->condition('entity_type', 'field_collection_item')
->condition('revision_id', $field_collection_duplicated_revision_id)
->execute();
// Add new copy of data with new revision id.
while ($each_row = $data_rows
->fetchAssoc()) {
$each_row['revision_id'] = $new_revision_id;
db_insert("field_revision_{$field['field_name']}")
->fields(array_keys($each_row), array_values($each_row))
->execute();
}
}
// Update the host's field data with new revision number.
db_update("field_revision_{$sandbox['field_name']}")
->fields(array(
"{$sandbox['field_name']}_revision_id" => $new_revision_id,
))
->condition('entity_type', $row_to_replace->entity_type)
->condition('revision_id', $row_to_replace->revision_id)
->condition('delta', $row_to_replace->delta)
->condition('language', $row_to_replace->language)
->execute();
if ($field_collection_item_current_revision == $field_collection_duplicated_revision_id) {
_field_collection_update_7009_update_data($new_revision_id, $field_collection_duplicated_revision_id);
// Update the current field collection item data in its host.
db_update("field_data_{$sandbox['field_name']}")
->fields(array(
'revision_id' => $new_revision_id,
))
->condition('revision_id', $field_collection_duplicated_revision_id)
->condition('entity_type', $row_to_replace->entity_type)
->execute();
}
}
foreach ($modern_revisions as $each_modern_revision) {
$new_revision_id = _field_collection_update_7009_new_revision($field_collection_item_id, $each_modern_revision, $sandbox['inner_fields'], $sandbox['field_name']);
// Update inner fields with new revision number.
foreach ($sandbox['inner_fields'] as $field) {
db_update("field_revision_{$field['field_name']}")
->fields(array(
'revision_id' => $new_revision_id,
))
->condition('revision_id', $each_modern_revision->{$sandbox['field_name'] . '_revision_id'})
->condition('entity_type', 'field_collection_item')
->execute();
}
// Update the host's field data with new revision number.
db_update("field_revision_{$sandbox['field_name']}")
->fields(array(
"{$sandbox['field_name']}_revision_id" => $new_revision_id,
))
->condition('entity_type', $each_modern_revision->entity_type)
->condition('revision_id', $each_modern_revision->revision_id)
->condition('delta', $each_modern_revision->delta)
->condition('language', $each_modern_revision->language)
->execute();
if ($field_collection_item_current_revision == $each_modern_revision->{"{$sandbox['field_name']}_revision_id"}) {
_field_collection_update_7009_update_data($new_revision_id, $field_collection_item_current_revision);
// Update the current field collection item data in its host.
db_update("field_data_{$sandbox['field_name']}")
->fields(array(
'revision_id' => $new_revision_id,
))
->condition('revision_id', $field_collection_item_current_revision)
->condition('entity_type', $each_modern_revision->entity_type)
->execute();
}
// Remove old copy of revision.
db_delete('field_collection_item_revision')
->condition('revision_id', $each_modern_revision->revision_id)
->execute();
}
$sandbox['current_field_collection_item']++;
}
$sandbox['#finished'] = 0;
if (count($vids) < $items_per_pass) {
$sandbox['current_field']++;
if ($sandbox['current_field'] == count($sandbox['field_collection_fields'])) {
$sandbox['#finished'] = 1;
return;
}
$sandbox['current_field_collection_item'] = 0;
$sandbox['field_name'] = $sandbox['field_collection_fields'][$sandbox['current_field']];
$sandbox['inner_fields'] = field_read_instances(array(
'entity_type' => 'field_collection_item',
'bundle' => $sandbox['field_name'],
));
}
}