t('Clear')),
array('data' => t('Import')),
array('data' => t('Scan')),
array('data' => t('Content Set')),
array('data' => t('Source')),
array('data' => t('Rows in Set')),
array('data' => t('Imported')),
array('data' => t('Unimported')),
array('data' => t('Last imported')),
);
$form['header'] = array('#type' => 'value', '#value' => $header);
$sql = "SELECT *
FROM {migrate_content_sets}
ORDER BY weight, contenttype, view_name";
$result = db_query($sql);
$clearing = array();
$clearingenable = array();
$importing = array();
$importingenable = array();
$scanning = array();
$scanningenable = array();
$rownum = 0;
while ($row = db_fetch_object($result)) {
$status = '';
if ($row->mcsid) {
$view = views_get_view($row->view_name);
if (!$view) {
drupal_set_message(t('View !view does not exist - either (re)create this view, or
remove the content set using it.', array('!view' => $row->view_name)));
continue;
}
$clearing[$row->mcsid] = '';
$importing[$row->mcsid] = '';
$scanning[$row->mcsid] = '';
$status = t('N/A');
$maptable = migrate_map_table_name($row->mcsid);
$sourcekey = $row->sourcekey;
if ($row->clearing) {
$clearingenable[] = $row->mcsid;
}
if ($row->importing) {
$importingenable[] = $row->mcsid;
}
if ($row->scanning) {
$scanningenable[] = $row->mcsid;
}
$imported = db_result(db_query('SELECT COUNT(*) FROM {' . $maptable . '}'));
// If not caching counts, override the saved count with a fresh count
if (!variable_get('migrate_cache_counts', 0)) {
$row->rowcount = _migrate_get_view_count($view);
}
$unimported = $row->rowcount - $imported;
$msgtablename = migrate_message_table_name($row->mcsid);
if ($unimported > 0) {
$messages = '';
/* Restore when views integration is fully implemented
$unimported = l($unimported, 'admin/content/migrate/audit/'.$row->view_name.'_unimported');*/
$numerrors = db_result(db_query("SELECT COUNT(DISTINCT sourceid)
FROM {" . $msgtablename . "}
WHERE level=%d",
MIGRATE_MESSAGE_ERROR));
if ($numerrors > 0) {
$messages .= l(format_plural($numerrors, '1 error', '@count errors'),
"admin/content/tw/view/$msgtablename/" . MIGRATE_MESSAGE_ERROR,
array('html' => TRUE))
. '
';
}
$numwarnings = db_result(db_query("SELECT COUNT(DISTINCT sourceid)
FROM {" . $msgtablename . "}
WHERE level=%d",
MIGRATE_MESSAGE_WARNING));
if ($numwarnings > 0) {
$messages .= l(format_plural($numwarnings, '1 warning', '@count warnings'),
"admin/content/tw/view/$msgtablename/" . MIGRATE_MESSAGE_WARNING,
array('html' => TRUE))
. '
';
}
$numnotices = db_result(db_query("SELECT COUNT(DISTINCT sourceid)
FROM {" . $msgtablename . "}
WHERE level=%d",
MIGRATE_MESSAGE_NOTICE));
if ($numnotices > 0) {
$messages .= l(format_plural($numnotices, '1 notice', '@count notices'),
"admin/content/tw/view/$msgtablename/" . MIGRATE_MESSAGE_NOTICE,
array('html' => TRUE))
. '
';
}
if ($messages) {
$unimported = $messages . " $unimported total";
}
}
if ($imported > 0) {
$numinformational = db_result(db_query("SELECT COUNT(DISTINCT sourceid)
FROM {" . $msgtablename . "}
WHERE level=%d",
MIGRATE_MESSAGE_INFORMATIONAL));
if ($numinformational > 0) {
$imported .= '
' .
l(format_plural($numinformational, '1 informational message', '@count informational messages'),
"admin/content/tw/view/$msgtablename/" . MIGRATE_MESSAGE_INFORMATIONAL,
array('html' => TRUE))
. '
';
}
}
}
else {
$imported = '';
$unimported = '';
}
$form['data'][$rownum]['clearing'] = array('#value' => check_plain($row->clearing));
$form['data'][$rownum]['importing'] = array('#value' => check_plain($row->importing));
$form['data'][$rownum]['scanning'] = array('#value' => check_plain($row->scanning));
$form['data'][$rownum]['description'] = array('#value' =>
l($row->description, 'admin/content/migrate/content_sets/' . $row->mcsid));
$form['data'][$rownum]['view_name'] = array('#value' =>
l($row->view_name, 'admin/build/views/edit/'. $row->view_name));
$form['data'][$rownum]['importrows'] = array('#value' => check_plain($row->rowcount));
$form['data'][$rownum]['imported'] = array('#value' => $imported);
$form['data'][$rownum]['unimported'] = array('#value' => $unimported);
$form['data'][$rownum]['lastimported'] = array('#value' => $row->lastimported);
$form['data'][$rownum]['mcsid'] = array('#value' => check_plain($row->mcsid));
$form['data'][$rownum]['semaphore'] = array('#value' => $row->semaphore);
$rownum++;
}
$form['clearing'] = array(
'#type' => 'checkboxes',
'#options' => $clearing,
'#default_value' => $clearingenable,
);
$form['importing'] = array(
'#type' => 'checkboxes',
'#options' => $importing,
'#default_value' => $importingenable,
);
$form['scanning'] = array(
'#type' => 'checkboxes',
'#options' => $scanning,
'#default_value' => $scanningenable,
);
if (user_access(MIGRATE_ACCESS_ADVANCED)) {
$form['interactive'] = array(
'#type' => 'fieldset',
'#title' => t('Interactive mode'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#description' => t('While large migration tasks are best run in the non interactively (via drush or cron),
you may choose here to begin tasks interactively; either because they are relatively small,
or to test subsets of the migration.'),
);
$form['interactive']['donow'] = array(
'#type' => 'checkbox',
'#default_value' => 1,
'#title' => t('Enable'),
'#description' => t('If enabled, processing of selected processes begins immediately
upon clicking Submit, with any unfinished processing continued in the background.
If disabled, processing will be done entirely in the background beginning with the next cron.'),
);
$form['interactive']['limit'] = array(
'#type' => 'textfield',
'#title' => t('Sample size'),
'#size' => 4,
'#description' => t('Number of records to process in the current interactive run. Leave
blank to process all records that can be completed within the PHP max_execution_time.'),
'#default_value' => variable_get('migrate_limit', ''),
);
$form['interactive']['idlist'] = array(
'#type' => 'textfield',
'#title' => t('Source IDs'),
'#size' => 30,
'#description' => t('Enter a comma-separated list of IDs from the incoming content set, to
process only those records in the current interactive run.'),
);
$form['clearsemaphores'] = array(
'#type' => 'checkbox',
'#title' => t('Unstick migration process'),
'#description' => t('An error during processing can leave a migration semaphore enabled,
preventing further processing. When this happens, you will see the message that a content
set "has an operation already in progress" when you are sure there is no process currently running
(even in cron or drush). Check this box to clear the semaphores when this happens.'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t("Submit"),
);
}
return $form;
}
function theme_migrate_dashboard($form) {
$output = drupal_render($form['description']);
if (isset($form['data']) && is_array($form['data'])) {
foreach (element_children($form['data']) as $rownum) {
$row = array();
foreach (element_children($form['data'][$rownum]) as $colname) {
if ($colname == 'clearing' || $colname == 'importing' || $colname == 'scanning') {
$row[] = drupal_render($form[$colname][$form['data'][$rownum]['mcsid']['#value']]);
// Throw out the column contents
drupal_render($form['data'][$rownum][$colname]);
drupal_render($form['data'][$rownum]['mcsid']);
}
else {
$row[] = drupal_render($form['data'][$rownum][$colname]);
}
}
// Highlight any process currently running
if ($form['data'][$rownum]['semaphore']['#value']) {
$rows[] = array('data' => $row, 'class' => 'migrate-running');
}
else {
$rows[] = $row;
}
}
}
$header = $form['header']['#value'];
if (!$rows) {
$rows[] = array(array('data' => t('No data in the table.'), 'colspan' => count($header)));
}
$output .= theme('table', $header, $rows, array('class' => 'migrate-dashboard'));
$output .= drupal_render($form);
return $output;
}
/*
* Implementation of hook_submit().
*/
function _migrate_dashboard_form_submit($form, &$form_state) {
$started = time();
foreach ($form_state['values']['importing'] as $mcsid => $value) {
if ($value) {
$importing = TRUE;
}
else {
$importing = FALSE;
}
if ($form_state['values']['clearing'][$mcsid]) {
$clearing = TRUE;
}
else {
$clearing = FALSE;
}
if ($form_state['values']['scanning'][$mcsid]) {
$scanning = TRUE;
}
else {
$scanning = FALSE;
}
db_query("UPDATE {migrate_content_sets}
SET clearing=%d, importing=%d, scanning=%d
WHERE mcsid=%d",
$clearing, $importing, $scanning, $mcsid);
}
if ($form_state['values']['clearsemaphores']) {
db_query("UPDATE {migrate_content_sets} SET semaphore=0");
}
if ($form_state['values']['donow']) {
variable_set('migrate_limit', $form_state['values']['limit']);
$batch = array(
'operations' => array(
array('migrate_content_process_all_batch', array($started, $form_state['values']['limit'],
trim($form_state['values']['idlist'])))),
'title' => t('Migration processing'),
'file' => drupal_get_path('module', 'migrate') . '/migrate_pages.inc',
'init_message' => t('Starting migration process'),
'progress_message' => t(''),
'error_message' => t('An error occurred. Some or all of the migrate processing has failed.'),
'finished' => '_migrate_content_process_finish',
);
batch_set($batch);
}
}
/**
* Batch API finished callback - report results
*
* @param $success
* @param $results
* @param $operations
*/
function _migrate_content_process_finish($success, $results, $operations) {
foreach ($results as $result) {
drupal_set_message($result);
}
}
/**
* Enter description here...
*
* @return unknown
*/
function migrate_content_sets() {
return (drupal_get_form('_migrate_content_set_form'));
}
function _migrate_content_set_form($form_state) {
// Fetch information on available destinations
$desttypes = migrate_invoke_all('types');
$header = array(
array('data' => t('Description'), 'field' => 'description'),
array('data' => t('Destination'), 'field' => 'contenttype'),
array('data' => t('Source view'), 'field' => 'view_name'),
array('data' => t('Weight'), 'field' => 'weight', 'sort' => 'asc'),
);
$sql = "SELECT *
FROM {migrate_content_sets} ";
$sql .= tablesort_sql($header);
$result = db_query($sql);
$used_views = array();
while ($row = db_fetch_object($result)) {
if ($row->desttype) {
$destination = $desttypes[$row->contenttype . '/' . $row->desttype];
}
else {
$destination = $desttypes[$row->contenttype];
}
$rows[] = array('data' =>
array(
l($row->description, 'admin/content/migrate/content_sets/' . $row->mcsid,
array('html' => TRUE)),
$destination,
l($row->view_name, 'admin/build/views/edit/' . $row->view_name),
$row->weight,
),
'class' => "migrate-content-sets-tr",
);
$used_views[$row->view_name] = $row->view_name;
}
if (!isset($rows)) {
$rows[] = array(array('data' => t('No content sets have been defined'), 'colspan' => count($header)));
}
$form['setlist'] = array(
'#value' => theme('table', $header, $rows, array('id' => 'migrate-content-sets')),
);
$form['addset'] = array(
'#type' => 'fieldset',
'#title' => t('Add a content set'),
'#collapsible' => TRUE,
);
$form['addset']['description'] = array(
'#type' => 'textfield',
'#title' => t('Description of the content set'),
'#description' => t('A friendly phrase only used for display.'),
);
$form['addset']['contenttype'] = array(
'#type' => 'select',
'#title' => t('Destination'),
'#options' => $desttypes,
'#description' => t('The type of Drupal content which will store the incoming records.'),
);
$views = views_get_all_views();
foreach ($views as $name => $view) {
if (!isset($used_views[$name])) {
if ($view->tag) {
$options[$name] = $view->tag . ': ' . $name;
}
else {
$options[$name] = $name;
}
if ($view->description) {
if (drupal_strlen($view->description) > 60) {
$view->description = drupal_substr($view->description, 0, 57) . '...';
}
$options[$name] .= " ($view->description)";
}
}
}
asort($options);
$form['addset']['sourceview'] = array(
'#type' => 'select',
'#title' => t('Source view from which to import content'),
'#options' => $options,
'#description' => t('This View defines the records which are to be migrated.'),
);
$form['addset']['weight'] = array(
'#type' => 'textfield',
'#title' => t('Weight'),
'#description' => t('The order in which content sets will be processed and displayed.'),
);
$form['addset']['add'] = array(
'#type' => 'submit',
'#value' => t('Add'),
);
return $form;
}
function _migrate_content_set_validate($form_state) {
$description = trim($form_state['values']['description']);
if (!$description) {
form_set_error('description', t('A description is required.'));
}
$weight = trim($form_state['values']['weight']);
if (!is_numeric($weight) || (((int)$weight) != $weight)) {
form_set_error('weight', t('Weight must be an integer value (positive or negative)'));
}
}
function _migrate_content_set_form_validate($form, $form_state) {
_migrate_content_set_validate($form_state);
}
function _migrate_content_set_form_submit($form, &$form_state) {
$content_set['view_name'] = $form_state['values']['sourceview'];
$content_set['description'] = $form_state['values']['description'];
$destination = explode('/', $form_state['values']['contenttype']);
$content_set['contenttype'] = $destination[0];
if (isset($destination[1])) {
$content_set['desttype'] = $destination[1];
}
$content_set['weight'] = $form_state['values']['weight'];
$mcsid = migrate_save_content_set($content_set);
// Go straight to the mapping form
$form_state['redirect'] = "admin/content/migrate/content_sets/$mcsid";
}
/**
* Menu callback function.
*/
function migrate_content_set_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;
// Fetch information on available destinations
$desttypes = migrate_invoke_all('types');
$destfields = migrate_invoke_all("fields_$contenttype", $desttype);
$form['mcsid'] = array(
'#type' => 'value',
'#value' => $mcsid,
);
$form['description'] = array(
'#type' => 'textfield',
'#title' => t('Description of the content set'),
'#default_value' => $description,
);
$form['show_view_name'] = array(
'#prefix' => '