tripal_feature.admin.inc 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <?php
  2. /**
  3. * @file
  4. * Administration of features
  5. */
  6. /**
  7. * Launchpad for feature administration.
  8. *
  9. * @ingroup tripal_feature
  10. */
  11. function tripal_feature_admin_feature_view() {
  12. $output = '';
  13. // set the breadcrumb
  14. $breadcrumb = array();
  15. $breadcrumb[] = l('Home', '<front>');
  16. $breadcrumb[] = l('Administration', 'admin');
  17. $breadcrumb[] = l('Tripal', 'admin/tripal');
  18. $breadcrumb[] = l('Chado', 'admin/tripal/chado');
  19. $breadcrumb[] = l('Features', 'admin/tripal/chado/tripal_feature');
  20. drupal_set_breadcrumb($breadcrumb);
  21. // Add the view
  22. $view = views_embed_view('tripal_feature_admin_features','default');
  23. if (isset($view)) {
  24. $output .= $view;
  25. }
  26. else {
  27. $output .= '<p>The Feature module uses primarily views to provide an '
  28. . 'administrative interface. Currently one or more views needed for this '
  29. . 'administrative interface are disabled. <strong>Click each of the following links to '
  30. . 'enable the pertinent views</strong>:</p>';
  31. $output .= '<ul>';
  32. $output .= '<li>'.l('Features View', 'admin/tripal/chado/tripal_feature/views/features/enable').'</li>';
  33. $output .= '</ul>';
  34. }
  35. // Add a summary chart.
  36. $organism_feature_count = chado_select_record(
  37. 'organism_feature_count',
  38. array('*'),
  39. array(),
  40. array('order_by' => array('genus' => 'ASC', 'species' => 'ASC', 'feature_type' => 'ASC', 'num_features' => 'DESC'))
  41. );
  42. $summary = array();
  43. $organisms = array();
  44. $types = array();
  45. $chart = array();
  46. foreach ($organism_feature_count as $row) {
  47. $summary[$row->organism_id][$row->cvterm_id] = $row->num_features;
  48. $organisms[$row->organism_id]['organism_id'] = $row->organism_id;
  49. $organisms[$row->organism_id]['genus'] = $row->genus;
  50. $organisms[$row->organism_id]['species'] = $row->species;
  51. $organisms[$row->organism_id]['common_name'] = $row->common_name;
  52. $organisms[$row->organism_id]['scientific_name'] = $row->genus . ' ' . $row->species;
  53. $organisms[$row->organism_id]['total_features'] = (isset($organisms[$row->organism_id]['total_features'])) ? $organisms[$row->organism_id]['total_features'] + $row->num_features : $row->num_features;
  54. $types[$row->cvterm_id]['cvterm_id'] = $row->cvterm_id;
  55. $types[$row->cvterm_id]['name'] = $row->feature_type;
  56. $types[$row->cvterm_id]['total_features'] = (isset($types[$row->cvterm_id]['total_features'])) ? $types[$row->cvterm_id]['total_features'] + $row->num_features : $row->num_features;
  57. $chart[$row->cvterm_id]['cvterm_id'] = $row->cvterm_id;
  58. $chart[$row->cvterm_id]['name'] = $row->feature_type;
  59. $chart[$row->cvterm_id]['max_features'] = (isset($types[$row->cvterm_id]['max_features'])) ? max($types[$row->cvterm_id]['max_features'], $row->num_features) : $row->num_features;
  60. $chart[$row->cvterm_id]['organisms'][] = array(
  61. 'name' => $row->genus . ' ' . $row->species,
  62. 'value' => (int) $row->num_features
  63. );
  64. $type_names[$row->cvterm_id] = $row->feature_type;
  65. $organism_names[$row->organism_id] = $row->genus . ' ' . $row->species;
  66. }
  67. // Quick processing of the organisms array per type
  68. // to build-up the stacked bars.
  69. foreach ($chart as $type_id => $bar) {
  70. $y0 = 0;
  71. $y1 = 0;
  72. $chart[$type_id]['bars'] = array();
  73. foreach ($bar['organisms'] as $k => $org) {
  74. $y0 = $y1;
  75. $y1 = $y0 + $org['value'];
  76. $chart[$type_id]['bars'][$k]['name'] = $org['name'];
  77. $chart[$type_id]['bars'][$k]['y0'] = $y0;
  78. $chart[$type_id]['bars'][$k]['y1'] = $y1;
  79. }
  80. $chart[$type_id]['total_features'] = $y1;
  81. }
  82. $variables['organisms'] = $organisms;
  83. $variables['types'] = $types;
  84. // Sort based on the total number of features.
  85. // NOTE: This changes the keys so it's no longer the organism/type_id.
  86. usort($chart, 'tripal_feature_admin_summary_sort');
  87. sort($type_names);
  88. sort($organism_names);
  89. // We also need to add information about the materialized views
  90. // so that admin can update it and know how recent the data is.
  91. $mview = db_query('
  92. SELECT mview_id, name, last_update
  93. FROM tripal_mviews
  94. WHERE mv_table=:mv_table',
  95. array(':mv_table' => 'organism_feature_count')
  96. )->fetchObject();
  97. tripal_add_d3js();
  98. drupal_add_css(drupal_get_path('module','tripal_feature') . '/theme/css/tripal_feature.css');
  99. drupal_add_js(drupal_get_path('module','tripal_feature') . '/theme/js/tripalFeature.adminChart.js');
  100. drupal_add_js(array('tripalFeature' => array('admin' => array(
  101. 'summary' => $chart,
  102. 'types' => $type_names,
  103. 'organisms' => $organism_names,
  104. 'mviewUrl' => url('admin/tripal/schema/mviews/update/' . $mview->mview_id),
  105. 'mviewUable' => $mview->name,
  106. 'mviewLastUpdate' => format_date($mview->last_update),
  107. ))), 'setting');
  108. return $output;
  109. }
  110. /**
  111. * Feature Settings page
  112. *
  113. * @ingroup tripal_feature
  114. */
  115. function tripal_feature_admin() {
  116. // FEATURE PAGE TITLES
  117. // Using the Chado Node: Title & Path API
  118. $details = array(
  119. 'module' => 'tripal_feature',
  120. 'content_type' => 'chado_feature',
  121. // An array of options to use under "Page Titles"
  122. // the key should be the token and the value should be the human-readable option
  123. 'options' => array(
  124. '[feature.name]' => 'Feature Name Only',
  125. '[feature.uniquename]' => 'Feature Unique Name Only',
  126. // there should always be one options matching the unique constraint.
  127. '[feature.name], [feature.uniquename] ([feature.type_id>cvterm.name]) [feature.organism_id>organism.genus] [feature.organism_id>organism.species]' => 'Unique Contraint: Includes the name, uniquename, type and scientific name'
  128. ),
  129. // the token indicating the unique constraint in the options array
  130. 'unique_option' => '[feature.name], [feature.uniquename] ([feature.type_id>cvterm.name]) [feature.organism_id>organism.genus] [feature.organism_id>organism.species]'
  131. );
  132. // This call adds the configuration form to your current form
  133. // This sub-form handles it's own validation & submit
  134. chado_add_admin_form_set_title($form, $form_state, $details);
  135. // FEATURE NODE URL
  136. // Using the Chado Node: Title & Path API
  137. $details = array(
  138. 'module' => 'tripal_feature',
  139. 'content_type' => 'chado_feature',
  140. // An array of options to use under "Page URL"
  141. // the key should be the token and the value should be the human-readable option
  142. 'options' => array(
  143. '/feature/[feature.feature_id]' => 'Feature ID',
  144. // there should always be one options matching the unique constraint.
  145. '/feature/[feature.organism_id>organism.genus]/[feature.organism_id>organism.species]/[feature.type_id>cvterm.name]/[feature.uniquename]' => 'Unique Contraint: Includes the name, uniquename, type and scientific name'
  146. )
  147. );
  148. // This call adds the configuration form to your current form
  149. // This sub-form handles it's own validation & submit
  150. chado_add_admin_form_set_url($form, $form_state, $details);
  151. // FEATURE BROWSER
  152. $form['browser'] = array(
  153. '#type' => 'fieldset',
  154. '#title' => t('Feature Browser'),
  155. '#collapsible' => TRUE,
  156. '#collapsed' => TRUE,
  157. );
  158. $form['browser']['browser_desc'] = array(
  159. '#markup' => t('A feature browser can be added to an organism page to allow users to quickly ' .
  160. 'access a feature. This will most likely not be the ideal mechanism for accessing feature ' .
  161. 'information, especially for large sites, but it will alow users exploring the site (such ' .
  162. 'as students) to better understand the data types available on the site.'),
  163. );
  164. $form['browser']['feature_types'] = array(
  165. '#title' => t('Feature Types'),
  166. '#type' => 'textarea',
  167. '#description' => t("Enter the Sequence Ontology (SO) terms for the feature types that " .
  168. "will be shown in the feature browser."),
  169. '#default_value' => variable_get('chado_browser_feature_types', 'gene mRNA'),
  170. );
  171. $form['browser']['set_browse_button'] = array(
  172. '#type' => 'submit',
  173. '#value' => t('Set Browser'),
  174. '#weight' => 2,
  175. );
  176. // FEATURE SUMMARY REPORT
  177. $form['summary'] = array(
  178. '#type' => 'fieldset',
  179. '#title' => t('Feature Summary Report'),
  180. '#collapsible' => TRUE,
  181. '#collapsed' => TRUE,
  182. );
  183. $form['summary']['feature_mapping'] = array(
  184. '#title' => 'Map feature types',
  185. '#description' => t('You may specify which Sequence Ontology (SO) terms to show in the ' .
  186. 'feature summary report by listing them in the following text area. Enter one per line. ' .
  187. 'If left blank, all SO terms for all features will be shown in the report. Only those terms ' .
  188. 'listed below will be shown in the report. Terms will appear in the report in the same order listed. To rename a ' .
  189. 'SO term to be more human readable form, use an \'=\' sign after the SO term (e.g. \'polypeptide = Protein\')'),
  190. '#type' => 'textarea',
  191. '#rows' => 15,
  192. '#default_value' => variable_get('tripal_feature_summary_report_mapping', ''),
  193. );
  194. $form['summary']['set_summary_button'] = array(
  195. '#type' => 'submit',
  196. '#value' => t('Set Summary'),
  197. '#weight' => 2,
  198. );
  199. return system_settings_form($form);
  200. }
  201. /**
  202. * Validate the feature settings forms
  203. *
  204. * @ingroup tripal_feature
  205. */
  206. function tripal_feature_admin_validate($form, &$form_state) {
  207. global $user; // we need access to the user info
  208. $job_args = array();
  209. variable_set('chado_browser_feature_types', $form_state['values']['feature_types']);
  210. switch ($form_state['values']['op']) {
  211. case t('Set Summary') :
  212. variable_set('tripal_feature_summary_report_mapping', $form_state['values']['feature_mapping']);
  213. break;
  214. }
  215. }
  216. /**
  217. * USort function for the admin summary chart.
  218. * Not meant to be called directly.
  219. */
  220. function tripal_feature_admin_summary_sort($a, $b) {
  221. if ($a['total_features'] == $b['total_features']) return 0;
  222. return $b['total_features'] - $a['total_features'];
  223. }