tripal_chado.migrate.inc 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  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['overview_vert_tabs']['#default_tab'] = key_exists('tripal_migrate_current_tab', $_SESSION) ? $_SESSION['tripal_migrate_current_tab'] : 'edit-step1';
  15. $form['instructions'] = array(
  16. '#type' => 'item',
  17. '#markup' => t('Here you may migrate Tripal v2 content types to Tripal v3
  18. content types. The migration process is divided into four steps that
  19. allow you to migrate your site as your own pace. Please click each
  20. step below for details as to the purpose of the step. When all steps
  21. are completed your site will be fully Tripal v3 compatible.'),
  22. '#weight' => -100
  23. );
  24. // Step 1
  25. $form['step1'] = array(
  26. '#type' => 'fieldset',
  27. '#title' => 'Step1',
  28. '#description' => '<b>Enable Legacy Support</b>',
  29. '#collapsible' => TRUE,
  30. '#collapsed' => TRUE,
  31. '#group' => 'overview_vert_tabs'
  32. );
  33. global $base_url;
  34. $mod_url = '/admin/modules';
  35. $form['step1']['step1_content'] = array(
  36. '#markup' => 'Tripal legacy modules are needed to support the display of Tripal v2
  37. content types. Review and ' . l('enable modules', $mod_url) . ' in the \'Tripal v2 Legacy\' category
  38. for legacy content support. Only content types for enabled legacy
  39. moodules can be migrated'
  40. );
  41. // Step 2
  42. $form['step2'] = array(
  43. '#type' => 'fieldset',
  44. '#title' => 'Step2',
  45. '#description' => '<b>Migrate Content</b>',
  46. '#collapsible' => TRUE,
  47. '#collapsed' => TRUE,
  48. '#group' => 'overview_vert_tabs'
  49. );
  50. $form['step2']['step2_container'] = array(
  51. '#type' => 'container',
  52. '#collapsible' => FALSE,
  53. '#prefix' => '<div id="tripal-chado-migrate-form-step2">',
  54. '#suffix' => '</div>'
  55. );
  56. $form['step2']['step2_container']['instructions'] = array(
  57. '#type' => 'item',
  58. '#markup' => t('Here you can migrate Tripal v2 content types to Tripal v3
  59. content types. This will not destroy or remove existing Tripal v2 pages
  60. but will creatte new Tripal v3 pages. This allows you to keep existing
  61. pages while reviewing and customizing the Tripal v3 content types. Site
  62. visitors can continue to visit the Tripal v2 pages. Tripal
  63. v3 content types may remain private while customization is underway.
  64. Once customization is completed a subsequent step will allow you to
  65. swap out Tripal v2 pages for the newer Tripal v3 pages.') .
  66. t('If you would like to use Trial v3 web services you must migrate
  67. content types.'),
  68. );
  69. $tv2_content_type = 'all';
  70. if (array_key_exists('values', $form_state)) {
  71. $tv2_content_type = $form_state['values']['tv2_content_type'];
  72. }
  73. $tv2_options = tripal_chado_get_tripal_v2_content_type_options(TRUE);
  74. $form['step2']['step2_container']['tv2_content_type'] = array(
  75. '#type' => 'select',
  76. '#title' => 'Tripal v2 Content Type',
  77. '#description' => t('Select the Tripal v2 content type to migrate.'),
  78. '#options' => $tv2_options,
  79. '#default_value' => $tv2_content_type,
  80. '#ajax' => array(
  81. 'callback' => "tripal_chado_migrate_form_step2_ajax_callback",
  82. 'wrapper' => "tripal-chado-migrate-form-step2",
  83. 'effect' => 'fade',
  84. 'method' => 'replace'
  85. ),
  86. );
  87. // Add a review button that allows reviewing migratable content types
  88. if ($tv2_content_type != 'all') {
  89. $table = str_replace('chado_', '', $tv2_content_type);
  90. $schema = chado_get_schema($table);
  91. $pkey = $schema['primary key'][0];
  92. $fkeys = $schema['foreign keys'];
  93. $form['step2']['step2_container']['tv3_content_type'] = array(
  94. '#type' => 'fieldset',
  95. '#title' => 'Tripal v3 Content Type',
  96. '#description' => "Click the 'Get Tripal v3 Types' button to retrieve a list of Tripal v3
  97. content types to which this Tripal v2 type can be converted. This may take a while
  98. depending on the size of your database. The number of items to be converted is
  99. shown beside the type."
  100. );
  101. $form['step2']['step2_container']['tv3_content_type']['get_v3_type_btn'] = array(
  102. '#type' => 'button',
  103. '#name' => 'get_v3_type_btn',
  104. '#value' => "Get Tripal v3 Types",
  105. '#ajax' => array(
  106. 'callback' => "tripal_chado_migrate_form_step2_ajax_callback",
  107. 'wrapper' => "tripal-chado-migrate-form-step2",
  108. 'effect' => 'fade',
  109. 'method' => 'replace'
  110. ),
  111. );
  112. $no_data = TRUE;
  113. if ($form_state['clicked_button']['#name'] == 'get_v3_type_btn') {
  114. // Migrate all
  115. $form['step2']['step2_container']['tv3_content_type']['tv3_migrate_all'] = array(
  116. '#type' => 'checkbox',
  117. '#title' => 'Migrate All'
  118. );
  119. // Migrate selection only
  120. if ($table == 'organism') {
  121. $sql =
  122. "SELECT count(*)
  123. FROM {organism} O
  124. INNER JOIN public.chado_organism CO ON O.organism_id = CO.organism_id
  125. LEFT JOIN public.chado_entity CE ON CE.record_id = O.organism_id
  126. AND CE.data_table = 'organism'
  127. WHERE CE.record_id IS NULL";
  128. $org_count = chado_query($sql)->fetchField();
  129. if ($org_count > 0) {
  130. $key = urldecode('tv3_content_type--OBI--0100026--organism');
  131. $form['step2']['step2_container']['tv3_content_type'][$key] = array(
  132. '#type' => 'checkbox',
  133. '#title' => 'Organism (' . $org_count . ')',
  134. );
  135. $no_data = FALSE;
  136. }
  137. }
  138. else if ($table == 'analysis') {
  139. $sql =
  140. "SELECT count(*)
  141. FROM {analysis} A
  142. INNER JOIN public.chado_analysis CA ON A.analysis_id = CA.analysis_id
  143. LEFT JOIN public.chado_entity CE ON CE.record_id = A.analysis_id
  144. AND CE.data_table = 'analysis'
  145. WHERE CE.record_id IS NULL";
  146. $ana_count = chado_query($sql)->fetchField();
  147. if ($ana_count > 0) {
  148. $key = urlencode('tv3_content_type--local--analysis--analysis');
  149. $form['step2']['step2_container']['tv3_content_type'][$key] = array(
  150. '#type' => 'checkbox',
  151. '#title' => 'Analysis (' . $ana_count . ')',
  152. );
  153. $no_data = FALSE;
  154. }
  155. }
  156. else if ($table == 'project') {
  157. $sql =
  158. "SELECT count(*)
  159. FROM {project} P
  160. INNER JOIN public.chado_project CP ON P.project_id = CP.project_id
  161. LEFT JOIN public.chado_entity CE ON CE.record_id = P.project_id
  162. AND CE.data_table = 'project'
  163. WHERE CE.record_id IS NULL";
  164. $proj_count = chado_query($sql)->fetchField();
  165. if ($proj_count > 0) {
  166. $key = urlencode('tv3_content_type--local--project--project');
  167. $form['step2']['step2_container']['tv3_content_type'][$key] = array(
  168. '#type' => 'checkbox',
  169. '#title' => 'Project (' . $proj_count . ')',
  170. );
  171. $no_data = FALSE;
  172. }
  173. }
  174. else if ($table == 'featuremap') {
  175. $sql =
  176. "SELECT count(*)
  177. FROM {featuremap} M
  178. INNER JOIN public.chado_featuremap CM ON M.featuremap_id = CM.featuremap_id
  179. LEFT JOIN public.chado_entity CE ON CE.record_id = M.featuremap_id
  180. AND CE.data_table = 'featuremap'
  181. WHERE CE.record_id IS NULL";
  182. $map_count = chado_query($sql)->fetchField();
  183. if ($map_count > 0) {
  184. $key = urlencode('tv3_content_type--data--1274--map');
  185. $form['step2']['step2_container']['tv3_content_type'][$key] = array(
  186. '#type' => 'checkbox',
  187. '#title' => 'Map (' . $map_count . ')',
  188. );
  189. $no_data = FALSE;
  190. }
  191. }
  192. else if ($table == 'pub') {
  193. $sql =
  194. "SELECT count(*)
  195. FROM {pub} P
  196. INNER JOIN public.chado_pub CP ON P.pub_id = CP.pub_id
  197. LEFT JOIN public.chado_entity CE ON CE.record_id = P.pub_id
  198. AND CE.data_table = 'pub'
  199. WHERE CE.record_id IS NULL";
  200. $proj_count = chado_query($sql)->fetchField();
  201. if ($proj_count > 0) {
  202. $key = urlencode('tv3_content_type--TPUB--0000002--Publication');
  203. $form['step2']['step2_container']['tv3_content_type'][$key] = array(
  204. '#type' => 'checkbox',
  205. '#title' => 'Publication (' . $proj_count . ')',
  206. );
  207. $no_data = FALSE;
  208. }
  209. }
  210. else if (key_exists('cvterm', $fkeys) && key_exists('type_id', $fkeys['cvterm']['columns'])) {
  211. // Get all Tripal v2 node types from the chad_* linking table
  212. $sql =
  213. "SELECT V.name AS type, X.accession, db.name AS vocabulary , count(*) AS num
  214. FROM {" . $table . "} T
  215. INNER JOIN public.$tv2_content_type CT ON T.$pkey = CT.$pkey
  216. INNER JOIN {cvterm} V ON V.cvterm_id = T.type_id
  217. INNER JOIN {dbxref} X ON X.dbxref_id = V.dbxref_id
  218. INNER JOIN {db} ON db.db_id = X.db_id
  219. LEFT JOIN public.chado_entity CE ON CE.record_id = T.$pkey
  220. AND CE.data_table = '$table'
  221. WHERE CE.record_id IS NULL
  222. GROUP BY V.name, X.accession, db.name";
  223. $tv3_content_types = chado_query($sql);
  224. while($tv3_content_type = $tv3_content_types->fetchObject()) {
  225. // We need to store vocabulary/accession/type for each checkbox in the key becuase
  226. // the value only allows 1 or 0
  227. $key = urlencode(
  228. 'tv3_content_type--' .
  229. $tv3_content_type->vocabulary . '--' .
  230. $tv3_content_type->accession . '--' .
  231. $tv3_content_type->type);
  232. $form['step2']['step2_container']['tv3_content_type'][$key] = array(
  233. '#type' => 'checkbox',
  234. '#title' => $tv3_content_type->type . ' (' . $tv3_content_type->num . ')',
  235. );
  236. $no_data = FALSE;
  237. }
  238. }
  239. if ($no_data) {
  240. unset($form['step2']['step2_container']['tv3_content_type']['tv3_migrate_all']);
  241. drupal_set_message('No data for migration or all have been migrated.', 'warning');
  242. }
  243. }
  244. }
  245. // Migrate button
  246. if ($tv2_content_type == 'all' || key_exists('tv3_migrate_all', $form['step2']['step2_container']['tv3_content_type'])) {
  247. $form['step2']['step2_container']['migrate_btn'] = array(
  248. '#type' => 'submit',
  249. '#name' => 'migrate_btn',
  250. '#value' => "Migrate $tv2_options[$tv2_content_type]",
  251. );
  252. }
  253. // Step 3
  254. $form['step3'] = array(
  255. '#type' => 'fieldset',
  256. '#title' => 'Step3',
  257. '#description' => '<b>Use Legacy Templates (optional)</b>',
  258. '#collapsible' => TRUE,
  259. '#collapsed' => TRUE,
  260. '#group' => 'overview_vert_tabs'
  261. );
  262. $form['step3']['instructions'] = array(
  263. '#type' => 'item',
  264. '#markup' => t('Once content types have been migrated you have the option
  265. to use the Tripal v2 display templates. Tripal v3 allows you to
  266. customize the page layout using a web interface whereas Tripal v2
  267. required programatic changes to template files. If your site has
  268. considerable Tripal v2 customizations that you do not
  269. want to lose you can use the legacy templates by checking the box
  270. for the desired content types below.'),
  271. );
  272. // Get a list of enabled legacy modules with tv2 templates
  273. $enabled_templates = variable_get('tripal_chado_enabled_legacy_templates', array());
  274. $info = module_invoke_all('node_info');
  275. $options = tripal_chado_get_tripal_v2_content_type_options(FALSE, TRUE);
  276. foreach ($options AS $type_name => $type_label) {
  277. $title = $type_label;
  278. if ($type_name != 'all' and !key_exists($type_name, $info)) {
  279. $title .= " <strong>(please enable the $type_name legacy module).</strong>";
  280. }
  281. $form ['step3']['legacy_template--' . $type_name] = array (
  282. '#type' => 'checkbox',
  283. '#title' => $title,
  284. '#default_value' => key_exists('legacy_template--' . $type_name, $enabled_templates) ? $enabled_templates['legacy_template--' . $type_name] : 0,
  285. );
  286. }
  287. $form['step3']['save_btn'] = array(
  288. '#type' => 'submit',
  289. '#name' => 'save_enabled_template_btn',
  290. '#value' => "Save",
  291. );
  292. // Step 4
  293. $form['step4'] = array(
  294. '#type' => 'fieldset',
  295. '#title' => 'Step4',
  296. '#description' => '<b>Complete Migration</b>',
  297. '#collapsible' => TRUE,
  298. '#collapsed' => TRUE,
  299. '#group' => 'overview_vert_tabs'
  300. );
  301. $form['step4']['instructions'] = array(
  302. '#type' => 'item',
  303. '#markup' => t('This step allows you to fully switch to Tripal v3 pages.
  304. You can move URLs and titles from Tripal v2 pages to their
  305. corresponding Tripal v3 pages. This ensures user bookmarks and external
  306. links to your site are not broken. Here you can also unpublish Tripal
  307. v2 content types or completely remove them if desired. You can
  308. perform these action in stages such as first moving titles and URLs,
  309. then unpublishing Tripal v2 pages and once the migration has been
  310. verified you can finally delete the Tripal v2 pages to free space.
  311. Deleting the Tripal v2 content will not delete the data in Chado.
  312. The page is simply removed from the site.'),
  313. );
  314. $form['step4']['warning'] = array(
  315. '#type' => 'item',
  316. '#markup' => tripal_set_message('Any of the following options cannot be
  317. undone. Also, please be sure you have migrated all
  318. desired content types in Step 2 prior to deleting the Tripal v2
  319. contents.', TRIPAL_WARNING, array('return_html' => TRUE)),
  320. );
  321. $opt_complete_migration = array (
  322. 'cp_title' => 'Copy Title over to Tripal v3 Content',
  323. 'mv_url' => 'Migrate URL Alias to Tripal v3 Content',
  324. 'unpublish' => 'Unpublish Tripal v2 Content',
  325. 'delete' => 'Delete Tripal v2 Content',
  326. );
  327. if (count($tv2_options) == 1 && key_exists('all', $tv2_options)) {
  328. $form['step4']['complete'] = array(
  329. '#markup' => 'Migration completed. All content have been migrated.'
  330. );
  331. }
  332. else {
  333. foreach ($tv2_options AS $opt_key => $opt) {
  334. $form['step4'][$opt_key . '_title'] = array(
  335. '#markup' => "<b>$opt</b>"
  336. );
  337. $form['step4']['complete_migration--' . $opt_key] = array(
  338. '#type' => 'checkboxes',
  339. '#options' => $opt_complete_migration,
  340. );
  341. }
  342. $form['step4']['submit_btn'] = array(
  343. '#type' => 'submit',
  344. '#name' => 'complete_migration_btn',
  345. '#value' => "Submit",
  346. );
  347. }
  348. return $form;
  349. }
  350. /**
  351. * Implements hook_validate()
  352. *
  353. * @param $form
  354. * @param $form_state
  355. */
  356. function tripal_chado_migrate_form_validate($form, &$form_state) {
  357. }
  358. /**
  359. * Implements hook_submit()
  360. *
  361. * By submiting the form, a Tripal job to migrate Tripal v2 content is submitted
  362. *
  363. * @param $form
  364. * @param $form_state
  365. */
  366. function tripal_chado_migrate_form_submit($form, &$form_state) {
  367. // Store the legacy template setting in a Drupal variable
  368. if ($form_state['clicked_button']['#name'] == 'save_enabled_template_btn') {
  369. $values = $form_state['values'];
  370. $enabled_templates = array();
  371. foreach ($values AS $key => $value) {
  372. if (preg_match('/^legacy_template--/', $key)) {
  373. $enabled_templates[$key] = $value;
  374. }
  375. }
  376. variable_set('tripal_chado_enabled_legacy_templates', $enabled_templates);
  377. drupal_theme_rebuild();
  378. $_SESSION['tripal_migrate_current_tab'] = 'edit-step3';
  379. }
  380. // Complete migration
  381. else if ($form_state['clicked_button']['#name'] == 'complete_migration_btn') {
  382. $values = $form_state['values'];
  383. $config = array (
  384. 'delete' => array(),
  385. 'unpublish' => array(),
  386. 'cp_title' => array(),
  387. 'mv_url' => array()
  388. );
  389. $all = array();
  390. $all_types = array();
  391. // Gather checked checkboxes and store in the $config array
  392. foreach ($values AS $key => $value) {
  393. if (preg_match('/^complete_migration--/', $key)) {
  394. $type = str_replace('complete_migration--', '', $key);
  395. if ($type != 'all') {
  396. array_push($all_types, $type);
  397. }
  398. foreach ($value AS $key_op => $op) {
  399. if ($type == 'all') {
  400. if ($op) {
  401. array_push($all, $key_op);
  402. }
  403. }
  404. else {
  405. if ($op) {
  406. array_push($config[$key_op], $type);
  407. }
  408. }
  409. }
  410. }
  411. }
  412. foreach($all AS $a) {
  413. $config[$a] = $all_types;
  414. }
  415. // Submit jobs to complete the migration
  416. global $user;
  417. $includes = array(
  418. module_load_include('inc', 'tripal_chado', 'includes/tripal_chado.migrate'),
  419. );
  420. if (count($config['cp_title']) > 0) {
  421. $args = array($config['cp_title']);
  422. tripal_add_job("Copy Title over to Tripal v3 Content", 'tripal_chado',
  423. 'tripal_chado_copy_title_for_selected_types', $args, $user->uid, 10, $includes);
  424. }
  425. if (count($config['mv_url']) > 0) {
  426. $args = array($config['mv_url']);
  427. tripal_add_job(" Migrate URL Alias to Tripal v3 Content ", 'tripal_chado',
  428. 'tripal_chado_migrate_url_alias_for_selected_types', $args, $user->uid, 10, $includes);
  429. }
  430. if (count($config['unpublish']) > 0) {
  431. $args = array($config['unpublish']);
  432. tripal_add_job(" Unpublish Tripal v2 Content ", 'tripal_chado',
  433. 'tripal_chado_unpublish_selected_types', $args, $user->uid, 10, $includes);
  434. }
  435. if (count($config['delete']) > 0) {
  436. $args = array($config['delete']);
  437. tripal_add_job("Delete Tripal v2 Content ", 'tripal_chado',
  438. 'tripal_chado_delete_selected_types', $args, $user->uid, 10, $includes);
  439. }
  440. $_SESSION['tripal_migrate_current_tab'] = 'edit-step4';
  441. return;
  442. }
  443. // Migrate tv2 content to tv3 content
  444. else if ($form_state['clicked_button']['#name'] == 'migrate_btn') {
  445. global $user;
  446. $values = $form_state['values'];
  447. $tv2_content_type = $form_state['values']['tv2_content_type'];
  448. $tv3_content_type = array();
  449. foreach ($values AS $key => $value) {
  450. if ($tv2_content_type != 'all') {
  451. $key = urldecode($key);
  452. if (preg_match('/^tv3_content_type--(.+)--(.+)--(.+)/', $key, $matches) &&
  453. ($value == 1 || $values['tv3_migrate_all'] == 1)) {
  454. $vocabulary = $matches[1];
  455. $accession = $matches[2];
  456. $type = $matches[3];
  457. $table = str_replace('chado_', '', $tv2_content_type);
  458. $tv3_content_type [] = array(
  459. 'vocabulary' => $vocabulary,
  460. 'accession' => $accession,
  461. 'term_name' => $type,
  462. 'storage_args' => array (
  463. 'data_table' => $table,
  464. 'type_column' => db_field_exists('chado.' . $table, 'type_id') ? 'type_id' : ''
  465. )
  466. );
  467. }
  468. }
  469. }
  470. // Submit a job to migrate content
  471. global $user;
  472. $args = array(
  473. array(
  474. 'tv2_content_type' => $tv2_content_type,
  475. 'tv3_content_type' => $tv3_content_type
  476. )
  477. );
  478. $includes = array(
  479. module_load_include('inc', 'tripal_chado', 'includes/tripal_chado.migrate'),
  480. );
  481. if ($tv2_content_type == 'all' || count($tv3_content_type) != 0) {
  482. return tripal_add_job("Migrate $tv2_content_type Tripal v2 content.",
  483. 'tripal_chado', 'tripal_chado_migrate_records', $args, $user->uid, 10, $includes);
  484. }
  485. else {
  486. return drupal_set_message('Nothing to do. All data have been migrated or no data for migration.');
  487. }
  488. $_SESSION['tripal_migrate_current_tab'] = 'edit-step2';
  489. }
  490. }
  491. /**
  492. * Ajax call back that returns the entire form
  493. *
  494. * The callback is triggered by ajax elements on the form which leads to the update of
  495. * entire form according to the values set on the form
  496. *
  497. * @param $form
  498. * @param $form_state
  499. * @return $form
  500. */
  501. function tripal_chado_migrate_form_step2_ajax_callback(&$form, &$form_state) {
  502. return $form['step2']['step2_container'];
  503. }
  504. /**
  505. * Get available Tripal v2 content types
  506. *
  507. * @param boolean $all_option
  508. * Include an 'all' option in the returned array
  509. * @return string[]
  510. * Return a string array keyed by the node type
  511. */
  512. function tripal_chado_get_tripal_v2_content_type_options($all_option = FALSE, $has_template = FALSE) {
  513. // Get all available Tripal v2 chado tables
  514. $sql = "
  515. SELECT table_name
  516. FROM information_schema.tables
  517. WHERE table_schema = 'public' AND table_name LIKE 'chado_%'
  518. ";
  519. $result = db_query($sql);
  520. // Store 'chado_*' tables that has at least one node
  521. $tables = array();
  522. while ($field = $result->fetchField()) {
  523. $count = db_query("SELECT count(*) FROM $field LIMIT 1")->fetchField();
  524. if ($count != 0) {
  525. array_push($tables, $field);
  526. }
  527. }
  528. // List all available Tripal v2 content types
  529. $result = db_select('node_type', 'nt')
  530. ->fields('nt', array('type', 'name', 'description'))
  531. ->condition('type', 'chado_%', 'LIKE')
  532. ->execute();
  533. $options = array();
  534. if ($all_option) {
  535. $options['all'] = 'All';
  536. }
  537. while ($obj = $result->fetchObject()) {
  538. if ($has_template) {
  539. $mod = str_replace('chado_', 'tripal_', $obj->type);
  540. $mod_dir = drupal_get_path('module', $mod);
  541. if (file_exists($mod_dir . '/theme/templates/' . $mod . '_base.tpl.php')) {
  542. $options[$obj->type] = $obj->name;
  543. }
  544. }
  545. else {
  546. if (in_array($obj->type, $tables)) {
  547. $options[$obj->type] = $obj->name;
  548. }
  549. }
  550. }
  551. return $options;
  552. }
  553. /**
  554. * Tripal job callback to migrate Tripal v2 content into Tripal v3 content
  555. *
  556. * @param $migration
  557. * @param $job_id
  558. */
  559. function tripal_chado_migrate_records($migration, $job_id = NULL) {
  560. $tv2_content_type = $migration['tv2_content_type'];
  561. $tv3_content_type = $migration['tv3_content_type'];
  562. // If tv2_content_type is 'all', migrate all existing Tripal v2 content
  563. if ($tv2_content_type == 'all') {
  564. print "Migrating all Tripal v2 content...\n";
  565. tripal_chado_migrate_all_types();
  566. }
  567. // Otherwise, migrate only selected Tripal v2 content
  568. else {
  569. print "Migrating selected Tripal v2 content...\n";
  570. tripal_chado_migrate_selected_types($tv3_content_type);
  571. }
  572. }
  573. /**
  574. * Migrate all Tripal v2 content types
  575. *
  576. * Gather all available Tripal v2 content types and store the result in an
  577. * associated array with values of vocabulary, accession, term_name. The array
  578. * is then pass to the function tripal_chado_migrate_selected_types() that
  579. * handles the migration.
  580. */
  581. function tripal_chado_migrate_all_types() {
  582. // Get all available Tripal v2 content types
  583. $tv2_content_types = tripal_chado_get_tripal_v2_content_type_options();
  584. $types = tripal_chado_migrate_map_types($tv2_content_types);
  585. tripal_chado_migrate_selected_types($types);
  586. }
  587. /**
  588. * Map all tv2_content_type to tv3_content_type
  589. *
  590. * @param unknown $tv2_content_type
  591. * return $tv3_content_type
  592. */
  593. function tripal_chado_migrate_map_types($tv2_content_types) {
  594. $types = array();
  595. foreach($tv2_content_types AS $tv2_content_type => $value) {
  596. $table = str_replace('chado_', '', $tv2_content_type);
  597. $schema = chado_get_schema($table);
  598. $pkey = $schema['primary key'][0];
  599. $fkeys = $schema['foreign keys'];
  600. if ($table == 'organism') {
  601. array_push($types, array(
  602. 'vocabulary' => 'OBI',
  603. 'accession' => '0100026',
  604. 'term_name' => 'organism',
  605. 'storage_args' => array (
  606. 'data_table' => $table
  607. )
  608. ));
  609. }
  610. else if ($table == 'analysis') {
  611. array_push($types, array(
  612. 'vocabulary' => 'local',
  613. 'accession' => 'analysis',
  614. 'term_name' => 'analysis',
  615. 'storage_args' => array (
  616. 'data_table' => $table
  617. )
  618. ));
  619. }
  620. else if ($table == 'project') {
  621. array_push($types, array(
  622. 'vocabulary' => 'local',
  623. 'accession' => 'project',
  624. 'term_name' => 'project',
  625. 'storage_args' => array (
  626. 'data_table' => $table
  627. )
  628. ));
  629. }
  630. else if ($table == 'featuremap') {
  631. array_push($types, array(
  632. 'vocabulary' => 'data',
  633. 'accession' => '1274',
  634. 'term_name' => 'map',
  635. 'storage_args' => array (
  636. 'data_table' => $table
  637. )
  638. ));
  639. }
  640. else if ($table == 'pub') {
  641. array_push($types, array(
  642. 'vocabulary' => 'TPUB',
  643. 'accession' => '0000002',
  644. 'term_name' => 'Publication',
  645. 'storage_args' => array (
  646. 'data_table' => $table
  647. )
  648. ));
  649. }
  650. else if (key_exists('cvterm', $fkeys) && key_exists('type_id', $fkeys['cvterm']['columns'])) {
  651. // Get all Tripal v2 node types from the chad_* linking table
  652. $sql = "
  653. SELECT V.name AS type, X.accession, db.name AS vocabulary
  654. FROM {" . $table . "} T
  655. INNER JOIN public.$tv2_content_type CT ON T.$pkey = CT.$pkey
  656. INNER JOIN {cvterm} V ON V.cvterm_id = T.type_id
  657. INNER JOIN {dbxref} X ON X.dbxref_id = V.dbxref_id
  658. INNER JOIN {db} ON db.db_id = X.db_id
  659. GROUP BY V.name, X.accession, db.name
  660. ";
  661. $tv3_content_types = chado_query($sql);
  662. while($tv3_content_type = $tv3_content_types->fetchObject()) {
  663. array_push($types, array(
  664. 'vocabulary' => $tv3_content_type->vocabulary,
  665. 'accession' => $tv3_content_type->accession,
  666. 'term_name' => $tv3_content_type->type,
  667. 'storage_args' => array (
  668. 'data_table' => $table,
  669. 'type_column' => db_field_exists('chado.' . $table, 'type_id') ? 'type_id' : ''
  670. )
  671. ));
  672. }
  673. }
  674. }
  675. return $types;
  676. }
  677. /**
  678. * Migrate only selected Tripal v2 content types
  679. *
  680. * @param unknown $tv3_content_type
  681. */
  682. function tripal_chado_migrate_selected_types($tv3_content_types) {
  683. // Initialize the population of the chado_cvterm_mapping table before migration.
  684. tripal_chado_map_cvterms();
  685. foreach ($tv3_content_types AS $tv3_content_type) {
  686. // Check if the term already exists
  687. $term = tripal_load_term_entity($tv3_content_type);
  688. // If term doesn't exist, create a new bundle for this term
  689. if (!$term) {
  690. print("Creating bundle for term '" . $tv3_content_type['term_name'] . "'...\n");
  691. $success = tripal_create_bundle($tv3_content_type);
  692. $term = tripal_load_term_entity($tv3_content_type);
  693. }
  694. // Create bundle name
  695. $bundle_name = 'bio_data_' . $term->id;
  696. // Publish records for the bundle
  697. $value = array(
  698. 'sync_node' => 1,
  699. 'bundle_name' => $bundle_name
  700. );
  701. tripal_chado_publish_records($value);
  702. // Migrate organism images
  703. if ($term->name == 'organism') {
  704. tripal_chado_migrate_organism_images($bundle_name);
  705. }
  706. }
  707. }
  708. /**
  709. * Delete selected Tripal v2 content
  710. *
  711. * Delete all records from chado_* table then call the cleanup orphan nodes function
  712. *
  713. * @param unknown $tv2_content_types
  714. */
  715. function tripal_chado_delete_selected_types($tv2_content_types = array()) {
  716. foreach ($tv2_content_types AS $type) {
  717. $sql = "DELETE FROM $type";
  718. db_query($sql);
  719. chado_cleanup_orphaned_nodes(str_replace('chado_', '', $type));
  720. }
  721. }
  722. /**
  723. * Unpublish selected Tripal v2 content
  724. *
  725. * Set status = 0 (unpublished) for all nodes of selected Tripal v2 content types
  726. *
  727. * @param unknown $tv2_content_types
  728. */
  729. function tripal_chado_unpublish_selected_types($tv2_content_types = array()) {
  730. foreach ($tv2_content_types AS $type) {
  731. $sql = "UPDATE node SET status = 0 WHERE nid IN (SELECT nid FROM $type)";
  732. db_query($sql);
  733. $sql = "UPDATE node_revision SET status = 0 WHERE nid IN (SELECT nid FROM $type)";
  734. db_query($sql);
  735. }
  736. }
  737. /**
  738. * Copy titles for selected Tripal v2 content
  739. *
  740. * Copy tiltles for all nodes of selected Tripal v2 content types
  741. *
  742. * @param unknown $tv2_content_types
  743. */
  744. function tripal_chado_copy_title_for_selected_types($tv2_content_types = array()) {
  745. foreach ($tv2_content_types AS $type) {
  746. $sql = "SELECT nid, entity_id FROM chado_entity WHERE nid IN (SELECT nid FROM $type)";
  747. $result = db_query($sql);
  748. while ($entity = $result->fetchObject()) {
  749. $usql = "
  750. UPDATE tripal_entity
  751. SET title = (SELECT title FROM node WHERE nid = :nid)
  752. WHERE id = :entity_id";
  753. db_query($usql, array(
  754. ':nid' => $entity->nid,
  755. ':entity_id' => $entity->entity_id)
  756. );
  757. }
  758. }
  759. }
  760. /**
  761. * Migrate URL alias for selected Tripal v2 content
  762. *
  763. * Migrate URL alias for all nodes of selected Tripal v2 content types
  764. *
  765. * @param unknown $tv2_content_types
  766. */
  767. function tripal_chado_migrate_url_alias_for_selected_types($tv2_content_types = array()) {
  768. foreach ($tv2_content_types AS $type) {
  769. $sql = "SELECT nid, entity_id FROM chado_entity WHERE nid IN (SELECT nid FROM $type)";
  770. $result = db_query($sql);
  771. while ($entity = $result->fetchObject()) {
  772. $usql = "
  773. UPDATE url_alias
  774. SET source = 'bio_data/" . $entity->entity_id .
  775. "' WHERE source = 'node/" . $entity->nid . "'";
  776. db_query($usql);
  777. }
  778. }
  779. }
  780. /**
  781. * Migrate images for Tripal v2 organism content
  782. *
  783. * Migrate images for all chado_organism
  784. *
  785. * @param unknown $tv2_content_types
  786. */
  787. function tripal_chado_migrate_organism_images () {
  788. // Get all organism entities
  789. $results =
  790. db_select('chado_entity', 'ce')
  791. ->fields('ce', array('entity_id', 'record_id', 'nid'))
  792. ->condition('data_table', 'organism')
  793. ->execute();
  794. // Iterate through each organism entity
  795. while ($organism = $results->fetchObject()) {
  796. $nid = $organism->nid;
  797. $eid = $organism->entity_id;
  798. // check if there is a file record for the organism node
  799. $fid = db_select('file_usage', 'fu')
  800. ->field('fu', array('fid'))
  801. ->condition('module', 'tripal_organism')
  802. ->condition('type', 'organism_image')
  803. ->condition('id', $nid)
  804. ->execute()
  805. ->fetchField();
  806. // If there is an image, add it to the organism entity
  807. if ($fid) {
  808. }
  809. }
  810. }