'vertical_tabs'
);
$form['modes']['#group'] = 'overview_vert_tabs';
$form['modes']['#weight'] = 1000;
// Step 1
$form['step1'] = array(
'#type' => 'fieldset',
'#title' => 'Step1',
'#description' => 'Enable Legacy Support',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#group' => 'overview_vert_tabs'
);
global $base_url;
$mod_url = $base_url . '/admin/modules';
$form['step1']['step1_content'] = array(
'#markup' => 'Tripal legacy modules are needed to support the display of Tripal v2
content types. Review and enable modules
in the \'Tripal v2 Legacy\' category for legacy content support'
);
// Step 2
$form['step2'] = array(
'#type' => 'fieldset',
'#title' => 'Step2',
'#description' => 'Migrate Content',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#group' => 'overview_vert_tabs'
);
$form['step2']['step2_container'] = array(
'#type' => 'container',
'#collapsible' => FALSE,
'#prefix' => '
',
'#suffix' => '
'
);
$tv2_content_type = 'all';
if (array_key_exists('values', $form_state)) {
$tv2_content_type = $form_state['values']['tv2_content_type'];
}
$tv2_options = tripal_chado_get_tripal_v2_content_type_options(TRUE);
$form['step2']['step2_container']['tv2_content_type'] = array(
'#type' => 'select',
'#title' => 'Tripal v2 Content Type',
'#description' => t('Select the Tripal v2 content type to migrate.'),
'#options' => $tv2_options,
'#default_value' => $tv2_content_type,
'#ajax' => array(
'callback' => "tripal_chado_migrate_form_step2_ajax_callback",
'wrapper' => "tripal-chado-migrate-form-step2",
'effect' => 'fade',
'method' => 'replace'
),
);
// Add a review button that allows reviewing migratable content types
if ($tv2_content_type != 'all') {
$table = str_replace('chado_', '', $tv2_content_type);
$schema = chado_get_schema($table);
$pkey = $schema['primary key'][0];
$fkeys = $schema['foreign keys'];
$form['step2']['step2_container']['tv3_content_type'] = array(
'#type' => 'fieldset',
'#title' => 'Tripal v3 Content Type',
'#description' => "Click the 'Get Tripal v3 Types' button to retrieve a list of Tripal v3
content types to which this Tripal v2 type can be converted. This may take a while
depending on the size of your database. The number of items to be converted is
shown beside the type."
);
$form['step2']['step2_container']['tv3_content_type']['get_v3_type_btn'] = array(
'#type' => 'button',
'#name' => 'get_v3_type_btn',
'#value' => "Get Tripal v3 Types",
'#ajax' => array(
'callback' => "tripal_chado_migrate_form_step2_ajax_callback",
'wrapper' => "tripal-chado-migrate-form-step2",
'effect' => 'fade',
'method' => 'replace'
),
);
$no_data = TRUE;
if ($form_state['clicked_button']['#name'] == 'get_v3_type_btn') {
// Migrate all
$form['step2']['step2_container']['tv3_content_type']['tv3_migrate_all'] = array(
'#type' => 'checkbox',
'#title' => 'Migrate All'
);
// Migrate selection only
if (key_exists('cvterm', $fkeys) && key_exists('type_id', $fkeys['cvterm']['columns'])) {
// Get all Tripal v2 node types from the chad_* linking table
$sql =
"SELECT V.name AS type, X.accession, db.name AS namespace , count(*) AS num
FROM {" . $table . "} T
INNER JOIN public.$tv2_content_type CT ON T.$pkey = CT.$pkey
INNER JOIN {cvterm} V ON V.cvterm_id = T.type_id
INNER JOIN {dbxref} X ON X.dbxref_id = V.dbxref_id
INNER JOIN {db} ON db.db_id = X.db_id
LEFT JOIN public.chado_entity CE ON CE.record_id = T.$pkey
AND CE.data_table = '$table'
WHERE CE.record_id IS NULL
GROUP BY V.name, X.accession, db.name";
$tv3_content_types = chado_query($sql);
while($tv3_content_type = $tv3_content_types->fetchObject()) {
// We need to store namespace/accession/type for each checkbox in the key becuase
// the value only allows 1 or 0
$key = urlencode(
'tv3_content_type--' .
$tv3_content_type->namespace . '--' .
$tv3_content_type->accession . '--' .
$tv3_content_type->type);
$form['step2']['step2_container']['tv3_content_type'][$key] = array(
'#type' => 'checkbox',
'#title' => $tv3_content_type->type . ' (' . $tv3_content_type->num . ')',
);
$no_data = FALSE;
}
}
else if ($table == 'organism') {
$sql =
"SELECT count(*)
FROM {organism} O
INNER JOIN public.chado_organism CO ON O.organism_id = CO.organism_id
LEFT JOIN public.chado_entity CE ON CE.record_id = O.organism_id
AND CE.data_table = 'organism'
WHERE CE.record_id IS NULL";
$org_count = chado_query($sql)->fetchField();
if ($org_count > 0) {
$key = urldecode('tv3_content_type--local--organism--organism');
$form['step2']['step2_container']['tv3_content_type'][$key] = array(
'#type' => 'checkbox',
'#title' => 'Organism (' . $org_count . ')',
);
$no_data = FALSE;
}
}
else if ($table == 'analysis') {
$sql =
"SELECT count(*)
FROM {analysis} A
INNER JOIN public.chado_analysis CA ON A.analysis_id = CA.analysis_id
LEFT JOIN public.chado_entity CE ON CE.record_id = A.analysis_id
AND CE.data_table = 'analysis'
WHERE CE.record_id IS NULL";
$ana_count = chado_query($sql)->fetchField();
if ($ana_count > 0) {
$key = urlencode('tv3_content_type--local--analysis--analysis');
$form['step2']['step2_container']['tv3_content_type'][$key] = array(
'#type' => 'checkbox',
'#title' => 'Analysis (' . $ana_count . ')',
);
$no_data = FALSE;
}
}
if ($no_data) {
unset($form['step2']['step2_container']['tv3_content_type']['tv3_migrate_all']);
drupal_set_message('No data for migration or all have been migrated.', 'warning');
}
}
}
// Migrate button
if ($tv2_content_type == 'all' || key_exists('tv3_migrate_all', $form['step2']['step2_container']['tv3_content_type'])) {
$form['step2']['step2_container']['migrate_btn'] = array(
'#type' => 'submit',
'#name' => 'migrate_btn',
'#value' => "Migrate $tv2_options[$tv2_content_type]",
);
}
// Step 3
$form['step3'] = array(
'#type' => 'fieldset',
'#title' => 'Step3',
'#description' => 'Use Legacy Templates (optional)',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#group' => 'overview_vert_tabs'
);
// Get a list of enabled legacy modules with tv2 templates
$mod_enabled = tripal_chado_migrate_get_enabled_legacy_modules(TRUE);
$enabled_templates = variable_get('tripal_chado_enabled_legacy_templates', array());
foreach ($mod_enabled AS $mod_name => $mod_path) {
$form ['step3']['legacy_template--' . $mod_name] = array (
'#type' => 'checkbox',
'#title' => ucwords(str_replace(array('tripal', '_'), array('chado', ' '), $mod_name)),
'#default_value' => key_exists('legacy_template--' . $mod_name, $enabled_templates) ? $enabled_templates['legacy_template--' . $mod_name] : 0,
);
}
$form['step3']['save_btn'] = array(
'#type' => 'button',
'#name' => 'save_enabled_template_btn',
'#value' => "Save",
);
// Step 4
$form['step4'] = array(
'#type' => 'fieldset',
'#title' => 'Step4',
'#description' => 'Complete Migration',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#group' => 'overview_vert_tabs'
);
$opt_complete_migration = array (
'delete' => 'Delete Tripal v2 Content',
'unpublish' => 'Unpublish Tripal v2 Content',
'cp_title' => 'Copy Title over to Tripal v3 Content',
'mv_url' => 'Migrate URL Alias to Tripal v3 Content'
);
foreach ($tv2_options AS $opt_key => $opt) {
$form['step4'][$opt_key . '_title'] = array(
'#markup' => "$opt"
);
$form['step4']['complete_migration--' . $opt_key] = array(
'#type' => 'checkboxes',
'#options' => $opt_complete_migration,
);
}
$form['step4']['submit_btn'] = array(
'#type' => 'button',
'#name' => 'complete_migration_btn',
'#value' => "Submit",
);
return $form;
}
/**
* Implements hook_validate()
*
* @param $form
* @param $form_state
*/
function tripal_chado_migrate_form_validate($form, &$form_state) {
// Store the legacy template setting in a Drupal variable
if ($form_state['clicked_button']['#name'] == 'save_enabled_template_btn') {
$values = $form_state['values'];
$enabled_templates = array();
foreach ($values AS $key => $value) {
if (preg_match('/^legacy_template--/', $key)) {
$enabled_templates[$key] = $value;
}
}
variable_set('tripal_chado_enabled_legacy_templates', $enabled_templates);
drupal_theme_rebuild();
}
// Complete migration
else if ($form_state['clicked_button']['#name'] == 'complete_migration_btn') {
$values = $form_state['values'];
$delete = array();
$unpublish = array();
$cp_title = array();
$mv_url = array();
foreach ($values AS $key => $value) {
if (preg_match('/^complete_migration--/', $key)) {
}
}
}
}
/**
* Implements hook_submit()
*
* By submiting the form, a Tripal job to migrate Tripal v2 content is submitted
*
* @param $form
* @param $form_state
*/
function tripal_chado_migrate_form_submit($form, &$form_state) {
if ($form_state['clicked_button']['#name'] == 'migrate_btn') {
global $user;
$values = $form_state['values'];
$tv2_content_type = $form_state['values']['tv2_content_type'];
$tv3_content_type = array();
foreach ($values AS $key => $value) {
if ($tv2_content_type != 'all') {
$key = urldecode($key);
if (preg_match('/^tv3_content_type--(.+)--(.+)--(.+)/', $key, $matches) &&
($value == 1 || $values['tv3_migrate_all'] == 1)) {
$namespace = $matches[1];
$accession = $matches[2];
$type = $matches[3];
$tv3_content_type [] = array(
'namespace' => $namespace,
'accession' => $accession,
'term_name' => $type
);
}
}
}
// Submit a job to migrate content
global $user;
$args = array(
array(
'tv2_content_type' => $tv2_content_type,
'tv3_content_type' => $tv3_content_type
)
);
$includes = array(
module_load_include('inc', 'tripal_chado', 'includes/tripal_chado.migrate'),
);
if ($tv2_content_type == 'all' || count($tv3_content_type) != 0) {
return tripal_add_job("Migrate $tv2_content_type Tripal v2 content.",
'tripal_chado', 'tripal_chado_migrate_records', $args, $user->uid, 10, $includes);
}
else {
return drupal_set_message('Nothing to do. All data have been migrated or no data for migration.');
}
}
}
/**
* Ajax call back that returns the entire form
*
* The callback is triggered by ajax elements on the form which leads to the update of
* entire form according to the values set on the form
*
* @param $form
* @param $form_state
* @return $form
*/
function tripal_chado_migrate_form_step2_ajax_callback(&$form, &$form_state) {
return $form['step2']['step2_container'];
}
/**
* Get available Tripal v2 content types
*
* @param boolean $all_option
* Include an 'all' option in the returned array
* @return string[]
* Return a string array keyed by the node type
*/
function tripal_chado_get_tripal_v2_content_type_options($all_option = FALSE) {
// Get all available Tripal v2 chado tables
$sql =
"SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public' AND table_name LIKE 'chado_%'";
$result = db_query($sql);
$tables = array();
while ($field = $result->fetchField()) {
$count = db_query("SELECT count(*) FROM $field")->fetchField();
if ($count != 0) {
array_push($tables, $field);
}
}
// List all available Tripal v2 content types
$result = db_select('node_type', 'nt')
->fields('nt', array('type', 'name', 'description'))
->condition('type', 'chado_%', 'LIKE')
->execute();
$options = array();
if ($all_option) {
$options['all'] = 'All';
}
while ($obj = $result->fetchObject()) {
if (in_array($obj->type, $tables)) {
$options[$obj->type] = $obj->name;
}
}
return $options;
}
/**
* Tripal job callback to migrate Tripal v2 content into Tripal v3 content
*
* @param $migration
* @param $job_id
*/
function tripal_chado_migrate_records($migration, $job_id = NULL) {
$tv2_content_type = $migration['tv2_content_type'];
$tv3_content_type = $migration['tv3_content_type'];
// If tv2_content_type is 'all', migrate all existing Tripal v2 content
if ($tv2_content_type == 'all') {
print "Migrating all Tripal v2 content...\n";
tripal_chado_migrate_all_types();
}
// Otherwise, migrate only selected Tripal v2 content
else {
print "Migrating selected Tripal v2 content...\n";
tripal_chado_migrate_selected_types($tv3_content_type);
}
}
/**
* Migrate all Tripal v2 content types
*
* Gather all available Tripal v2 content types and store the result in an associated array with
* values of namespace, accession, term_name. The array is then pass to the function
* tripal_chado_migrate_selected_types() that handles the migration
*/
function tripal_chado_migrate_all_types() {
// Get all available Tripal v2 content types
$tv2_content_types = tripal_chado_get_tripal_v2_content_type_options();
$types = array();
foreach($tv2_content_types AS $tv2_content_type => $value) {
$table = str_replace('chado_', '', $tv2_content_type);
$schema = chado_get_schema($table);
$pkey = $schema['primary key'][0];
$fkeys = $schema['foreign keys'];
if (key_exists('cvterm', $fkeys) && key_exists('type_id', $fkeys['cvterm']['columns'])) {
// Get all Tripal v2 node types from the chad_* linking table
$sql = "
SELECT V.name AS type, X.accession, db.name AS namespace
FROM {" . $table . "} T
INNER JOIN public.$tv2_content_type CT ON T.$pkey = CT.$pkey
INNER JOIN {cvterm} V ON V.cvterm_id = T.type_id
INNER JOIN {dbxref} X ON X.dbxref_id = V.dbxref_id
INNER JOIN {db} ON db.db_id = X.db_id
GROUP BY V.name, X.accession, db.name
";
$tv3_content_types = chado_query($sql);
while($tv3_content_type = $tv3_content_types->fetchObject()) {
array_push($types, array(
'namespace' => $tv3_content_type->namespace,
'accession' => $tv3_content_type->accession,
'term_name' => $tv3_content_type->type
));
}
}
else if ($table == 'organism') {
array_push($types, array(
'namespace' => 'local',
'accession' => 'organism',
'term_name' => 'organism'
));
}
else if ($table == 'analysis') {
array_push($types, array(
'namespace' => 'local',
'accession' => 'analysis',
'term_name' => 'analysis'
));
}
}
tripal_chado_migrate_selected_types($types);
}
/**
* Migrate only selected Tripal v2 content types
*
* @param unknown $tv3_content_type
*/
function tripal_chado_migrate_selected_types($tv3_content_types) {
foreach ($tv3_content_types AS $tv3_content_type) {
// Check if the term already exists
$term = tripal_load_term_entity($tv3_content_type);
// If term doesn't exist, create a new bundle for this term
if (!$term) {
print("Creating bundle for term '" . $tv3_content_type['term_name'] . "'...\n");
$success = tripal_create_bundle($tv3_content_type['namespace'], $tv3_content_type['accession'], $tv3_content_type['term_name']);
$term = tripal_load_term_entity($tv3_content_type);
}
// Create bundle name
$bundle_name = 'bio_data_' . $term->id;
// Publish records for the bundle
$value = array(
'sync_node' => 1,
'bundle_name' => $bundle_name
);
tripal_chado_publish_records ($value);
}
}
/**
* Get a list of enabled legacy modules
*
* return an associated array with value of module directory and keyed by the module name
*/
function tripal_chado_migrate_get_enabled_legacy_modules ($has_base_template = FALSE) {
$mod_enabled = module_list();
$legacy_mod = array ();
foreach ($mod_enabled AS $mod) {
if (preg_match('/^tripal_/', $mod)) {
$mod_dir = drupal_get_path('module', $mod);
if (preg_match('/\/legacy\//', $mod_dir) ) {
if ($has_base_template) {
if (file_exists($mod_dir . '/theme/templates/' . $mod . '_base.tpl.php')) {
$legacy_mod[$mod] = $mod_dir;
}
} else {
$legacy_mod[$mod] = $mod_dir;
}
}
}
}
return $legacy_mod;
}
/**
* Delete selected Tripal v2 content
*
* Delete all records from chado_* table then call the cleanup orphan nodes function
*
* @param unknown $tv2_content_types
*/
function tripal_chado_delete_selected_types($tv2_content_types = array()) {
foreach ($tv2_content_types AS $type) {
$sql = "DELETE FROM $type";
db_query($sql);
}
}
/**
* Unpublish selected Tripal v2 content
*
* Set status = 0 (unpublished) for all nodes of selected Tripal v2 content types
*
* @param unknown $tv2_content_types
*/
function tripal_chado_unpublish_selected_types($tv2_content_types = array()) {
foreach ($tv2_content_types AS $type) {
$sql = "UPDATE node SET status = 0 WHERE nid IN (SELECT nid FROM $type)";
db_query($sql);
}
}
/**
* Copy titles for selected Tripal v2 content
*
* Copy tiltles for all nodes of selected Tripal v2 content types
*
* @param unknown $tv2_content_types
*/
function tripal_chado_copy_title_for_selected_types($tv2_content_types = array()) {
foreach ($tv2_content_types AS $type) {
$sql = "SELECT nid, entity_id FROM chado_entity WHERE nid IN (SELECT nid FROM $type)";
$result = db_query($sql);
while ($entity = $result->fetchObject()) {
$usql = "
UPDATE tripal_entity
SET title = (SELECT title FROM node WHERE nid = :nid)
WHERE id = :entity_id";
db_query($usql, array(
':nid' => $entity->nid,
':entity_id' => $entity->entity_id)
);
}
}
}
/**
* Migrate URL alias for selected Tripal v2 content
*
* Migrate URL alias for all nodes of selected Tripal v2 content types
*
* @param unknown $tv2_content_types
*/
function tripal_chado_migrate_url_alias_for_selected_types($tv2_content_types = array()) {
foreach ($tv2_content_types AS $type) {
$sql = "SELECT nid, entity_id FROM chado_entity WHERE nid IN (SELECT nid FROM $type)";
$result = db_query($sql);
while ($entity = $result->fetchObject()) {
$usql = "
UPDATE url_alias
SET source = 'bio_data/'" . $entity->entity_id .
"WHERE source = 'node/" . $entity->nid;
db_query($usql);
}
}
}