tripal_feature.admin.inc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. <?php
  2. /*************************************************************************
  3. * Purpose: Provide Guidance to new Tripal Admin
  4. *
  5. * @return HTML Formatted text
  6. */
  7. function tripal_feature_module_description_page() {
  8. $text .= '<h3>Tripal Feature Administrative Tools Quick Links:</h3>';
  9. $text .= "<ul>";
  10. $text .= "<li><a href=\"".url("admin/tripal/tripal_feature/configuration") . "\">Feature Configuration</a></li>";
  11. $text .= "<li><a href=\"".url("admin/tripal/tripal_feature/fasta_loader"). "\">Import a multi-FASTA file</a></li>";
  12. $text .= "<li><a href=\"".url("admin/tripal/tripal_feature/gff3_load"). "\">Import a GFF3 file</a></li>";
  13. $text .= "<li><a href=\"".url("admin/tripal/tripal_feature/aggregate"). "\">Feature Relationship Aggegators</a></li>";
  14. $text .= "</ul>";
  15. $text .= '<h3>Module Description:</h3>';
  16. $text .= '<p>TODO: Basic Description of this module including mention/link to the chado module</p>';
  17. $text .= '<h3>Post Installation Instructions:</h3>';
  18. $text .= '<p>TODO: Describe any post installation intructions here. You shouldalways include setting user permissions.</p>';
  19. $text .= '<h3>Features of this Module:</h3>';
  20. $text .= '<p>TODO: Discuss the Features of this module including links. Some features to consider are creating content, details pages/node content, editing/deleteing, basic listings and vies integration. See admin/tripal/tripal_stock for an example.</p>';
  21. return $text;
  22. }
  23. /************************************************************************
  24. *
  25. */
  26. function tripal_feature_admin () {
  27. // before proceeding check to see if we have any
  28. // currently processing jobs. If so, we don't want
  29. // to give the opportunity to sync libraries
  30. $active_jobs = FALSE;
  31. if(tripal_get_module_active_jobs('tripal_feature')){
  32. $active_jobs = TRUE;
  33. }
  34. if(!$active_jobs){
  35. $form['chado_feature_accession_prefix'] = array (
  36. '#title' => t('Internal ID Prefix'),
  37. '#type' => t('textfield'),
  38. '#description' => t("Internal ID numbers for features consist of the ".
  39. "chado feature_id and a site specific prefix. Set the prefix that ".
  40. "will be incorporated in front of each feature_id to form a unique ".
  41. "accession number for this site."),
  42. '#required' => TRUE,
  43. '#default_value' => variable_get('chado_feature_accession_prefix','ID'),
  44. );
  45. $form['chado_feature_types'] = array(
  46. '#title' => t('Feature Types'),
  47. '#type' => 'textarea',
  48. '#description' => t('Enter the names of the sequence types that the ".
  49. "site will support with independent pages. Pages for these data ".
  50. "types will be built automatically for features that exist in the ".
  51. "chado database. The names listed here should be spearated by ".
  52. "spaces or entered separately on new lines. The names must match ".
  53. "exactly (spelling and case) with terms in the sequence ontology'),
  54. '#required' => TRUE,
  55. '#default_value' => variable_get('chado_feature_types','EST contig'),
  56. );
  57. $form['browser'] = array(
  58. '#type' => 'fieldset',
  59. '#title' => t('Feature Browser')
  60. );
  61. $allowedoptions1 = array (
  62. 'show_feature_browser' => "Show the feature browser on the organism page. The browser loads when page loads. This may be slow for large sites.",
  63. 'hide_feature_browser' => "Hide the feature browser on the organism page. Disables the feature browser completely.",
  64. );
  65. // $allowedoptions ['allow_feature_browser'] = "Allow loading of the feature browsing through AJAX. For large sites the initial page load will be quick with the feature browser loading afterwards.";
  66. $form['browser']['browse_features'] = array(
  67. '#title' => 'Feature Browser on Organism Page',
  68. '#description' => 'A feature browser can be added to an organism page to allow users to quickly '.
  69. 'access a feature. This will most likely not be the ideal mechanism for accessing feature '.
  70. 'information, especially for large sites, but it will alow users exploring the site (such '.
  71. 'as students) to better understand the data types available on the site.',
  72. '#type' => 'radios',
  73. '#options' => $allowedoptions1,
  74. '#default_value'=>variable_get('tripal_feature_browse_setting', 'show_feature_browser'),
  75. );
  76. $form['browser']['set_browse_button'] = array(
  77. '#type' => 'submit',
  78. '#value' => t('Set Browser'),
  79. '#weight' => 2,
  80. );
  81. $form['summary'] = array(
  82. '#type' => 'fieldset',
  83. '#title' => t('Feature Summary')
  84. );
  85. $allowedoptions2 ['show_feature_summary'] = "Show the feature summary on the organism page. The summary loads when page loads.";
  86. $allowedoptions2 ['hide_feature_summary'] = "Hide the feature summary on the organism page. Disables the feature summary.";
  87. $form['summary']['feature_summary'] = array(
  88. '#title' => 'Feature Summary on Organism Page',
  89. '#description' => 'A feature summary can be added to an organism page to allow users to see the '.
  90. 'type and quantity of features available for the organism.',
  91. '#type' => 'radios',
  92. '#options' => $allowedoptions2,
  93. '#default_value'=>variable_get('tripal_feature_summary_setting', 'show_feature_summary'),
  94. );
  95. $form['summary']['set_summary_button'] = array(
  96. '#type' => 'submit',
  97. '#value' => t('Set Summary'),
  98. '#weight' => 2,
  99. );
  100. get_tripal_feature_admin_form_sync_set($form);
  101. get_tripal_feature_admin_form_taxonomy_set($form);
  102. get_tripal_feature_admin_form_reindex_set($form);
  103. get_tripal_feature_admin_form_cleanup_set($form);
  104. } else {
  105. $form['notice'] = array(
  106. '#type' => 'fieldset',
  107. '#title' => t('Feature Management Temporarily Unavailable')
  108. );
  109. $form['notice']['message'] = array(
  110. '#value' => t('Currently, feature management jobs are waiting or ".
  111. "are running. Managemment features have been hidden until these ".
  112. "jobs complete. Please check back later once these jobs have ".
  113. "finished. You can view the status of pending jobs in the Tripal ".
  114. "jobs page.'),
  115. );
  116. }
  117. return system_settings_form($form);
  118. }
  119. /************************************************************************
  120. *
  121. */
  122. function tripal_feature_admin_validate($form, &$form_state) {
  123. global $user; // we need access to the user info
  124. $job_args = array();
  125. // if the user wants to sync up the chado features then
  126. // add the job to the management queue
  127. if ($form_state['values']['op'] == t('Sync all Features')) {
  128. tripal_add_job('Sync all features','tripal_feature',
  129. 'tripal_feature_sync_features',$job_args,$user->uid);
  130. }
  131. if ($form_state['values']['op'] == t('Set/Reset Taxonomy for all feature nodes')) {
  132. tripal_add_job('Set all feature taxonomy','tripal_feature',
  133. 'tripal_features_set_taxonomy',$job_args,$user->uid);
  134. }
  135. if ($form_state['values']['op'] == t('Reindex all feature nodes')) {
  136. tripal_add_job('Reindex all features','tripal_feature',
  137. 'tripal_features_reindex',$job_args,$user->uid);
  138. }
  139. if ($form_state['values']['op'] == t('Clean up orphaned features')) {
  140. tripal_add_job('Cleanup orphaned features','tripal_feature',
  141. 'tripal_features_cleanup',$job_args,$user->uid);
  142. }
  143. if ($form_state['values']['op'] == t('Set Browser')) {
  144. variable_set('tripal_feature_browse_setting',$form_state['values']['browse_features']);
  145. }
  146. if ($form_state['values']['op'] == t('Set Summary')) {
  147. variable_set('tripal_feature_summary_setting',$form_state['values']['feature_summary']);
  148. }
  149. }
  150. /************************************************************************
  151. *
  152. */
  153. function get_tripal_feature_admin_form_cleanup_set(&$form) {
  154. $form['cleanup'] = array(
  155. '#type' => 'fieldset',
  156. '#title' => t('Clean Up')
  157. );
  158. $form['cleanup']['description'] = array(
  159. '#type' => 'item',
  160. '#value' => t("With Drupal and chado residing in different databases ".
  161. "it is possible that nodes in Drupal and features in Chado become ".
  162. "\"orphaned\". This can occur if a feature node in Drupal is ".
  163. "deleted but the corresponding chado feature is not and/or vice ".
  164. "versa. The Cleanup function will also remove nodes for features ".
  165. "that are not in the list of allowed feature types as specified ".
  166. "above. This is helpful when a feature type needs to be ".
  167. "removed but was previously present as Drupal nodes. ".
  168. "Click the button below to resolve these discrepancies."),
  169. '#weight' => 1,
  170. );
  171. $form['cleanup']['button'] = array(
  172. '#type' => 'submit',
  173. '#value' => t('Clean up orphaned features'),
  174. '#weight' => 2,
  175. );
  176. }
  177. /************************************************************************
  178. *
  179. */
  180. function get_tripal_feature_admin_form_reindex_set(&$form) {
  181. $form['reindex'] = array(
  182. '#type' => 'fieldset',
  183. '#title' => t('Reindex')
  184. );
  185. $form['reindex']['description'] = array(
  186. '#type' => 'item',
  187. '#value' => t("Reindexing of nodes is important when content for nodes ".
  188. "is updated external to drupal, such as external uploads to chado. ".
  189. "Features need to be reindexed to ensure that updates to features ".
  190. "are searchable. Depending on the number of features this may take ".
  191. "quite a while. Click the button below to begin reindexing of ".
  192. "features."),
  193. '#weight' => 1,
  194. );
  195. $form['reindex']['button'] = array(
  196. '#type' => 'submit',
  197. '#value' => t('Reindex all feature nodes'),
  198. '#weight' => 2,
  199. );
  200. }
  201. /************************************************************************
  202. *
  203. */
  204. function get_tripal_feature_admin_form_taxonomy_set (&$form) {
  205. $form['taxonomy'] = array(
  206. '#type' => 'fieldset',
  207. '#title' => t('Set Taxonomy')
  208. );
  209. $form['taxonomy']['description'] = array(
  210. '#type' => 'item',
  211. '#value' => t("Drupal allows for assignment of \"taxonomy\" or ".
  212. "catagorical terms to nodes. These terms allow for advanced ".
  213. "filtering during searching."),
  214. '#weight' => 1,
  215. );
  216. $tax_options = array (
  217. 'organism' => t('Organism name'),
  218. 'feature_type' => t('Feature Type (e.g. EST, mRNA, etc.)'),
  219. 'analysis' => t('Analysis Name'),
  220. 'library' => t('Library Name'),
  221. );
  222. $form['taxonomy']['tax_classes'] = array (
  223. '#title' => t('Available Taxonomic Classes'),
  224. '#type' => t('checkboxes'),
  225. '#description' => t("Please select the class of terms to assign to ".
  226. "chado features"),
  227. '#required' => FALSE,
  228. '#prefix' => '<div id="taxclass_boxes">',
  229. '#suffix' => '</div>',
  230. '#options' => $tax_options,
  231. '#weight' => 2,
  232. '#default_value' => variable_get('tax_classes',''),
  233. );
  234. $form['taxonomy']['button'] = array(
  235. '#type' => 'submit',
  236. '#value' => t('Set/Reset Taxonomy for all feature nodes'),
  237. '#weight' => 3,
  238. );
  239. }
  240. /************************************************************************
  241. *
  242. */
  243. function get_tripal_feature_admin_form_sync_set (&$form) {
  244. // get the list of organisms which will be synced.
  245. $feature_sql = "SELECT * FROM {Feature} WHERE uniquename = '%s' and organism_id = %d";
  246. $previous_db = tripal_db_set_active('chado');
  247. $feature = db_fetch_object(db_query($feature_sql,$node->title,$node->organism_id));
  248. tripal_db_set_active($previous_db);
  249. // define the fieldsets
  250. $form['sync'] = array(
  251. '#type' => 'fieldset',
  252. '#title' => t('Sync Features')
  253. );
  254. $form['sync']['description'] = array(
  255. '#type' => 'item',
  256. '#value' => t("Click the 'Sync all Features' button to create Drupal ".
  257. "content for features in chado. Only features of the types listed ".
  258. "above in the Feature Types box will be synced. Depending on the ".
  259. "number of features in the chado database this may take a long ".
  260. "time to complete. "),
  261. '#weight' => 1,
  262. );
  263. $orgs = tripal_organism_get_synced();
  264. $org_list = '';
  265. foreach($orgs as $org){
  266. $org_list .= "$org->genus $org->species, ";
  267. }
  268. $form['sync']['description2'] = array(
  269. '#type' => 'item',
  270. '#value' => "Only features for the following organisms will be synced: ".
  271. " $org_list",
  272. '#weight' => 1,
  273. );
  274. $form['sync']['button'] = array(
  275. '#type' => 'submit',
  276. '#value' => t('Sync all Features'),
  277. '#weight' => 3,
  278. );
  279. }
  280. /*************************************************************************
  281. *
  282. */
  283. function tripal_feature_aggregator_page(){
  284. $add_url = url("admin/tripal/tripal_feature/aggregate/new");
  285. $output = "<a href=\"$add_url\">Add a new aggregator</a>";
  286. $output .= drupal_get_form('tripal_feature_aggregator_select_form');
  287. $output .= '<div id="db-edit-div">Please select an aggregator base type to view or edit</div>';
  288. return $output;
  289. }
  290. /*************************************************************************
  291. *
  292. */
  293. function tripal_feature_aggregator_select_form(){
  294. // get a list of base terms from chado for user to choose
  295. $sql = "SELECT DISTINCT type_id FROM {tripal_feature_relagg} ORDER BY type_id ";
  296. $results = db_query ($sql);
  297. $sql = "SELECT * FROM {cvterm} WHERE cvterm_id = %d";
  298. $previous_db = tripal_db_set_active('chado');
  299. $types = array();
  300. $types[] = '';
  301. while($base = db_fetch_object($results)){
  302. $term = db_fetch_object(db_query($sql,$base->type_id));
  303. $types[$base->type_id] = $term->name;
  304. }
  305. tripal_db_set_active($previous_db);
  306. $form['type_id'] = array(
  307. '#title' => t('Aggregator Base Type'),
  308. '#type' => 'select',
  309. '#options' => $types,
  310. '#ahah' => array(
  311. 'path' => 'admin/tripal/tripal_feature/aggregate/edit/js',
  312. 'wrapper' => 'db-edit-div',
  313. 'effect' => 'fade',
  314. 'event' => 'change',
  315. 'method' => 'replace',
  316. ),
  317. );
  318. return $form;
  319. }
  320. /*************************************************************************
  321. *
  322. */
  323. function tripal_feature_aggregator_form(&$form_state = NULL,$type_id = NULL){
  324. // get this requested database
  325. if($type_id){
  326. $sql = "SELECT * FROM {tripal_feature_relagg} WHERE type_id = %d ";
  327. $tsql = "SELECT * FROM {cvterm} WHERE cvterm_id = %d ";
  328. // get the default list of terms
  329. $results = db_query($sql,$type_id);
  330. while($type = db_fetch_object($results)){
  331. $previous_db = tripal_db_set_active('chado');
  332. $term = db_fetch_object(db_query($tsql,$type->rel_type_id));
  333. tripal_db_set_active($previous_db);
  334. $default_others .= $term->name . " ";
  335. }
  336. $default_base = $base->name;
  337. $action = 'Update';
  338. $form['type_id'] = array(
  339. '#type' => 'hidden',
  340. '#value' => $type_id
  341. );
  342. } else {
  343. $action = 'Add';
  344. $form['base']= array(
  345. '#type' => 'textfield',
  346. '#title' => t('Base Feature type'),
  347. '#description' => t('Please enter the Sequence Ontology (SO) term for the base feature type for this aggregator.'),
  348. '#default_value' => $default_base,
  349. '#required' => TRUE,
  350. '#weight' => 1
  351. );
  352. }
  353. $form['others']= array(
  354. '#type' => 'textarea',
  355. '#title' => t('Aggregate these types if a relationship exists'),
  356. '#description' => t('Please enter the Sequence Ontology (SO) terms that should be aggregated with the base feature type listed above. Separate each by a space or newline'),
  357. '#default_value' => $default_others,
  358. '#required' => TRUE,
  359. '#weight' => 2
  360. );
  361. if(strcmp($action,'Update')==0){
  362. $form['update'] = array (
  363. '#type' => 'submit',
  364. '#value' => t('Update'),
  365. '#weight' => 5,
  366. '#executes_submit_callback' => TRUE,
  367. );
  368. $form['delete'] = array (
  369. '#type' => 'submit',
  370. '#value' => t('Delete'),
  371. '#weight' => 6,
  372. '#executes_submit_callback' => TRUE,
  373. );
  374. } else {
  375. $form['add'] = array (
  376. '#type' => 'submit',
  377. '#value' => t('Add'),
  378. '#weight' => 5,
  379. '#executes_submit_callback' => TRUE,
  380. );
  381. }
  382. $form['#redirect'] = 'admin/tripal/tripal_feature/aggregate';
  383. return $form;
  384. }
  385. /************************************************************************
  386. *
  387. */
  388. function tripal_feature_aggregator_form_validate($form, &$form_state){
  389. $type_id = $form_state['values']['type_id'];
  390. $base = $form_state['values']['base'];
  391. $others = $form_state['values']['others'];
  392. $op = $form_state['values']['op'];
  393. // split apart the feature types to be aggregated
  394. $types = preg_split('/\s+/',$others);
  395. // the SQL for finding the term
  396. $tsql = "
  397. SELECT *
  398. FROM {cvterm} CVT
  399. INNER JOIN {cv} CV on CVT.cv_id = CV.cv_id
  400. WHERE CVT.name = '%s' and CV.name = 'sequence'";
  401. // make sure the base type exists
  402. if($base){
  403. $previous_db = tripal_db_set_active('chado');
  404. $term = db_fetch_object(db_query($tsql,$base));
  405. tripal_db_set_active($previous_db);
  406. if(!$term){
  407. form_set_error('base',t('The specified base type is not a valid SO term'));
  408. }
  409. // make sure this type doesn't already in the table
  410. $sql = "SELECT * FROM {tripal_feature_relagg} WHERE type_id = %d ";
  411. $agg = db_fetch_object(db_query($sql,$term->cvterm_id));
  412. if($agg){
  413. form_set_error('base',t('The specified base type is already used as a base type for another aggregator and cannot be readded.'));
  414. }
  415. }
  416. // iterate through each type to be aggregated and make sure they are valid
  417. foreach($types as $type){
  418. $previous_db = tripal_db_set_active('chado');
  419. $term = db_fetch_object(db_query($tsql,$type));
  420. tripal_db_set_active($previous_db);
  421. if(!$term){
  422. form_set_error('others',t('The specified type ') . $type . t(' is not a valid SO term'));
  423. }
  424. }
  425. }
  426. /************************************************************************
  427. *
  428. */
  429. function tripal_feature_aggregator_form_submit($form, &$form_state){
  430. $type_id = $form_state['values']['type_id'];
  431. $base = $form_state['values']['base'];
  432. $others = $form_state['values']['others'];
  433. $op = $form_state['values']['op'];
  434. // split apart the feature types to be aggregated
  435. $types = preg_split('/\s+/',$others);
  436. // the SQL for finding the term
  437. $tsql = "
  438. SELECT *
  439. FROM {cvterm} CVT
  440. INNER JOIN {cv} CV on CVT.cv_id = CV.cv_id
  441. WHERE CVT.name = '%s' and CV.name = 'sequence'";
  442. // the SQL for deleting an aggregator
  443. $dsql = "
  444. DELETE FROM {tripal_feature_relagg}
  445. WHERE type_id = %d
  446. ";
  447. // if this is an insert then we have a base type name. We
  448. // need to get the corresponding term id
  449. if($base){
  450. $previous_db = tripal_db_set_active('chado');
  451. $term = db_fetch_object(db_query($tsql,$base));
  452. tripal_db_set_active($previous_db);
  453. $type_id = $term->cvterm_id;
  454. }
  455. if(strcmp($op,'Delete')==0){
  456. $result = db_query($dsql,$type_id);
  457. if($result){
  458. drupal_set_message("Aggregator deleted");
  459. } else {
  460. drupal_set_message("Failed to delete mailing list.");
  461. }
  462. }
  463. else {
  464. // for an update, first remove all the current aggregator settings
  465. // and we'll add them again
  466. $result = db_query($dsql,$type_id);
  467. // the SQL for inserting the aggregated types
  468. $isql = "
  469. INSERT INTO {tripal_feature_relagg}
  470. (type_id,rel_type_id)
  471. VALUES
  472. (%d,%d)
  473. ";
  474. // iterate through each type to be aggregated and add an entry in the table
  475. foreach($types as $type){
  476. $previous_db = tripal_db_set_active('chado');
  477. $term = db_fetch_object(db_query($tsql,$type));
  478. tripal_db_set_active($previous_db);
  479. $result = db_query($isql,$type_id,$term->cvterm_id);
  480. }
  481. drupal_set_message("Aggregator added");
  482. }
  483. return '';
  484. }
  485. /*************************************************************************
  486. *
  487. */
  488. function tripal_feature_aggregator_ajax_edit (){
  489. // get the database id, build the form and then return the JSON object
  490. $type_id = $_POST['type_id'];
  491. $form = drupal_get_form('tripal_feature_aggregator_form',$type_id);
  492. drupal_json(array('status' => TRUE, 'data' => $form));
  493. }