Commit 8376bb8b authored by KarenS's avatar KarenS
Browse files

More tweaking of content migrate script, starting to work correctly for at...

More tweaking of content migrate script, starting to work correctly for at least the cases I have tested so far.
parent f5d210e1
......@@ -30,7 +30,7 @@ function cck_menu_alter(&$items) {
}
function cck_debug_field_info() {
if (drupal_function_exists('dsm')) {
if (function_exists('dsm')) {
module_load_include('inc', 'field', 'field.info');
dsm(_field_info_collate_types());
dsm(_field_info_collate_fields());
......
......@@ -19,6 +19,7 @@ function content_migrate_select($form, &$form_state) {
$options = array('available' => array(), 'converted' => array(), 'missing' => array());
$field_values = content_migrate_get_field_values();
if (empty($field_values)) {
drupal_set_message(t('There is no D6 field information in this database.'));
return $form;
......@@ -28,23 +29,31 @@ function content_migrate_select($form, &$form_state) {
$new_fields = array_keys(field_info_fields());
// Figure out which field and widget modules are available.
$available_modules = array_unique(array_merge(module_implements('field_info'), module_implements('widget_info')));
$available_modules = array_unique(array_merge(module_implements('field_info'), module_implements('field_widget_info')));
foreach ($field_values as $field_name => $field_value) {
$bundles = array();
$missing_module = !in_array($field_value['module'], $available_modules);
$missing_modules = $missing_module ? array($field_value['module']) : array();
$instance_values = content_migrate_get_instance_values(NULL, $field_name);
// Debug
//dsm($field_value);
//dsm($instance_values);
foreach ($instance_values as $bundle => $instance_value) {
$bundles[] = $type_names[$bundle];
$label = $instance_value['label'];
if (!in_array($instance_value['widget']['module'], $available_modules)) {
$missing_module = TRUE;
$missing_modules[] = $instance_value['widget']['module'];
}
}
$data = array(
0 => $field_name,
1 => $field_value['type'],
2 => implode(', ', $bundles),
3 => empty($missing_modules) ? '' : t('Missing modules: @list', array('@list' => implode(', ', $missing_modules))),
);
if (in_array($field_name, $new_fields)) {
$options['converted'][$field_name] = $data;
......@@ -58,7 +67,7 @@ function content_migrate_select($form, &$form_state) {
}
}
$header = array(t('Field'), t('Field type'), t('Content type(s)'));
$header = array(t('Field'), t('Field type'), t('Content type(s)'), t('Other information'));
$form['#tree'] = TRUE;
$form['available'] = array(
'#type' => 'fieldset',
......@@ -216,35 +225,36 @@ function _content_migrate_batch_process_create_fields($field_names) {
drupal_set_message(t("Error creating field @field_name", array('@field_name' => $field_name)), 'error');
drupal_set_message($e, 'error');
}
field_info_cache_clear();
}
//dsm($field_values);
$context['finished'] = TRUE;
}
/**
* Batch operation callback to migrate data.
* Copy old table data to new field table.
*
* TODO This query still needs work.
*/
function _content_migrate_batch_process_migrate_data($field_name) {
$field_value = content_migrate_get_field_values($field_name);
$field = $context['fields'][$field_name];
foreach ($info['instances'] as $instance_value) {
$instance_values = content_migrate_get_instance_values(NULL, $field_name);
$field = field_info_field($field_name);
//$instances = field_read_instances(array('field_id' => $field['id']));
foreach ($instance_values as $instance_value) {
$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);
$query = db_select($old_table, 'old');
// We need a new columns for bundle name, entity type, and language.
$query->addExpression($instance_value['bundle'], 'bundle');
$query->addExpression("'". $instance_value['bundle'] ."'", 'bundle');
$query->addExpression(1, 'etid');
$query->addExpression(LANGUAGE_NONE, 'language');
$query->addExpression("'". LANGUAGE_NONE ."'", 'language');
// There are new names for what were the nid and vid columns.
$query->addField('old', 'nid', 'entity_id');
......@@ -282,27 +292,4 @@ function _content_migrate_batch_process_migrate_data($field_name) {
drupal_set_message($e, 'error');
}
}
}
function content_migrate_test() {
$field_values = content_migrate_get_field_values();
dsm($field_values);
foreach ($field_values as $field_name => $field_value) {
field_delete_field($field_name);
$field = field_create_field($field_value);
dsm($field);
$instance_values = content_migrate_get_instance_values(NULL, $field_name);
foreach ($instance_values as $instance_value) {
$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);
dsm($old_table);
dsm($old_cols);
dsm($new_table);
dsm($new_columns);
}
}
}
\ No newline at end of file
......@@ -3,12 +3,15 @@
/**
* @file
* Code For D6 to D7 field update.
*
* Modules can implement hook_content_migrate_field_alter()
* and hook_content_migrate_instance_alter()
*/
define('CONTENT_DB_STORAGE_PER_FIELD', 0);
define('CONTENT_DB_STORAGE_PER_CONTENT_TYPE', 1);
/**
* Implementation of hook_menu().
* Implements hook_menu().
*/
function content_migrate_menu() {
// Demo page.
......@@ -39,7 +42,9 @@ function content_migrate_get_field_values($field_name = NULL) {
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_type'))
->fields('nf')
->execute();
......@@ -47,7 +52,7 @@ function content_migrate_get_field_values($field_name = NULL) {
$field_value = $row;
// All Drupal 6 fields were attached to nodes.
$field_value['entity_type'] = 'node';
$field_value['entity_types'] = array('node');
$field_value['cardinality'] = $field_value['multiple'] != 1 ? $field_value['multiple'] : FIELD_CARDINALITY_UNLIMITED;
......@@ -59,16 +64,16 @@ function content_migrate_get_field_values($field_name = NULL) {
$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']);
// TODO Move this to a hook_content_migrate_field_alter on behalf of text module.
// The max_length field can no longer be empty or it will create a SQL error.
if ($field_value['type'] == 'text' && empty($field_value['settings']['max_length'])) {
$field_value['settings']['max_length'] = 255;
}
// Let modules change these values.
drupal_alter('content_migrate_field', $field_value);
// We left the widget type in the $field_value so modules
// could adjust the field based on that information.
// Needed so optionwidgets can change the field type
// from text or numeric to list.
unset($field_value['widget_type']);
// 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.
......@@ -101,13 +106,19 @@ function content_migrate_get_instance_values($bundle = NULL, $field_name = NULL)
$node_field_alias = $query->join('content_node_field', 'nf', 'ni.field_name=nf.field_name');
$result = $query
->fields('ni')
->fields($node_field_alias, array('required', 'type'))
->fields($node_field_alias, array('required'))
->orderBy('label', 'ASC')
->execute();
foreach ($result as $row) {
$field_type = $row['type'];
foreach ($result as $row) {
$instance_value = $row;
// The instance has the same module as the field,
// not the widget. May have been altered
// from the original values, so get the altered
// field values.
$field_value = content_migrate_get_field_values($row['field_name']);
$instance_value['module'] = $field_value['module'];
// All Drupal 6 instances were attached to nodes.
$instance_value['entity_type'] = 'node';
......@@ -120,8 +131,6 @@ function content_migrate_get_instance_values($bundle = NULL, $field_name = NULL)
// Build instance values.
$instance_value['bundle'] = $instance_value['type_name'];
$instance_value['active'] = $instance_value['widget_active'];
$instance_value['module'] = $instance_value['widget_module'];
$instance_value['type'] = $instance_value['widget_type'];
$instance_value['default_value'] = $instance_value['widget_settings']['default_value'];
// Core does not support this, but retain it so
......@@ -135,9 +144,9 @@ function content_migrate_get_instance_values($bundle = NULL, $field_name = NULL)
// 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['module'];
$instance_value['widget']['module'] = $instance_value['widget_module'];
$default_settings = field_info_widget_settings($row['type']);
$default_settings = field_info_widget_settings($field_value['type']);
$instance_value['widget']['settings'] = array_merge($default_settings, $instance_value['widget_settings']);
// Build display values.
......@@ -147,14 +156,15 @@ function content_migrate_get_instance_values($bundle = NULL, $field_name = NULL)
foreach ($instance_value['display'] as $context => $settings) {
$instance_value['display'][$context]['label'] = $label['format'];
// TODO the format used in D6 does not match the formatter in D7.
// 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($instance_value['display'][$context]['exclude'], $instance_value['display'][$context]['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'], $instance_value['widget_type'], $instance_value['widget']['settings']['default_value'], $instance_value['widget']['settings']['default_value_php']);
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'], $instance_value['widget']['settings']['default_value'], $instance_value['widget']['settings']['default_value_php']);
// Let modules change these values.
drupal_alter('content_migrate_instance', $instance_value);
......@@ -188,8 +198,7 @@ function content_migrate_get_instance_values($bundle = NULL, $field_name = NULL)
* @param $instance_value
*/
function content_migrate_old_table($field_value, $instance_value) {
$storage = content_migrate_storage_type($field_value, $instance_value);
$storage = content_migrate_storage_type($field_value);
switch ($storage) {
case CONTENT_DB_STORAGE_PER_CONTENT_TYPE :
$name = $instance_value['bundle'];
......@@ -207,11 +216,12 @@ function content_migrate_old_table($field_value, $instance_value) {
* @param $field_value
* @param $instance_value
*/
function content_migrate_storage_type($field_value, $instance_value) {
if (!empty($field_value['db_storage'])) {
function content_migrate_storage_type($field_value) {
$storage = CONTENT_DB_STORAGE_PER_CONTENT_TYPE;
if (isset($field_value['db_storage'])) {
return $field_value['db_storage'];
}
elseif ($field_value['cardinality'] > 0) {
elseif ($field_value['cardinality'] > 0 || $field_value['cardinality'] == FIELD_CARDINALITY_UNLIMITED) {
$storage = CONTENT_DB_STORAGE_PER_FIELD;
}
else {
......@@ -220,7 +230,6 @@ function content_migrate_storage_type($field_value, $instance_value) {
$storage = CONTENT_DB_STORAGE_PER_FIELD;
}
}
$storage = CONTENT_DB_STORAGE_PER_CONTENT_TYPE;
return $storage;
}
......@@ -268,14 +277,212 @@ function content_migrate_old_columns($field_value, $instance_value) {
* @return unknown
*/
function content_migrate_new_columns($field) {
$columns = array();
if (empty($field['storage']['details'])) {
$columns = array();
foreach ($field['columns'] as $col => $values) {
$columns[] = $field['field_name'] .'_'. $col;
}
return $columns;
}
else {
return $field['storage']['details']['sql'][FIELD_LOAD_CURRENT];
foreach ($field['storage']['details']['sql'][FIELD_LOAD_CURRENT] as $table => $cols) {
foreach ($cols as $col) {
$columns[] = $col;
}
}
return $columns;
}
}
/**
* 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.
*
* $field_value['widget_type'] is available to
* see what widget type was originally used.
*/
function content_migrate_content_migrate_field_alter(&$field_value) {
switch ($field_value['type']) {
case 'text':
// The max_length field can no longer be empty
// or it will create a SQL error.
if (empty($field_value['settings']['max_length'])) {
$field_value['settings']['max_length'] = 255;
}
// Text fields using optionwidgets are
// now List fields.
switch ($field_value['widget_type']) {
case 'optionwidgets_buttons':
case 'optionwidgets_select':
$field_value['type'] = 'list_text';
$field_value['module'] = 'list';
break;
case 'optionwidgets_onoff':
$field_value['type'] = 'list_boolean';
$field_value['module'] = 'list';
break;
case 'text_textarea':
$field_value['type'] = 'text_long';
unset($field_value['settings']['max_length']);
break;
}
break;
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 ($field_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_content_migrate_instance_alter(&$instance_value) {
//$field = content_migrate_get_field_values($instance_value['field_name']);
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;
}
switch ($instance_value['module']) {
case 'text':
// The formatter names changed, all are prefixed
// with 'text_'.
foreach ($instance_value['display'] as $context => $settings) {
$instance_value['display'][$context]['type'] = 'text_'. $settings['type'];
}
break;
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;
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment