Commit f7cb36f7 authored by KarenS's avatar KarenS
Browse files

#781088 Reorganize Content Migrate files for efficiency, and also to make it...

#781088 Reorganize Content Migrate files for efficiency, and also to make it easier to use the individual module code as examples on how to implement the hooks.
parent bdf8319f
......@@ -4,5 +4,10 @@ description = Migrate fields and field data from CCK D6 format to the D7 field f
core = 7.x
package = CCK
files[] = content_migrate.module
files[] = content_migrate.admin.inc
files[] = includes/content_migrate.admin.inc
files[] = includes/content_migrate.values.inc
files[] = modules/content_migrate.text.inc
files[] = modules/content_migrate.number.inc
files[] = modules/content_migrate.optionwidgets.inc
files[] = modules/content_migrate.filefield.inc
files[] = tests/content_migrate.test
<?php
// $Id$
/*
/**
* @file content_migrate.admin.inc
* Contains page callbacks for the module.
* Code to process field data migration, moved into a separate file for efficiency.
*/
/**
......@@ -169,7 +167,7 @@ function content_migrate_select_submit($form, &$form_state) {
function _content_migrate_batch($field_names) {
$batch = array(
'title' => t('Migrating data'),
'file' => drupal_get_path('module', 'content_migrate') . '/content_migrate.admin.inc',
'file' => drupal_get_path('module', 'content_migrate') . '/includes/content_migrate.admin.inc',
'operations' => array(
array('_content_migrate_batch_process_create_fields', array($field_names)),
),
......
<?php
/**
* @file content_migrate.values.inc
* Code to produce D7-style field and instance values from the data in D6 tables.
* Separated into a separate file for efficiency.
*/
/**
* Create a D7-style field array from data stored
* in the D6 content field tables.
*
* @param $field_name
* Optionally request only a specific field name.
*/
function _content_migrate_get_field_values($field_name = NULL) {
$field_values = &drupal_static(__FUNCTION__);
if (!is_array($field_values)) {
$field_values = array();
}
if (empty($field_values) && db_table_exists('content_node_field')) {
$field_values = array();
$query = db_select('content_node_field', 'nf', array('fetch' => PDO::FETCH_ASSOC));
$node_instance_alias = $query->join('content_node_field_instance', 'ni', 'ni.field_name=nf.field_name');
$result = $query
->fields($node_instance_alias, array('widget_module', 'widget_type', 'widget_settings', 'display_settings'))
->fields('nf')
->execute();
foreach ($result as $row) {
$field_value = $row;
// Pass instance settings to the field, in case they are needed.
$instance_value = array(
'widget' => array(
'type' => $row['widget_type'],
'module' => $row['widget_module'],
'settings' => unserialize($row['widget_settings']),
),
'display' => array(
'settings' => unserialize($row['display_settings']),
),
);
unset($field_value['widget_type'], $field_value['widget_module'], $field_value['widget_settings'], $field_value['display_settings']);
// All Drupal 6 fields were attached to nodes.
$field_value['entity_types'] = array();
if ($field_value['multiple'] == 0) {
$field_value['cardinality'] = 1;
}
elseif ($field_value['multiple'] == 1) {
$field_value['cardinality'] = FIELD_CARDINALITY_UNLIMITED;
}
else {
$field_value['cardinality'] = $field_value['multiple'];
}
// We need column information for the old table.
$field_value['columns'] = unserialize($field_value['db_columns']);
// Field settings.
$default_settings = field_info_field_settings($row['type']);
$field_value['settings'] = array_merge($default_settings, unserialize($field_value['global_settings']));
unset($field_value['multiple'], $field_value['global_settings'], $field_value['required'], $field_value['db_columns']);
// Let modules change these values.
drupal_alter('content_migrate_field', $field_value, $instance_value);
unset($field_value['allowed_values_php']);
// We retain $field_value['columns'] and $field_value['db_storage']
// even though they are not used or different in D7
// so we can find the old table information.
// Add field definiation to $field_values array.
$field_values[$field_value['field_name']] = $field_value;
}
}
if (!empty($field_name)) {
return $field_values[$field_name];
}
return $field_values;
}
/**
* Create a D7-style instance array from data stored
* in the D6 content field tables.
*
* @param $bundle
* Optionally request only instances of a specific bundle.
* @param $field_name
* Optionally request only instances of a specific field_name.
*/
function _content_migrate_get_instance_values($bundle = NULL, $field_name = NULL) {
$instance_values = &drupal_static(__FUNCTION__);
if (empty($instance_values) && db_table_exists('content_node_field_instance')) {
$instance_values = array();
$query = db_select('content_node_field_instance', 'ni', array('fetch' => PDO::FETCH_ASSOC));
$node_field_alias = $query->join('content_node_field', 'nf', 'ni.field_name=nf.field_name');
$result = $query
->fields('ni')
->fields($node_field_alias, array('type', 'module', 'required', 'global_settings'))
->orderBy('label', 'ASC')
->execute();
foreach ($result as $row) {
$instance_value = $row;
// Pass field settings to the instance, in case they are needed.
$field_value = array(
'require' => $instance_value['required'],
'type' => $instance_value['type'],
'module' => $instance_value['module'],
'settings' => unserialize($instance_value['global_settings']),
);
unset($instance_value['type'], $instance_value['module'], $instance_value['required'], $instance_value['global_settings']);
// All Drupal 6 instances were attached to nodes.
$instance_value['entity_type'] = 'node';
// Unserialize arrays.
foreach (array('widget_settings', 'display_settings', 'global_settings') as $key) {
$instance_value[$key] = (!empty($instance_value[$key])) ? (array) unserialize($instance_value[$key]) : array();
}
// Build instance values.
$instance_value['bundle'] = $instance_value['type_name'];
$instance_value['default_value'] = !empty($instance_value['widget_settings']['default_value']) ? $instance_value['widget_settings']['default_value'] : '';
// Core does not support this, but retain it so
// another module can do something with it
// in drupal_alter.
if (isset($instance_value['widget_settings']['default_value_php'])) {
$instance_value['widget']['settings']['default_value_php'] = $instance_value['widget_settings']['default_value_php'];
}
// Build widget values.
$instance_value['widget'] = array();
// TODO Some widget types have been renamed in D7.
$instance_value['widget']['type'] = $instance_value['widget_type'];
$instance_value['widget']['weight'] = $instance_value['weight'];
$instance_value['widget']['module'] = $instance_value['widget_module'];
$instance_value['widget']['active'] = $instance_value['widget_active'];
$default_settings = field_info_widget_settings($field_value['type']);
$instance_value['widget']['settings'] = array_merge($default_settings, $instance_value['widget_settings']);
// Build display values.
$instance_value['display'] = array();
$label = $instance_value['display_settings']['label'];
foreach ($instance_value['display_settings'] as $context => $settings) {
// @TODO Multigroup fields have some unexpected elements, we need to work out what should happen to them.
if ($context == 'parent' || $context == 'weight') {
continue;
}
$instance_value['display'][$context]['label'] = $label['format'];
// The format used in D6 may not match the formatter in D7.
// Fix it using drupal_alter().
$instance_value['display'][$context]['type'] = $settings['format'];
$instance_value['display'][$context]['settings'] = field_info_formatter_settings($settings['format']);
}
// Unset unneeded values.
unset($instance_value['type_name'], $instance_value['global_settings'], $instance_value['widget_settings'], $instance_value['display_settings'], $instance_value['widget_module'], $instance_value['widget_active']);
// Unset some values that don't exist on all fields.
if (isset($instance_value['widget']['settings']['default_value'])) unset($instance_value['widget']['settings']['default_value']);
// Let modules change these values.
drupal_alter('content_migrate_instance', $instance_value, $field_value);
// Get rid of this value once CCK or some other module has handled it.
if (isset($instance_value['widget']['settings']['default_value_php'])) unset($instance_value['widget']['settings']['default_value_php']);
// Add instance information to instance array.
$instance_values['instances'][$instance_value['bundle']][$instance_value['field_name']] = $instance_value;
$instance_values['fields'][$instance_value['field_name']][$instance_value['bundle']] = $instance_value;
}
}
if (!empty($bundle)) {
if (!empty($field_name)) {
return $instance_values['instances'][$bundle][$field_name];
}
else {
return $instance_values['instances'][$bundle];
}
}
elseif (!empty($field_name)) {
return $instance_values['fields'][$field_name];
}
return $instance_values;
}
\ No newline at end of file
<?php
/**
* @file content_migrate.filefield.inc
* Code to implement hook_content_migrate_field_alter, content_migrate_instance_alter() and content_migrate_data_record_alter()
* on behalf of the former filefield and imagefield modules, moved into a separate file for efficiency.
*/
/**
* Implements hook_content_migrate_field_alter().
*
* Use this to tweak the conversion of field settings
* from the D6 style to the D7 style for specific
* situations not handled by basic conversion,
* as when field types or settings are changed.
*/
function content_migrate_filefield_field_alter(&$field_value, $instance_value) {
switch ($instance_value['widget']['module']) {
case 'imagefield':
// Module names and types changed.
$field_value['module'] = 'image';
$field_value['type'] = 'image';
// default_image is now a field setting.
$field_value['settings']['default_image'] = $instance_value['widget']['settings']['default_image'];
break;
case 'filefield':
// Module names and types changed.
$field_value['module'] = 'file';
$field_value['type'] = 'file';
break;
}
}
/**
* Implements hook_content_migrate_instance_alter().
*
* Use this to tweak the conversion of instance or widget settings
* from the D6 style to the D7 style for specific
* situations not handled by basic conversion, as when
* formatter or widget names or settings are changed.
*/
function content_migrate_filefield_instance_alter(&$instance_value, $field_value) {
switch ($instance_value['widget']['module']) {
case 'imagefield':
// Module names and types changed.
$instance_value['widget']['module'] = 'image';
$instance_value['widget']['type'] = 'image';
// Most settings became instance settings instead of widget settings, with a couple name changes.
$instance_value['settings']['file_directory'] = $instance_value['widget']['settings']['file_path'];
unset($instance_value['widget']['settings']['file_path']);
$instance_value['settings']['file_extensions'] = $instance_value['widget']['settings']['file_extensions'];
unset($instance_value['widget']['settings']['file_extensions']);
$instance_value['settings']['max_filesize'] = $instance_value['widget']['settings']['max_filesize_per_file'];
unset($instance_value['widget']['settings']['max_filesize_per_file']);
$instance_value['settings']['max_resolution'] = $instance_value['widget']['settings']['max_resolution'];
unset($instance_value['widget']['settings']['max_resolution']);
$instance_value['settings']['min_resolution'] = $instance_value['widget']['settings']['min_resolution'];
unset($instance_value['widget']['settings']['min_resolution']);
// What is the difference between alt and custom_alt on the old field?
$instance_value['settings']['alt_field'] = $instance_value['widget']['settings']['custom_alt'];
unset($instance_value['widget']['settings']['custom_alt']);
$instance_value['settings']['title_field'] = $instance_value['widget']['settings']['custom_title'];
unset($instance_value['widget']['settings']['custom_title']);
// Many settings have no place in the new field array.
unset($instance_value['widget']['settings']['title']);
unset($instance_value['widget']['settings']['alt']);
unset($instance_value['widget']['settings']['max_filesize_per_node']);
unset($instance_value['widget']['settings']['title_type']);
// default_image is now a field setting.
unset($instance_value['widget']['settings']['default_image']);
break;
case 'filefield':
// Module names and types changed.
$instance_value['widget']['module'] = 'file';
$instance_value['widget']['type'] = 'file_generic';
// Some settings had name changes.
$instance_value['widget']['settings']['file_directory'] = $instance_value['widget']['settings']['file_path'];
unset($instance_value['widget']['settings']['file_path']);
$instance_value['widget']['settings']['max_filesize'] = $instance_value['widget']['settings']['max_filesize_per_file'];
unset($instance_value['widget']['settings']['max_filesize_per_file']);
break;
}
}
/**
* Implements hook_content_migrate_data_record_alter().
*
* Tweaks individual records in a field.
*/
function content_migrate_filefield_data_record_alter(&$record, $field) {
switch($field['type']) {
case 'image':
// Map D6 imagefield field columns to D7 image field columns.
if (!empty($record[$field['field_name'] . '_title']) && ($data = unserialize($record[$field['field_name'] . '_title']))) {
$record[$field['field_name'] . '_alt'] = $data['alt'];
$record[$field['field_name'] . '_title'] = $data['title'];
}
else {
unset($record[$field['field_name'] . '_alt']);
unset($record[$field['field_name'] . '_title']);
}
// Fall through.
case 'file':
// Map D6 filefield field columns to D7 file field columns.
if (!empty($record[$field['field_name'] . '_description']) && ($data = unserialize($record[$field['field_name'] . '_description']))) {
$record[$field['field_name'] . '_description'] = $data['description'];
}
else {
unset($record[$field['field_name'] . '_description']);
}
// Copies imagefield data from the old 'files' table into 'files_managed' and sets file_usage
// Mostly copied from system_update_7061, which does the same for the D6 core 'upload' module
$nid = $record['entity_id'];
$fid = $record[$field['field_name'] . '_fid'];
if (empty($fid)) {
$record = NULL;
return;
};
$file = db_select('files', 'f')->fields('f', array('fid', 'uid', 'filename', 'filepath', 'filemime', 'filesize', 'timestamp', 'status'))->condition('fid', $fid)->execute()->fetchObject();
$basename = variable_get('file_directory_path', conf_path() . '/files');
$scheme = file_default_scheme() . '://';
// We will convert filepaths to uri using the default scheme
// and stripping off the existing file directory path.
$file->uri = $scheme . str_replace($basename, '', $file->filepath);
$file->uri = file_stream_wrapper_uri_normalize($file->uri);
unset($file->filepath);
// Insert into the file_managed table.
// Each fid should only be stored once in file_managed.
db_merge('file_managed')
->key(array(
'fid' => $file->fid,
))
->fields(array(
'uid' => $file->uid,
'filename' => $file->filename,
'uri' => $file->uri,
'filemime' => $file->filemime,
'filesize' => $file->filesize,
'status' => $file->status,
'timestamp' => $file->timestamp,
))
->execute();
// Add the usage entry for the file.
file_usage_add($file, 'file', 'node', $nid);
break;
}
}
\ No newline at end of file
<?php
/**
* @file content_migrate.number.inc
* Code to implement hook_content_migrate_field_alter, content_migrate_instance_alter() and content_migrate_data_record_alter()
* on behalf of the former number module, moved into a separate file for efficiency.
*/
/**
* Implements hook_content_migrate_field_alter().
*
* Use this to tweak the conversion of field settings
* from the D6 style to the D7 style for specific
* situations not handled by basic conversion,
* as when field types or settings are changed.
*/
function content_migrate_number_field_alter(&$field_value, $instance_value) {
switch ($field_value['type']) {
case 'number_integer':
case 'number_decimal':
case 'number_float':
// Changed name of setting from 'decimal' to
// 'decimal_separator'.
if (isset($field_value['settings']['decimal'])) {
$field_value['settings']['decimal_separator'] = $field_value['settings']['decimal'];
unset($field_value['settings']['decimal']);
}
// Add a decimal_separator setting to floats.
if ($field_value['type'] == 'number_float') {
$field_value['settings']['decimal_separator'] = '.';
}
// Number fields using optionwidgets are
// now List fields.
switch ($instance_value['widget']['type']) {
case 'optionwidgets_buttons':
case 'optionwidgets_select':
$field_value['type'] = 'list_number';
$field_value['module'] = 'list';
break;
case 'optionwidgets_onoff':
$field_value['type'] = 'list_boolean';
$field_value['module'] = 'list';
break;
}
break;
}
}
/**
* Implements hook_content_migrate_instance_alter().
*
* Use this to tweak the conversion of instance or widget settings
* from the D6 style to the D7 style for specific
* situations not handled by basic conversion, as when
* formatter or widget names or settings are changed.
*/
function content_migrate_number_instance_alter(&$instance_value, $field_value) {
// Switch
switch ($instance_value['widget']['module']) {
case 'number':
// The number formatters and formatter settings
// have changed.
$new_type = array(
'unformatted' => 'number_unformatted',
'default' => 'number_decimal',
'us_0' => 'number_integer',
'us_1' => 'number_decimal',
'us_2' => 'number_decimal',
'be_0' => 'number_integer',
'be_1' => 'number_decimal',
'be_2' => 'number_decimal',
'fr_0' => 'number_integer',
'fr_1' => 'number_decimal',
'fr_2' => 'number_decimal',
);
$new_settings = array(
'default' => array(
'thousand_separator' => '',
'decimal_separator' => '.',
'scale' => 0,
'prefix_suffix' => TRUE,
),
'us_0' => array(
'thousand_separator' => ',',
'decimal_separator' => '.',
'scale' => 0,
'prefix_suffix' => TRUE,
),
'us_1' => array(
'thousand_separator' => ',',
'decimal_separator' => '.',
'scale' => 1,
'prefix_suffix' => TRUE,
),
'us_2' => array(
'thousand_separator' => ',',
'decimal_separator' => '.',
'scale' => 2,
'prefix_suffix' => TRUE,
),
'be_0' => array(
'thousand_separator' => '',
'decimal_separator' => ',',
'scale' => 0,
'prefix_suffix' => TRUE,
),
'be_1' => array(
'thousand_separator' => '.',
'decimal_separator' => ',',
'scale' => 1,
'prefix_suffix' => TRUE,
),
'be_2' => array(
'thousand_separator' => '.',
'decimal_separator' => ',',
'scale' => 2,
'prefix_suffix' => TRUE,
),
'fr_0' => array(
'thousand_separator' => '',
'decimal_separator' => ', ',
'scale' => 0,
'prefix_suffix' => TRUE,
),
'fr_1' => array(
'thousand_separator' => ' ',
'decimal_separator' => ', ',
'scale' => 1,
'prefix_suffix' => TRUE,
),
'fr_2' => array(
'thousand_separator' => ' ',
'decimal_separator' => ', ',
'scale' => 2,
'prefix_suffix' => TRUE,
),
);
foreach ($instance_value['display'] as $context => $settings) {
$instance_value['display'][$context]['type'] = $new_type[$settings['type']];
$instance_value['display'][$context]['settings'] = $new_settings[$settings['type']];
}
break;
}
}
<?php
/**
* @file content_migrate.optionwidgets.inc
* Code to implement hook_content_migrate_field_alter, content_migrate_instance_alter() and content_migrate_data_record_alter()
* on behalf of the former optionwidgets module, moved into a separate file for efficiency.
*/
/**
* Implements hook_content_migrate_instance_alter().
*
* Use this to tweak the conversion of instance or widget settings
* from the D6 style to the D7 style for specific
* situations not handled by basic conversion, as when
* formatter or widget names or settings are changed.
*/
function content_migrate_optionwidgets_instance_alter(&$instance_value, $field_value) {
switch ($instance_value['widget']['module']) {
// Optionswidgets module became Options module
// and widget type names changed.
case 'optionwidgets':
$replace = array(
'optionwidgets_select' => 'options_select',
'optionwidgets_buttons' => 'options_buttons',
'optionwidgets_onoff' => 'options_onoff',
);
$instance_value['widget']['module'] = 'options';
$instance_value['widget']['type'] = strtr($instance_value['widget']['type'], $replace);
break;
}
}
\ No newline at end of file