Index: migrate.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/migrate/migrate.info,v retrieving revision 1.1.2.1 diff -u -p -r1.1.2.1 migrate.info --- migrate.info 20 Mar 2009 13:18:20 -0000 1.1.2.1 +++ migrate.info 17 Jul 2009 17:21:56 -0000 @@ -4,4 +4,5 @@ description = "Import content from exter package = "Development" core = 6.x dependencies[] = views -dependencies[] = tw \ No newline at end of file +dependencies[] = tw +dependencies[] = ctools Index: migrate.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/migrate/migrate.install,v retrieving revision 1.1.2.7 diff -u -p -r1.1.2.7 migrate.install --- migrate.install 11 Jul 2009 19:41:24 -0000 1.1.2.7 +++ migrate.install 17 Jul 2009 17:21:56 -0000 @@ -7,6 +7,17 @@ function migrate_schema() { $schema['migrate_content_sets'] = array( 'description' => t('Sets of content mappings'), + 'export' => array( + 'key' => 'view_name', + 'identifier' => 'set', + 'default hook' => 'migrate_default_content_sets', + 'api' => array( + 'owner' => 'migrate', + 'api' => 'migrate_default_sets', + 'minimum_version' => 1, + 'current_version' => 1, + ), + ), 'fields' => array( 'mcsid' => array( 'type' => 'serial', @@ -80,6 +91,10 @@ function migrate_schema() { ); $schema['migrate_content_mappings'] = array( 'description' => t('Content field mappings'), + 'export' => array( + 'key' => 'mcmid', + 'identifier' => 'map', + ), 'fields' => array( 'mcmid' => array( 'type' => 'serial', Index: migrate.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/migrate/migrate.module,v retrieving revision 1.1.2.30 diff -u -p -r1.1.2.30 migrate.module --- migrate.module 17 Jul 2009 15:07:17 -0000 1.1.2.30 +++ migrate.module 17 Jul 2009 17:21:57 -0000 @@ -706,6 +695,15 @@ function migrate_menu() { 'access arguments' => array(MIGRATE_ACCESS_ADVANCED), 'file' => 'migrate_pages.inc', ); + $items['admin/content/migrate/destinations/list'] = array( + 'title' => 'List', + 'description' => 'Manage content sets: mappings of source data to Drupal content', + 'weight' => 1, + 'page callback' => 'migrate_destinations', + 'access arguments' => array(MIGRATE_ACCESS_ADVANCED), + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'file' => 'migrate_pages.inc', + ); $items['admin/content/migrate/process'] = array( 'title' => 'Process', 'description' => 'Perform and monitor the creation of Drupal content from source data', @@ -730,6 +728,14 @@ function migrate_menu() { 'access arguments' => array(MIGRATE_ACCESS_ADVANCED), 'file' => 'migrate_pages.inc', ); + $items['admin/content/migrate/destinations/import'] = array( + 'title' => 'Import', + 'page callback' => 'migrate_import_content_set', + 'access arguments' => array(MIGRATE_ACCESS_ADVANCED), + 'type' => MENU_LOCAL_TASK, + 'file' => 'migrate_export.inc', + 'weight' => 3, + ); $items['admin/content/migrate/destinations/%'] = array( 'title' => 'Content set', 'page callback' => 'drupal_get_form', @@ -738,6 +744,14 @@ function migrate_menu() { 'type' => MENU_CALLBACK, 'file' => 'migrate_pages.inc', ); + $items['admin/content/migrate/destinations/%/export'] = array( + 'title' => 'Content set', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('migrate_export_content_set', 4), + 'access arguments' => array(MIGRATE_ACCESS_ADVANCED), + 'type' => MENU_CALLBACK, + 'file' => 'migrate_export.inc', + ); $items['migrate/xlat/%'] = array( 'page callback' => 'migrate_xlat', 'access arguments' => array('access content'), @@ -919,3 +929,22 @@ function _migrate_message_table_schema($ function migrate_views_api() { return array('api' => '2.0'); } + +/** + * Retrieve list of mappings for a content set. + */ +function migrate_get_mappings($mcsid) { + $mappings = array(); + $result = db_query("SELECT * FROM {migrate_content_mappings} WHERE mcsid = %d", $mcsid); + while ($map = db_fetch_object($result)) { + $mappings[$map->destfield] = $map; + } + return $mappings; +} + +/** + * Check if this is a valid content set id. + */ +function migrate_validate_mcsid($mcsid) { + return db_query("SELECT count(*) FROM {migrate_content_sets} WHERE mcsid = %d", $mcsid); +} Index: migrate_export.inc =================================================================== RCS file: migrate_export.inc diff -N migrate_export.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ migrate_export.inc 17 Jul 2009 17:21:57 -0000 @@ -0,0 +1,160 @@ + $set->description))); + return drupal_get_form('migrate_destination_mappings', $set); + } + + return drupal_get_form('migrate_import_content_set_form'); +} + +/** + * Import content set form. + */ +function migrate_import_content_set_form() { + $form['content_set'] = array( + '#type' => 'textarea', + '#title' => t('Content set code'), + '#cols' => 60, + '#rows' => 15, + '#description' => t('Cut and paste the results of an exported content set here.'), + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Import'), + ); + + $form['#redirect'] = NULL; + return $form; +} + +/** + * Handle the submit button on importing a content set. + */ +function migrate_import_content_set_form_submit($form, &$form_state) { + ob_start(); + eval($form_state['values']['content_set']); + ob_end_clean(); + + if (isset($set)) { + include_once('./' . drupal_get_path('module', 'migrate') . '/migrate_pages.inc'); + $_SESSION['content_set_import'] = serialize($set); + drupal_set_title(t('Import content set "@s"', array('@s' => $set->description))); + $output = drupal_get_form('migrate_destination_mappings', $set); + print theme('page', $output); + exit; + } + else { + drupal_set_message(t('Unable to find a content set in the import data.')); + } +} + +/** + * Export a content set and display it in a form. + */ +function migrate_export_content_set(&$form_state, $mcsid) { + $set = migrate_content_set_load($mcsid); + drupal_set_title(check_plain($set->description)); + $code = migrate_content_set_export($set); + $lines = substr_count($code, "\n"); + + $form['export'] = array( + '#title' => t('Export data'), + '#type' => 'textarea', + '#value' => $code, + '#rows' => $lines, + '#description' => t('Copy the export text and paste it into another content set using the import function.'), + ); + return $form; +} + +/** + * Load a single content set. + */ +function migrate_content_set_load($mcsid) { + ctools_include('export'); + $view_name = db_result(db_query("SELECT view_name FROM {migrate_content_sets} WHERE mcsid = %d", $mcsid)); + $result = ctools_export_load_object('migrate_content_sets', 'names', array($view_name)); + if (isset($result[$view_name])) { + $result[$view_name]->mappings = migrate_content_set_mappings_load($mcsid, $view_name); + return $result[$view_name]; + } +} + +/** + * Load all content sets. + */ +function migrate_load_all_content_sets() { + ctools_include('export'); + $sets = ctools_export_load_object('migrate_content_sets'); + $mcsids = array(); + foreach ($sets as $set) { + $mcsids[$set->mcsid] = $set->view_name; + } + + $mappings = migrate_content_set_mappings_load_all($mcsids); + foreach ($mappings as $mcsid => $mapping) { + if (!empty($mapping)) { + $sets[$mcsids[$mcsid]]->mappings = $mapping; + } + } + + return $sets; +} + +/** + * Load all content set mappings. + */ +function migrate_content_set_mappings_load_all($mcsids) { + $mappings = array(); + foreach ($mcsids as $mcsid => $view_name) { + $mappings[$mcsid] = migrate_content_set_mappings_load($mcsid, $view_name); + } + return $mappings; +} + +/** + * Load a single content set mapping. + */ +function migrate_content_set_mappings_load($mcsid, $view_name = '') { + ctools_include('export'); + $result = db_query("SELECT * FROM {migrate_content_mappings} WHERE mcsid = %d", $mcsid); + $mappings = array(); + while ($obj = db_fetch_object($result)) { + $mapping = ctools_export_unpack_object('migrate_content_mappings', $obj); + $mappings[$mapping->mcsid]->mappings[$mapping->destfield] = $mapping; + } + return $mappings[$mcsid]->mappings; +} + +/** + * Export a content set. + */ +function migrate_content_set_export($set, $indent = '') { + ctools_include('export'); + $output = ctools_export_object('migrate_content_sets', $set, $indent); + // Export the mappings. + $mappings = !empty($set->mappings) ? $set->mappings : migrate_content_set_mappings_load($set->mcsid); + $output .= migrate_export_mappings($mappings, $indent); + return $output; +} + +/** + * Export the mappings for a content set. + */ +function migrate_export_mappings($mappings, $indent = '') { + ctools_include('export'); + foreach ($mappings as $destfield => $map) { + $output .= ctools_export_object('migrate_content_mappings', $map, $indent); + $output .= $indent . '$set->mappings["' . $map->destfield . '"] = $map' . ";\n"; + } + return $output; +} Index: migrate_pages.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/migrate/migrate_pages.inc,v retrieving revision 1.1.2.28 diff -u -p -r1.1.2.28 migrate_pages.inc --- migrate_pages.inc 17 Jul 2009 15:07:17 -0000 1.1.2.28 +++ migrate_pages.inc 17 Jul 2009 17:21:58 -0000 @@ -350,29 +350,45 @@ function _migrate_destination_form($form array('data' => t('')), ); - $sql = "SELECT mcs.* - FROM {migrate_content_sets} mcs - ORDER BY mcs.weight"; - $result = db_query($sql); + // Load all content sets, both those from the database and code. + include_once('./' . drupal_get_path('module', 'migrate') . '/migrate_export.inc'); + $sets = migrate_load_all_content_sets(); + $used_views = array(); - while ($row = db_fetch_object($result)) { - if ($row->desttype) { - $destination = $desttypes[$row->contenttype . '/' . $row->desttype]; + foreach ($sets as $view_name => $set) { + if ($set->desttype) { + $destination = $desttypes[$set->contenttype . '/' . $set->desttype]; } else { - $destination = $desttypes[$row->contenttype]; + $destination = $desttypes[$set->contenttype]; + } + + // All sets that are only in code, save to the database for subsequent + // processing. + // @TODO: do this some place more sensible? + if ($set->export_type == EXPORT_IN_CODE) { + unset($set->mcsid); + $set->mcsid = migrate_save_content_set($set); + foreach ($set->mappings as $mapping) { + unset($mapping->mcmid); + $mapping->mcsid = $set->mcsid; + migrate_save_content_mapping($mapping); + } + } + $rows[] = array('data' => array( - $row->description, - $row->view_name, + $set->description, + l($set->view_name, 'admin/content/tw/view/'. $set->view_name), $destination, - $row->weight, - l(t('Edit'), 'admin/content/migrate/destinations/'. $row->mcsid, array('html' => TRUE)), + $set->weight, + l(t('Edit'), 'admin/content/migrate/destinations/'. $set->mcsid, array('html' => TRUE)), + l(t('Export'), 'admin/content/migrate/destinations/'. $set->mcsid .'/export', array('html' => TRUE)), ), 'class' => "migrate-content-sets-tr", ); - $used_views[$row->view_name] = $row->view_name; + $used_views[$set->view_name] = $set->view_name; } if (!isset($rows)) { @@ -450,17 +466,29 @@ function _migrate_destination_form_submi /** * Menu callback function. */ -function migrate_destination_mappings($form_state, $mcsid) { - $row = db_fetch_object(db_query("SELECT * FROM {migrate_content_sets} - WHERE mcsid=%d", - $mcsid)); - $desttype = $row->desttype; - $view_name = $row->view_name; - $sourcekey = $row->sourcekey; - $description = $row->description; - $contenttype = $row->contenttype; - $desttype = $row->desttype; - $weight = $row->weight; +function migrate_destination_mappings($form_state, $set) { + include_once('./' . drupal_get_path('module', 'migrate') . '/migrate_export.inc'); + $mcsid = $set->mcsid; + if (!is_object($set)) { + $mcsid = $set; + $set = migrate_content_set_load($mcsid); + $in_db = 1; + } + else { + $in_db = migrate_validate_mcsid($mcsid); + } + // If this set doesn't exist in the database, reset $mcsid to 0 so the set + // will be added, rather than an update being attempted. + if (!$in_db) { + $mcsid = 0; + } + $desttype = $set->desttype; + $view_name = $set->view_name; + $sourcekey = $set->sourcekey; + $description = $set->description; + $contenttype = $set->contenttype; + $desttype = $set->desttype; + $weight = $set->weight; // Fetch information on available destinations $desttypes = migrate_invoke_all('destination', 'types'); @@ -546,25 +574,21 @@ function migrate_destination_mappings($f '#title' => t('Primary key of source view'), ); - $mappings = array(); + $mappings = (!empty($set->mappings) ? $set->mappings : migrate_get_mappings($mcsid)); $defaults = array(); $srcoptions = array_merge(array('' => t('')), $srcoptions); foreach ($destfields as $destfield => $destname) { - $sql = "SELECT * - FROM {migrate_content_mappings} - WHERE mcsid=%d AND destfield='%s'"; - $result = db_query($sql, $mcsid, $destfield); - $row = db_fetch_object($result); + $map = $mappings[$destfield]; $cols[] = $destfield; $form['srcfield'][$destfield] = array( '#type' => 'select', '#options' => $srcoptions, - '#default_value' => isset($row->srcfield) ? $row->srcfield : '', + '#default_value' => isset($map->srcfield) ? $map->srcfield : '', ); $form['default_value'][$destfield] = array( '#type' => 'textfield', - '#default_value' => isset($row->default_value) ? $row->default_value : '', + '#default_value' => isset($map->default_value) ? $map->default_value : '', '#size' => 25, '#maxlength' => 255, ); @@ -581,10 +605,20 @@ function migrate_destination_mappings($f '#value' => t('Submit changes'), ); } - $form['delete'] = array( - '#type' => 'submit', - '#value' => t('Delete'), - ); + // Only display the delete button if this content set already exists in the + // database. + if ($set->type == 'Overridden') { + $form['delete'] = array( + '#type' => 'submit', + '#value' => t('Reset'), + ); + } + elseif ($mcsid) { + $form['delete'] = array( + '#type' => 'submit', + '#value' => t('Delete'), + ); + } $form['#tree'] = TRUE; return $form; } @@ -627,8 +661,20 @@ function migrate_destination_mappings_su if ($form_state['clicked_button']['#parents'][0] == 'delete') { migrate_delete_content_set($mcsid); drupal_set_message(t('Content set deleted')); - $form_state['redirect'] = 'admin/content/migrate/destinations'; - } else { + } + elseif (empty($mcsid)) { + $mcsid = migrate_save_content_set($form_state['values']); + foreach ($form_state['values']['cols'] as $key => $destfield) { + $mapping = new stdClass; + $mapping->mcsid = $mcsid; + $mapping->srcfield = $form_state['values']['srcfield'][$destfield]; + $mapping->destfield = $destfield; + $mapping->default_value = $form_state['values']['default_value'][$destfield]; + migrate_save_content_mapping($mapping); + } + drupal_set_message('New content set saved.'); + } + else { // Get list of current mappings, so we know if any need deletion $sql = "SELECT mcmid,destfield FROM {migrate_content_mappings} WHERE mcsid=%d"; $result = db_query($sql, $mcsid); @@ -659,6 +705,7 @@ function migrate_destination_mappings_su migrate_save_content_set($form_state['values']); drupal_set_message('Changes saved'); } + $form_state['redirect'] = 'admin/content/migrate/destinations'; } function migrate_tools() {