tripal_chado.migrate.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. <?php
  2. /**
  3. * Implements hook_form()
  4. *
  5. * Provide a form to select Tripal v2 content types for migration
  6. *
  7. * @param $form
  8. * @param $form_state
  9. */
  10. function tripal_chado_migrate_form($form, &$form_state) {
  11. $form['overview_vert_tabs'] = array(
  12. '#type' => 'vertical_tabs'
  13. );
  14. $form['modes']['#group'] = 'overview_vert_tabs';
  15. $form['modes']['#weight'] = 1000;
  16. $form['step1'] = array(
  17. '#type' => 'fieldset',
  18. '#title' => 'Step1',
  19. '#description' => 'Enable Legacy Support',
  20. '#collapsible' => TRUE,
  21. '#collapsed' => TRUE,
  22. '#group' => 'overview_vert_tabs'
  23. );
  24. $form['step2'] = array(
  25. '#type' => 'fieldset',
  26. '#title' => 'Step2',
  27. '#description' => 'Migrate Content',
  28. '#collapsible' => TRUE,
  29. '#collapsed' => TRUE,
  30. '#group' => 'overview_vert_tabs'
  31. );
  32. $form['step2']['step2_content'] = array(
  33. '#type' => 'fieldset',
  34. '#collapsible' => FALSE,
  35. '#prefix' => '<div id="tripal-chado-migrate-form-step2">',
  36. '#suffix' => '</div>'
  37. );
  38. $tv2_content_type = 'all';
  39. if (array_key_exists('values', $form_state)) {
  40. $tv2_content_type = $form_state['values']['tv2_content_type'];
  41. }
  42. $options = tripal_chado_get_tripal_v2_content_type_options(TRUE);
  43. $form['step2']['step2_content']['tv2_content_type'] = array(
  44. '#type' => 'select',
  45. '#title' => 'Tripal v2 Content Type',
  46. '#description' => t('Select the Tripal v2 content type to migrate.'),
  47. '#options' => $options,
  48. '#default_value' => $tv2_content_type,
  49. '#ajax' => array(
  50. 'callback' => "tripal_chado_migrate_form_step2_ajax_callback",
  51. 'wrapper' => "tripal-chado-migrate-form-step2",
  52. 'effect' => 'fade',
  53. 'method' => 'replace'
  54. ),
  55. );
  56. // Add a review button that allows reviewing migratable content types
  57. if ($tv2_content_type != 'all') {
  58. $table = str_replace('chado_', '', $tv2_content_type);
  59. $schema = chado_get_schema($table);
  60. $pkey = $schema['primary key'][0];
  61. $fkeys = $schema['foreign keys'];
  62. $form['step2']['step2_content']['tv3_content_type'] = array(
  63. '#type' => 'fieldset',
  64. '#title' => 'Tripal v3 Content Type',
  65. '#description' => "Click the 'Get Tripal v3 Types' button to retrieve a list of Tripal v3
  66. content types to which this Tripal v2 type can be converted. This may take a while
  67. depending on the size of your database. The number of items to be converted is
  68. shown beside the type."
  69. );
  70. $form['step2']['step2_content']['tv3_content_type']['get_v3_type_btn'] = array(
  71. '#type' => 'button',
  72. '#name' => 'get_v3_type_btn',
  73. '#value' => "Get Tripal v3 Types",
  74. '#ajax' => array(
  75. 'callback' => "tripal_chado_migrate_form_step2_ajax_callback",
  76. 'wrapper' => "tripal-chado-migrate-form-step2",
  77. 'effect' => 'fade',
  78. 'method' => 'replace'
  79. ),
  80. );
  81. $no_data = TRUE;
  82. if ($form_state['clicked_button']['#name'] == 'get_v3_type_btn') {
  83. // Migrate all
  84. $form['step2']['step2_content']['tv3_content_type']['tv3_migrate_all'] = array(
  85. '#type' => 'checkbox',
  86. '#title' => 'Migrate All'
  87. );
  88. // Migrate selection only
  89. if (key_exists('cvterm', $fkeys) && key_exists('type_id', $fkeys['cvterm']['columns'])) {
  90. // Get all Tripal v2 node types from the chad_* linking table
  91. $sql =
  92. "SELECT V.name AS type, X.accession, db.name AS namespace , count(*) AS num
  93. FROM {" . $table . "} T
  94. INNER JOIN public.$tv2_content_type CT ON T.$pkey = CT.$pkey
  95. INNER JOIN {cvterm} V ON V.cvterm_id = T.type_id
  96. INNER JOIN {dbxref} X ON X.dbxref_id = V.dbxref_id
  97. INNER JOIN {db} ON db.db_id = X.db_id
  98. LEFT JOIN public.chado_entity CE ON CE.record_id = T.$pkey
  99. AND CE.data_table = '$table'
  100. WHERE CE.record_id IS NULL
  101. GROUP BY V.name, X.accession, db.name";
  102. $tv3_content_types = chado_query($sql);
  103. while($tv3_content_type = $tv3_content_types->fetchObject()) {
  104. // We need to store namespace/accession/type for each checkbox in the key becuase
  105. // the value only allows 1 or 0
  106. $key = urlencode(
  107. 'tv3_content_type--' .
  108. $tv3_content_type->namespace . '--' .
  109. $tv3_content_type->accession . '--' .
  110. $tv3_content_type->type);
  111. $form['step2']['step2_content']['tv3_content_type'][$key] = array(
  112. '#type' => 'checkbox',
  113. '#title' => $tv3_content_type->type . ' (' . $tv3_content_type->num . ')',
  114. );
  115. $no_data = FALSE;
  116. }
  117. }
  118. else if ($table == 'organism') {
  119. $sql =
  120. "SELECT count(*)
  121. FROM {organism} O
  122. INNER JOIN public.chado_organism CO ON O.organism_id = CO.organism_id
  123. LEFT JOIN public.chado_entity CE ON CE.record_id = O.organism_id
  124. AND CE.data_table = 'organism'
  125. WHERE CE.record_id IS NULL";
  126. $org_count = chado_query($sql)->fetchField();
  127. if ($org_count > 0) {
  128. $key = urldecode('tv3_content_type--local--organism--organism');
  129. $form['step2']['step2_content']['tv3_content_type'][$key] = array(
  130. '#type' => 'checkbox',
  131. '#title' => 'Organism (' . $org_count . ')',
  132. );
  133. $no_data = FALSE;
  134. }
  135. }
  136. else if ($table == 'analysis') {
  137. $sql =
  138. "SELECT count(*)
  139. FROM {analysis} A
  140. INNER JOIN public.chado_analysis CA ON A.analysis_id = CA.analysis_id
  141. LEFT JOIN public.chado_entity CE ON CE.record_id = A.analysis_id
  142. AND CE.data_table = 'analysis'
  143. WHERE CE.record_id IS NULL";
  144. $ana_count = chado_query($sql)->fetchField();
  145. if ($ana_count > 0) {
  146. $key = urlencode('tv3_content_type--local--analysis--analysis');
  147. $form['step2']['step2_content']['tv3_content_type'][$key] = array(
  148. '#type' => 'checkbox',
  149. '#title' => 'Analysis (' . $ana_count . ')',
  150. );
  151. $no_data = FALSE;
  152. }
  153. }
  154. if ($no_data) {
  155. unset($form['step2']['step2_content']['tv3_content_type']['tv3_migrate_all']);
  156. drupal_set_message('No data for migration or all have been migrated.', 'warning');
  157. }
  158. }
  159. }
  160. // Submit button
  161. if ($tv2_content_type == 'all' || key_exists('tv3_migrate_all', $form['step2']['step2_content']['tv3_content_type'])) {
  162. $form['step2']['step2_content']['migrate_btn'] = array(
  163. '#type' => 'submit',
  164. '#name' => 'migrate_btn',
  165. '#value' => "Migrate $options[$tv2_content_type]",
  166. );
  167. }
  168. $form['#prefix'] = '<div id="tripal-chado-migrate-form">';
  169. $form['#suffix'] = '</div>';
  170. return $form;
  171. }
  172. /**
  173. * Implements hook_validate()
  174. *
  175. * @param $form
  176. * @param $form_state
  177. */
  178. function tripal_chado_migrate_form_validate($form, &$form_state) {
  179. }
  180. /**
  181. * Implements hook_submit()
  182. *
  183. * By submiting the form, a Tripal job to migrate Tripal v2 content is submitted
  184. *
  185. * @param $form
  186. * @param $form_state
  187. */
  188. function tripal_chado_migrate_form_submit($form, &$form_state) {
  189. if ($form_state['clicked_button']['#name'] == 'migrate_btn') {
  190. global $user;
  191. $values = $form_state['values'];
  192. $tv2_content_type = $form_state['values']['tv2_content_type'];
  193. $tv3_content_type = array();
  194. foreach ($values AS $key => $value) {
  195. if ($tv2_content_type != 'all') {
  196. $key = urldecode($key);
  197. if (preg_match('/^tv3_content_type--(.+)--(.+)--(.+)/', $key, $matches) &&
  198. ($value == 1 || $values['tv3_migrate_all'] == 1)) {
  199. $namespace = $matches[1];
  200. $accession = $matches[2];
  201. $type = $matches[3];
  202. $tv3_content_type [] = array(
  203. 'namespace' => $namespace,
  204. 'accession' => $accession,
  205. 'term_name' => $type
  206. );
  207. }
  208. }
  209. }
  210. // Submit a job to migrate content
  211. global $user;
  212. $args = array(
  213. array(
  214. 'tv2_content_type' => $tv2_content_type,
  215. 'tv3_content_type' => $tv3_content_type
  216. )
  217. );
  218. $includes = array(
  219. module_load_include('inc', 'tripal_chado', 'includes/tripal_chado.migrate'),
  220. );
  221. if ($tv2_content_type == 'all' || count($tv3_content_type) != 0) {
  222. return tripal_add_job("Migrate $tv2_content_type Tripal v2 content.",
  223. 'tripal_chado', 'tripal_chado_migrate_records', $args, $user->uid, 10, $includes);
  224. }
  225. else {
  226. return drupal_set_message('Nothing to do. All data have been migrated or no data for migration.');
  227. }
  228. }
  229. }
  230. /**
  231. * Ajax call back that returns the entire form
  232. *
  233. * The callback is triggered by ajax elements on the form which leads to the update of
  234. * entire form according to the values set on the form
  235. *
  236. * @param $form
  237. * @param $form_state
  238. * @return $form
  239. */
  240. function tripal_chado_migrate_form_step2_ajax_callback(&$form, &$form_state) {
  241. return $form['step2']['step2_content'];
  242. }
  243. /**
  244. * Get available Tripal v2 content types
  245. *
  246. * @param boolean $all_option
  247. * Include an 'all' option in the returned array
  248. * @return string[]
  249. * Return a string array keyed by the node type
  250. */
  251. function tripal_chado_get_tripal_v2_content_type_options($all_option = FALSE) {
  252. // Get all available Tripal v2 chado tables
  253. $sql =
  254. "SELECT table_name
  255. FROM information_schema.tables
  256. WHERE table_schema = 'public' AND table_name LIKE 'chado_%'";
  257. $result = db_query($sql);
  258. $tables = array();
  259. while ($field = $result->fetchField()) {
  260. $count = db_query("SELECT count(*) FROM $field")->fetchField();
  261. if ($count != 0) {
  262. array_push($tables, $field);
  263. }
  264. }
  265. // List all available Tripal v2 content types
  266. $result = db_select('node_type', 'nt')
  267. ->fields('nt', array('type', 'name', 'description'))
  268. ->condition('type', 'chado_%', 'LIKE')
  269. ->execute();
  270. $options = array();
  271. if ($all_option) {
  272. $options['all'] = 'All';
  273. }
  274. while ($obj = $result->fetchObject()) {
  275. if (in_array($obj->type, $tables)) {
  276. $options[$obj->type] = $obj->name;
  277. }
  278. }
  279. return $options;
  280. }
  281. /**
  282. * Tripal job callback to migrate Tripal v2 content into Tripal v3 content
  283. *
  284. * @param $migration
  285. * @param $job_id
  286. */
  287. function tripal_chado_migrate_records($migration, $job_id = NULL) {
  288. $tv2_content_type = $migration['tv2_content_type'];
  289. $tv3_content_type = $migration['tv3_content_type'];
  290. // If tv2_content_type is 'all', migrate all existing Tripal v2 content
  291. if ($tv2_content_type == 'all') {
  292. print "Migrating all Tripal v2 content...\n";
  293. tripal_chado_migrate_all_types();
  294. }
  295. // Otherwise, migrate only selected Tripal v2 content
  296. else {
  297. print "Migrating selected Tripal v2 content...\n";
  298. tripal_chado_migrate_selected_types($tv3_content_type);
  299. }
  300. }
  301. /**
  302. * Migrate all Tripal v2 content types
  303. */
  304. function tripal_chado_migrate_all_types() {
  305. // Get all available Tripal v2 content types
  306. $tv2_content_types = tripal_chado_get_tripal_v2_content_type_options();
  307. $types = array();
  308. foreach($tv2_content_types AS $tv2_content_type => $value) {
  309. $table = str_replace('chado_', '', $tv2_content_type);
  310. $schema = chado_get_schema($table);
  311. $pkey = $schema['primary key'][0];
  312. $fkeys = $schema['foreign keys'];
  313. if (key_exists('cvterm', $fkeys) && key_exists('type_id', $fkeys['cvterm']['columns'])) {
  314. // Get all Tripal v2 node types from the chad_* linking table
  315. $sql = "
  316. SELECT V.name AS type, X.accession, db.name AS namespace
  317. FROM {" . $table . "} T
  318. INNER JOIN public.$tv2_content_type CT ON T.$pkey = CT.$pkey
  319. INNER JOIN {cvterm} V ON V.cvterm_id = T.type_id
  320. INNER JOIN {dbxref} X ON X.dbxref_id = V.dbxref_id
  321. INNER JOIN {db} ON db.db_id = X.db_id
  322. GROUP BY V.name, X.accession, db.name
  323. ";
  324. $tv3_content_types = chado_query($sql);
  325. while($tv3_content_type = $tv3_content_types->fetchObject()) {
  326. array_push($types, array(
  327. 'namespace' => $tv3_content_type->namespace,
  328. 'accession' => $tv3_content_type->accession,
  329. 'term_name' => $tv3_content_type->type
  330. ));
  331. }
  332. }
  333. else if ($table == 'organism') {
  334. array_push($types, array(
  335. 'namespace' => 'local',
  336. 'accession' => 'organism',
  337. 'term_name' => 'organism'
  338. ));
  339. }
  340. else if ($table == 'analysis') {
  341. array_push($types, array(
  342. 'namespace' => 'local',
  343. 'accession' => 'analysis',
  344. 'term_name' => 'analysis'
  345. ));
  346. }
  347. }
  348. tripal_chado_migrate_selected_types($types);
  349. }
  350. /**
  351. * Migrate only selected Tripal v2 content types
  352. *
  353. * @param unknown $tv3_content_type
  354. */
  355. function tripal_chado_migrate_selected_types($tv3_content_types) {
  356. foreach ($tv3_content_types AS $tv3_content_type) {
  357. // Check if the term already exists
  358. $term = tripal_load_term_entity($tv3_content_type);
  359. // If term doesn't exist, create a new bundle for this term
  360. if (!$term) {
  361. print("Creating bundle for term '" . $tv3_content_type['term_name'] . "'...\n");
  362. $success = tripal_create_bundle($tv3_content_type['namespace'], $tv3_content_type['accession'], $tv3_content_type['term_name']);
  363. $term = tripal_load_term_entity($tv3_content_type);
  364. }
  365. // Create bundle name
  366. $bundle_name = 'bio_data_' . $term->id;
  367. // Publish records for the bundle
  368. $value = array(
  369. 'sync_node' => 1,
  370. 'bundle_name' => $bundle_name
  371. );
  372. tripal_chado_publish_records ($value);
  373. }
  374. }