tripal_jbrowse_mgmt_tracks.form.inc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. <?php
  2. /**
  3. * @file tripal_jbrowse_mgmt_tracks.form.inc
  4. */
  5. /**
  6. * Add a track to an instance form.
  7. *
  8. * @param array $form
  9. * The drupal form.
  10. * @param array $form_state
  11. * The form state array.
  12. * @param int $instance_id
  13. * The parent instance ID to add the new track to.
  14. *
  15. * @return array
  16. * The modified form array.
  17. */
  18. function tripal_jbrowse_mgmt_add_track_form($form, &$form_state, $instance_id) {
  19. if (empty(tripal_jbrowse_mgmt_get_instance($instance_id))) {
  20. drupal_not_found();
  21. return [];
  22. }
  23. $form['label'] = [
  24. '#type' => 'textfield',
  25. '#title' => t('Track Label'),
  26. '#description' => t('This will appear on the sidebar.'),
  27. '#required' => TRUE,
  28. ];
  29. $form['instance_id'] = [
  30. '#type' => 'hidden',
  31. '#value' => $instance_id,
  32. ];
  33. $form['data'] = [
  34. '#type' => 'fieldset',
  35. '#title' => t('Track Files'),
  36. ];
  37. $form['data']['track_type'] = [
  38. '#type' => 'select',
  39. '#description' => t('See http://gmod.org/wiki/JBrowse_Configuration_Guide#flatfile-to-json.pl for more info.'),
  40. '#required' => TRUE,
  41. '#title' => t('Track Type'),
  42. '#options' => drupal_map_assoc(tripal_jbrowse_mgmt_get_track_types()),
  43. ];
  44. $form['data']['file_type'] = [
  45. '#type' => 'select',
  46. '#title' => t('File Type'),
  47. '#options' => drupal_map_assoc(['gff', 'bed', 'gbk', 'bam', 'cram', 'vcf', 'bw']),
  48. '#description' => t('See http://gmod.org/wiki/JBrowse_Configuration_Guide#flatfile-to-json.pl for more info.'),
  49. '#required' => TRUE,
  50. ];
  51. $form['data']['file'] = [
  52. '#type' => 'file',
  53. '#title' => t('File'),
  54. ];
  55. $form['data']['file2'] = [
  56. '#type' => 'file',
  57. '#title' => t('Index File'),
  58. '#states' => [
  59. 'visible' => [
  60. ':input[name="file_type"]' => ['value' => 'vcf'],
  61. ],
  62. ],
  63. ];
  64. $form['data']['file_path'] = [
  65. '#type' => 'textfield',
  66. '#title' => t('- OR Path to File on Server -'),
  67. '#description' => t('This path will be ignored if a file is provided above. Ex: sites/default/files/file.fasta or /data/file.fasta'),
  68. '#maxlength' => 255,
  69. '#states' => [
  70. 'invisible' => [
  71. ':input[name="file_type"]' => ['value' => 'vcf'],
  72. ],
  73. ],
  74. ];
  75. $form['data']['dir_path'] = [
  76. '#type' => 'textfield',
  77. '#title' => t('- OR Path to Directory on Server -'),
  78. '#description' => t('This path will be ignored if a file is provided above. ' . 'The directory must contain both the .tbi and .gz files.'),
  79. '#maxlength' => 255,
  80. '#states' => [
  81. 'visible' => [
  82. ':input[name="file_type"]' => ['value' => 'vcf'],
  83. ],
  84. ],
  85. ];
  86. $form['data']['symbolic_link'] = [
  87. '#type' => 'checkbox',
  88. '#title' => t('Symbolic Link'),
  89. '#description' => t('Create a symbolic link rather than make a copy of the file. This only applies when a path on the server is supplied.<br>Please have Symbolic Link selected if the same file is used for new track.'),
  90. ];
  91. $form['submit'] = [
  92. '#type' => 'submit',
  93. '#value' => 'Add New Track',
  94. ];
  95. return $form;
  96. }
  97. /**
  98. * Validate the add track form.
  99. *
  100. * This function also takes care of the uploading of files.
  101. * TODO: If the file is invalid, delete it!
  102. *
  103. * @param array $form
  104. * The Drupal form.
  105. * @param array $form_state
  106. * The form state.
  107. */
  108. function tripal_jbrowse_mgmt_add_track_form_validate($form, &$form_state) {
  109. $values = $form_state['values'];
  110. $file = $_FILES['files']['tmp_name']['file'];
  111. $settings = tripal_jbrowse_mgmt_get_settings();
  112. $instance = tripal_jbrowse_mgmt_get_instance($values['instance_id']);
  113. $data = $settings['data_dir'];
  114. $file_type = $values['file_type'];
  115. $symbolic_link = $values['symbolic_link'];
  116. $path = NULL;
  117. $base_path = $data . '/' . tripal_jbrowse_mgmt_make_slug($instance->title);
  118. if(isset($instance->analysis_id)){
  119. $base_path = $base_path . '_' . $instance->analysis_id;
  120. }
  121. $base_path = $base_path . '/data';
  122. if ($file_type === 'vcf') {
  123. $path = $base_path . '/vcf';
  124. }
  125. if (($file_type === 'bam') OR ($file_type === 'cram')){
  126. $path = $base_path . '/bam';
  127. }
  128. elseif ($file_type === 'bw') {
  129. $path = $base_path . '/wig';
  130. }
  131. else {
  132. $path = $base_path;
  133. }
  134. switch ($file_type) {
  135. case 'vcf':
  136. $index = $_FILES['files']['tmp_name']['file2'];
  137. $local_dir = isset($values['dir_path']) ? $values['dir_path'] : NULL;
  138. if (empty($file) && empty($index) && empty($local_dir)) {
  139. form_set_error('file',
  140. 'Please provide a local directory path or upload files.');
  141. }
  142. elseif (empty($file) && empty($index) && !empty($local_dir)) {
  143. if (!file_exists($local_dir)) {
  144. form_set_error('file_path', 'The directory provided does not exist.');
  145. }
  146. else {
  147. if (!is_dir($local_dir)) {
  148. form_set_error('file_path',
  149. 'The file provided is not a directory.');
  150. }
  151. else {
  152. $file_gz = glob($local_dir . '/*.vcf.gz');
  153. $file_index = glob($local_dir . '/*.vcf.gz.[cti][sbd][ix]');
  154. if (count($file_gz) != 1 || count($file_index) != 1) {
  155. form_set_error('file_path',
  156. 'Please provide a directory with exactly one gz and one index file.');
  157. }
  158. else {
  159. try {
  160. if (!tripal_jbrowse_mgmt_copy_file($file_gz[0], $path, $symbolic_link)) {
  161. form_set_error('file_path', 'Failed to copy file' . $file_gz[0] . ' to ' . $path.'. If this track is expected to create by existed file, please have Symbolic Link selected.');
  162. }
  163. else {
  164. if (!tripal_jbrowse_mgmt_copy_file($file_index[0], $path, $symbolic_link)) {
  165. form_set_error('file_path', 'Failed to copy file' . $file_gz[0] . ' to ' . $path.'. If this track is expected to create by existed file, please have Symbolic Link selected.');
  166. }
  167. }
  168. } catch (Exception $exception) {
  169. form_set_error($exception->getMessage());
  170. }
  171. }
  172. }
  173. }
  174. }
  175. elseif (empty($file) && !empty($index)) {
  176. form_set_error('file', 'Please upload both a gz and an index file.');
  177. }
  178. elseif (!empty($file) && empty($index)) {
  179. form_set_error('file2', 'Please upload both a gz and an index file.');
  180. }
  181. else {
  182. $gz_uploaded = tripal_jbrowse_mgmt_upload_file('file');
  183. if (!$gz_uploaded) {
  184. form_set_error('file', 'Unable to upload file');
  185. }
  186. else {
  187. $gz_uploaded = tripal_jbrowse_mgmt_move_file($gz_uploaded, $path);
  188. if (!isset($gz_uploaded)) {
  189. form_set_error('file', 'Failed to move gz file to ' . $path . '.');
  190. }
  191. else {
  192. $form_state['values']['uploaded_gz'] = $gz_uploaded;
  193. }
  194. }
  195. $index_uploaded = tripal_jbrowse_mgmt_upload_file('file2');
  196. if (!$index_uploaded) {
  197. form_set_error('file2', 'Unable to upload file');
  198. }
  199. else {
  200. $index_uploaded = tripal_jbrowse_mgmt_move_file($index_uploaded, $path);
  201. if (!isset($index_uploaded)) {
  202. form_set_error('file2', 'Failed to move index file to ' . $path . '.');
  203. }
  204. else {
  205. $form_state['values']['uploaded_tbi'] = $index_uploaded;
  206. }
  207. }
  208. }
  209. break;
  210. default:
  211. $local_file = isset($values['file_path']) ? $values['file_path'] : NULL;
  212. if (empty($file) && empty($local_file)) {
  213. form_set_error('file',
  214. 'Please provide a local file path or upload a new file.');
  215. }
  216. elseif (empty($file) && !empty($local_file)) {
  217. if (!file_exists($local_file)) {
  218. form_set_error('file_path', 'The file path provided does not exist.');
  219. }
  220. else {
  221. try {
  222. if (!tripal_jbrowse_mgmt_copy_file($local_file, $path, $symbolic_link)) {
  223. form_set_error('file_path', 'Failed to copy file ' . $local_file . ' to ' . $path. '. If this track is expected to create by existed file, please have Symbolic Link selected.');
  224. }
  225. } catch (Exception $exception) {
  226. form_set_error('file_path', 'Failed to copy file ' . $local_file . ' to ' . $path.'. If this track is expected to create by existed file, please have Symbolic Link selected.');
  227. }
  228. }
  229. }
  230. else {
  231. $uploaded = tripal_jbrowse_mgmt_upload_file('file');
  232. if (!$uploaded) {
  233. form_set_error('file', 'Unable to upload file');
  234. }
  235. else {
  236. $uploaded = tripal_jbrowse_mgmt_move_file($uploaded, $path);
  237. if (!isset($uploaded)) {
  238. form_set_error('file', 'Failed to move file to ' . $path);
  239. }
  240. else {
  241. $form_state['values']['uploaded_file'] = $uploaded;
  242. }
  243. }
  244. }
  245. break;
  246. }
  247. }
  248. /**
  249. * Handle form submission for adding a track.
  250. *
  251. * @param array $form
  252. * @param array $form_state
  253. *
  254. * @throws \Exception
  255. */
  256. function tripal_jbrowse_mgmt_add_track_form_submit($form, &$form_state) {
  257. global $user;
  258. $values = $form_state['values'];
  259. $file = isset($values['file_path']) ? $values['file_path'] : NULL;
  260. if (!empty($values['dir_path'])) {
  261. $file = $values['dir_path'];
  262. }
  263. if (!empty($values['uploaded_gz'])) {
  264. $file = $values['uploaded_gz'];
  265. }
  266. if (!empty($values['uploaded_file'])) {
  267. $file = $values['uploaded_file'];
  268. }
  269. $instance = tripal_jbrowse_mgmt_get_instance($values['instance_id']);
  270. $track_id = tripal_jbrowse_mgmt_create_track($instance, [
  271. 'label' => $values['label'],
  272. 'track_type' => $values['track_type'],
  273. 'file_type' => $values['file_type'],
  274. 'file' => $file,
  275. 'created_at' => time(),
  276. ]);
  277. tripal_add_job('Add JBrowse track to ' . $instance->title, 'tripal_jbrowse_mgmt',
  278. 'tripal_jbrowse_mgmt_add_track_to_instance', [$track_id], $user->uid);
  279. drupal_goto('admin/tripal/extension/tripal_jbrowse/management/instances/' . $instance->id);
  280. }
  281. /**
  282. * Delete a track form.
  283. *
  284. * @param array $form
  285. * @param array $form_state
  286. * @param int $track_id
  287. *
  288. * @return array
  289. */
  290. function tripal_jbrowse_mgmt_delete_track_form($form, &$form_state, $track_id) {
  291. $track = tripal_jbrowse_mgmt_get_track($track_id);
  292. if (!$track->id) {
  293. $form['error'] = [
  294. '#type' => 'item',
  295. '#markup' => '<p style="color: red">Unable to find track.</p>',
  296. ];
  297. return $form;
  298. }
  299. $form['description'] = [
  300. '#type' => 'item',
  301. '#markup' => 'Are you sure you want to delete the ' . $track->label . ' track?',
  302. ];
  303. $form['track_id'] = [
  304. '#type' => 'hidden',
  305. '#value' => $track_id,
  306. ];
  307. $form['submit'] = [
  308. '#type' => 'submit',
  309. '#value' => 'Delete Track',
  310. ];
  311. $form['cancel'] = [
  312. '#type' => 'markup',
  313. '#markup' => l('Cancel',
  314. 'admin/tripal/extension/tripal_jbrowse/management/instances/' . $track->instance_id),
  315. ];
  316. return $form;
  317. }
  318. /**
  319. * @param $form
  320. * @param $form_state
  321. *
  322. * @throws \Exception
  323. */
  324. function tripal_jbrowse_mgmt_delete_track_form_submit($form, &$form_state) {
  325. global $user;
  326. $values = $form_state['values'];
  327. $track = tripal_jbrowse_mgmt_get_track($values['track_id']);
  328. tripal_add_job('Delete JBrowse track', 'tripal_jbrowse_mgmt',
  329. 'tripal_jbrowse_mgmt_delete_track_from_instance', [$values['track_id']],
  330. $user->uid);
  331. tripal_jbrowse_mgmt_update_track($track, ['is_deleted' => 1]);
  332. drupal_goto('admin/tripal/extension/tripal_jbrowse/management/instances/' . $track->instance_id);
  333. }
  334. /**
  335. * Track json editor advance form.
  336. * allow user to make all configurations of a track
  337. *
  338. * @param array $form
  339. * @param array $form_state
  340. * @param int $track_id
  341. *
  342. * @return array
  343. * @throws \Exception
  344. */
  345. function tripal_jbrowse_mgmt_json_editor_advance_form($form, &$form_state, $track_id) {
  346. $track = tripal_jbrowse_mgmt_get_track($track_id);
  347. if (empty($track)) {
  348. drupal_not_found();
  349. return $form;
  350. }
  351. drupal_set_title('Edit Track Json: ' . $track->label);
  352. $breadcrumb = array();
  353. $breadcrumb[] = l('Home', '');
  354. $breadcrumb[] = l('Administration', 'admin');
  355. $breadcrumb[] = l('Tripal', 'admin/tripal');
  356. $breadcrumb[] = l('Extensions', 'admin/tripal/extension');
  357. $breadcrumb[] = l('Tripal JBrowse', 'admin/tripal/extension/tripal_jbrowse/management');
  358. $breadcrumb[] = l('Instance', 'admin/tripal/extension/tripal_jbrowse/management/instances/'.$track->instance_id);
  359. drupal_set_breadcrumb($breadcrumb);
  360. if (!$track->id) {
  361. $form['error'] = [
  362. '#type' => 'item',
  363. '#markup' => '<p style="color: red">Unable to find track.</p>',
  364. ];
  365. return $form;
  366. }
  367. $instance = tripal_jbrowse_mgmt_get_instance($track->instance_id);
  368. $json = tripal_jbrowse_mgmt_get_json($instance);
  369. $form_state['track_json'] = $json;
  370. $key = tripal_jbrowse_mgmt_make_slug($track->label);
  371. $track_json = NULL;
  372. $track_index = NULL;
  373. foreach ($json['tracks'] as $index => $jtrack) {
  374. if ($jtrack['label'] === $key) {
  375. $track_json = $jtrack;
  376. $track_index = $index;
  377. break;
  378. }
  379. }
  380. if (!$track_json) {
  381. $form['error'] = [
  382. '#type' => 'item',
  383. '#markup' => '<p style="color: red">Unable to find track in json!</p>',
  384. ];
  385. return $form;
  386. }
  387. $form['track_index'] = [
  388. '#type' => 'hidden',
  389. '#value' => $track_index,
  390. ];
  391. $form['track_id'] = [
  392. '#type' => 'hidden',
  393. '#value' => $track->id,
  394. ];
  395. $instr_detail = '<p><strong>Only use this functionality if the configuration option you want is not included in the "Track Manage" form.</strong>. For more information on the JBrowse track configuration see the '.l('JBrowse Documentation', 'http://jbrowse.org/docs/canvas_features.html').'.</p>
  396. <div class="messages warning">Please be extra cautious while editing track configuration, since it will make changes in file trackList.json directly. Also, do not change the "label" since it will disconnect this track from the JBrowse Management form.</div>';
  397. $form['Instruction']=[
  398. '#type' => 'markup',
  399. '#markup' => $instr_detail,
  400. ];
  401. $form['track_all_config'] = [
  402. '#type' => 'textarea',
  403. '#title' => t('Track configuration in json'),
  404. '#description' => t('The track info from trackList.json. Only '),
  405. '#default_value' => json_encode($track_json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES),
  406. '#rows' => '10',
  407. '#required' => TRUE,
  408. ];
  409. $form['submit'] = [
  410. '#type' => 'submit',
  411. '#value' => 'Save Track Configuration',
  412. ];
  413. return $form;
  414. }
  415. /**
  416. * Validate the form.
  417. *
  418. * @param $form
  419. * @param $form_state
  420. */
  421. function tripal_jbrowse_mgmt_json_editor_advance_form_validate($form, &$form_state) {
  422. $values = $form_state['values'];
  423. $track_all_config = $values['track_all_config'] ?? NULL;
  424. $track_key = $values['track_index'];
  425. if ($track_all_config && !empty($track_all_config)) {
  426. if (!json_decode($track_all_config)) {
  427. form_set_error(
  428. 'track_all_config',
  429. 'Invalid JSON. Please verify that the menu template contains only valid JSON.'
  430. );
  431. }
  432. }
  433. $json_before_edit = $form_state['track_json']['tracks'][$track_key];
  434. $json_after_edit = json_decode($form_state['values']['track_all_config'], TRUE);
  435. if (($json_before_edit['key'] != $json_after_edit['key']) OR ($json_before_edit['label'] != $json_after_edit['label'])){
  436. form_set_error('track_all_config', 'Key or Label changed. Please don\'t change Key or Label here. The functionality is provided in "Track Manage" form.');
  437. }
  438. }
  439. /**
  440. * @param array $form
  441. * @param array $form_state
  442. *
  443. * @throws \Exception
  444. */
  445. function tripal_jbrowse_mgmt_json_editor_advance_form_submit($form, &$form_state) {
  446. $values = $form_state['values'];
  447. $track_index = $values['track_index'];
  448. $track_all_config = $values['track_all_config'] ?? NULL;
  449. $track = tripal_jbrowse_mgmt_get_track($values['track_id']);
  450. $json = $form_state['track_json'];
  451. $json['tracks'][$track_index] = json_decode($track_all_config, TRUE);
  452. tripal_jbrowse_mgmt_update_track($track, ['label' => $json['tracks'][$track_index]['key']]);
  453. if (tripal_jbrowse_mgmt_save_json($track->instance, $json) === FALSE) {
  454. drupal_set_message(
  455. 'Unable to save JSON file. Please make sure it\'s editable.'
  456. );
  457. return;
  458. }
  459. drupal_set_message('Track updated successfully');
  460. }