function _content_migrate_batch_process_migrate_data in Content Construction Kit (CCK) 7.3
Batch operation callback to migrate data. Copy old table data to new field table.
2 string references to '_content_migrate_batch_process_migrate_data'
- drush_content_migrate_field_data in modules/
content_migrate/ includes/ content_migrate.drush.inc - _content_migrate_batch in modules/
content_migrate/ includes/ content_migrate.admin.inc - Helper function to create a batch.
File
- modules/
content_migrate/ includes/ content_migrate.admin.inc, line 298 - content_migrate.admin.inc Code to process field data migration, moved into a separate file for efficiency.
Code
function _content_migrate_batch_process_migrate_data($field_name, &$context) {
// The first time through, find all the nodes that have this field.
if (!isset($context['sandbox']['progress'])) {
$field_value = content_migrate_get_field_values($field_name);
if (isset($field_value['messages'])) {
unset($field_value['messages']);
}
$instance_values = content_migrate_get_instance_values(NULL, $field_name);
if (isset($instance_values['messages'])) {
unset($instance_values['messages']);
}
$types = array();
foreach ($instance_values as $bundle => $instance_value) {
$types[] = $bundle;
}
$field = field_info_field($field_name);
$old_table = content_migrate_old_table($field_value, $instance_value);
$old_cols = content_migrate_old_columns($field_value, $instance_value);
$new_table = content_migrate_new_table($field);
$new_revision_table = content_migrate_new_revision($field);
$new_columns = content_migrate_new_columns($field);
// Shared, non-multiple fields do not have a delta but are still in per-field tables.
$add_delta = $field_value['cardinality'] != 1 && content_migrate_storage_type($field_value, $instance_value) == CONTENT_DB_STORAGE_PER_FIELD;
$query = db_select($old_table, 'old_table', array(
'fetch' => PDO::FETCH_ASSOC,
));
$node_alias = $query
->join('node', 'n', 'old_table.nid=n.nid');
$result = $query
->fields($node_alias, array(
'title',
'type',
'vid',
'language',
))
->fields('old_table', array(
'nid',
))
->orderBy('nid', 'ASC')
->distinct()
->execute();
$nodes = array();
foreach ($result as $row) {
$nodes[] = array(
'nid' => $row['nid'],
'title' => $row['title'],
'type' => $row['type'],
'vid' => $row['vid'],
'language' => $row['language'],
);
}
$context['sandbox']['progress'] = 0;
$context['sandbox']['max'] = count($nodes);
$context['sandbox']['nodes'] = $nodes;
$context['sandbox']['old_table'] = $old_table;
$context['sandbox']['new_table'] = $new_table;
$context['sandbox']['new_revision_table'] = $new_revision_table;
$context['sandbox']['old_cols'] = $old_cols;
$context['sandbox']['new_cols'] = $new_columns;
$context['sandbox']['types'] = $types;
$context['sandbox']['field'] = $field;
$context['sandbox']['add_delta'] = $add_delta;
}
// Process 100 nodes in each batch.
$field = field_info_field($field_name);
// Construct an record to insert into the new field table
// from the data in the old table.
$query = db_select($context['sandbox']['old_table'], 'old_table', array(
'fetch' => PDO::FETCH_ASSOC,
));
// We need new columns for bundle name, entity type, and language.
// See the debate going on at http://drupal.org/node/1164852.
// Reverting back to setting all nodes as untranslated.
$language = LANGUAGE_NONE;
if ($field['translatable']) {
//$language = $node['language'];
}
$query
->addExpression("'node'", 'entity_type');
$query
->addExpression("'" . $language . "'", 'language');
// There are new names for what were the nid and vid columns.
$query
->addField('old_table', 'nid', 'entity_id');
$query
->addField('old_table', 'vid', 'revision_id');
// Add the field columns to the select query.
// Use the new column names as aliases in case the
// name changed, hopefully none did.
foreach ($context['sandbox']['old_cols'] as $column_name => $db_column_name) {
$query
->addField('old_table', $db_column_name, $context['sandbox']['new_cols'][$column_name]);
}
// Add delta, or construct it if missing.
if ($context['sandbox']['add_delta']) {
$query
->addField('old_table', 'delta', 'delta');
}
else {
$query
->addExpression(0, 'delta');
}
$base_query = $query;
for ($i = 0; $i <= 100; $i++) {
$query = clone $base_query;
$node = array_shift($context['sandbox']['nodes']);
if (!$node) {
// Rollback the field if there was a data migration error.
if ($context['sandbox']['rollback'] == TRUE) {
content_migrate_rollback(array(
$field_name,
));
}
return;
}
$instance = field_info_instance('node', $field_name, $node['type']);
$query
->addExpression("'" . $node['type'] . "'", 'bundle');
$query
->condition('nid', $node['nid']);
$result = $query
->execute();
foreach ($result as $record) {
module_load_include('inc', 'content_migrate', 'modules/content_migrate.' . $field['module']);
try {
// Let modules alter this before the insert.
drupal_alter('content_migrate_data_record', $record, $field, $instance);
// Don't save empty values.
if (!empty($record)) {
$function = $field['module'] . '_field_is_empty';
if (function_exists($function)) {
// The $record array has the database columns as keys, which drupal_write_record() will need,
// but the _field_is_empty() function will be looking for the short, normalized column name.
$item = array();
foreach ($context['sandbox']['new_cols'] as $column_name => $db_column_name) {
if (array_key_exists($db_column_name, $record)) {
$item[$column_name] = $record[$db_column_name];
}
}
if ($function($item, $field)) {
$record = NULL;
}
}
}
if (!empty($record)) {
if ($record['revision_id'] == $node['vid']) {
drupal_write_record($context['sandbox']['new_table'], $record);
}
drupal_write_record($context['sandbox']['new_revision_table'], $record);
}
} catch (Exception $e) {
// An error has occurred trying to migrate a record of this field.
// Set this field to be rolledback and display a detailed error message.
$context['sandbox']['rollback'] = TRUE;
$exception = t('<p>Requesting rollback of field "@field" due to failure to convert record:</p>' . '<p>@record</p> <p>Cause:</p> <p>@cause</p>', array(
'@field' => $field_name,
'@record' => var_export($record, TRUE),
'@cause' => $e,
));
drupal_set_message($exception, 'error');
}
}
// Update our progress information.
$context['sandbox']['progress']++;
}
$context['message'] = t('Processing through nid %nid', array(
'%nid' => $node['nid'],
));
// Inform the batch engine that we are not finished,
// and provide an estimation of the completion level we reached.
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
}