tripal_core.extensions.inc 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <?php
  2. function tripal_core_extensions_form($form, &$form_state = NULL) {
  3. $tab = $_GET['tab'];
  4. $form['extensions'] = array(
  5. '#type' => 'vertical_tabs',
  6. '#default_tab' => $tab,
  7. );
  8. // Get the RSS feed XML from the tripa.info website.
  9. $content = file_get_contents("http://tripal.info/rss/extensions.xml");
  10. $xml = new SimpleXmlElement($content);
  11. $namespace = "http://tripal.info/rss/extensions/";
  12. // Parse the items into an array indexed by category and compatible versions.
  13. $items = array();
  14. $types = array();
  15. $categories = array();
  16. foreach ($xml->channel->item as $item) {
  17. $type = (string) $item->category;
  18. // In order to get fields in the 'tripal_extension' name space we must
  19. // pass in the $namespace to the children function. We first get the
  20. // Tripal versions, then the chado versions and organize the elements
  21. // accordintly.
  22. $tvs = preg_split('/, /', (string) $item->children($namespace)->tripal_version);
  23. foreach($tvs as $tv) {
  24. $cvs = preg_split('/, /', (string) $item->children($namespace)->chado_version);
  25. foreach($cvs as $cv) {
  26. // Index the items by category, tripal version and chado version
  27. $items[$tv][$cv][$type][] = $item;
  28. if (!in_array($type, $types)) {
  29. $types[] = $type;
  30. }
  31. }
  32. }
  33. }
  34. // Get the Chado version and convert to the expected format
  35. $chado_version = chado_get_version(TRUE);
  36. $chado_version = preg_replace('/^(\d\.\d).*$/', "v$1x", $chado_version);
  37. // Get the Tripal version. This is the version set in the tripal_core.info
  38. $info = system_get_info('module', 'tripal_core');
  39. $tripal_version = $info['version'];
  40. $tripal_version = preg_replace('/^.*?-(\d\.\d+).*$/', "v$1", $tripal_version);
  41. $form['instructions'] = array(
  42. '#type' => 'item',
  43. '#markup' => t('This page will help you find extensions that are available
  44. for Tripal. Select an extension type from the vertical tabs to see
  45. the each type of extension.')
  46. );
  47. // Build the fieldsets for each category
  48. sort($types);
  49. $type_ids = array();
  50. foreach ($types as $type) {
  51. $type_id = preg_replace('/[^\w]/','_', strtolower($type));
  52. $type_ids[$type] = $type_id;
  53. $form[$type] = array(
  54. '#id' => $type_id,
  55. '#type' => 'fieldset',
  56. '#title' => $type . 's',
  57. '#collapsed' => TRUE,
  58. '#collapsible' => TRUE,
  59. '#group' => 'extensions',
  60. );
  61. }
  62. // Iterate through the compatible extensions. We will add a pager for
  63. // each type of extension, and display only those that should appear
  64. // on the page.
  65. $type_index = 0;
  66. foreach ($items[$tripal_version][$chado_version] as $type => $items) {
  67. // Initialize pager and gets current page
  68. $num_per_page = 5;
  69. $total_items = count($items);
  70. $page = pager_default_initialize($total_items, $num_per_page, $type_index);
  71. // Gets first record and last record to show
  72. $start = ($page) * $num_per_page;
  73. $end = ($start + $num_per_page < $total_items)? $start + $num_per_page : $total_items;
  74. // Iterate through each of the elements and add them to the form if
  75. // they are within the page
  76. $item_index = 0;
  77. foreach ($items as $item) {
  78. // Skip items that aren't on our current page.
  79. if ($item_index < $start or $item_index >= $end) {
  80. $item_index++;
  81. continue;
  82. }
  83. // The unique guid is used to keep track of each extension in the form.
  84. $guid = (string) $item->guid;
  85. // If this is an extension module then there will be a home page for it
  86. $home_page = '';
  87. if ((string) $item->children($namespace)->home_page) {
  88. $home_page = "<strong>Project Home: </strong>" . (string) $item->children($namespace)->home_page . "</br>";
  89. }
  90. // If the user click's the button to import the extension then we
  91. // need the item in the submit function so we can process the import.
  92. $form[$type]['item-' . $guid] = array(
  93. '#type' => 'value',
  94. '#value' => $item,
  95. );
  96. // Create the form elements that we'll later theme into tables.
  97. $form[$type][$guid]['header'] = array(
  98. '#markup' => l((string) $item->title, $item->link),
  99. );
  100. $form[$type][$guid]['details'] = array(
  101. '#markup' => "" .
  102. "<strong>Type:</strong> " . $type . "</br>" .
  103. "<strong>Categories: </strong>" . (string) $item->children($namespace)->categories . "</br>" .
  104. "<strong>Authors: </strong>" . (string) $item->children($namespace)->authors . "</br>" .
  105. "<strong>Chado compatible versions: </strong>" . (string) $item->children($namespace)->chado_version . "</br>" .
  106. "<strong>Chado compatible versions: </strong>" . (string) $item->children($namespace)->tripal_version . "</br>" .
  107. $home_page .
  108. "<p>" . (string) $item->description . "</p>",
  109. );
  110. // Add an import button to each of types that can support import.
  111. switch ($type) {
  112. case 'Bulk Loader Template':
  113. $form[$type][$guid]['import'] = array(
  114. '#type' => 'submit',
  115. '#value' => "Import Loader",
  116. '#name' => "import-" . $guid,
  117. );
  118. break;
  119. case 'Materialized View':
  120. $form[$type][$guid]['import'] = array(
  121. '#type' => 'submit',
  122. '#value' => "Import MView",
  123. '#name' => "import-" . $guid,
  124. );
  125. break;
  126. case 'Extension Module':
  127. $form[$type][$guid]['import'] = array(
  128. '#type' => 'submit',
  129. '#value' => "Download Module",
  130. '#name' => "import-" . $guid,
  131. );
  132. break;
  133. default:
  134. break;
  135. }
  136. $form[$type][$guid]['#theme'] = 'tripal_core_extensions_form_tables';
  137. $item_index++;
  138. }
  139. // Now create and theme the pager.
  140. $pager = array(
  141. 'tags' => array(),
  142. 'element' => $type_index,
  143. 'parameters' => array(
  144. 'tab' => $type_ids[$type],
  145. ),
  146. 'quantity' => $num_per_page,
  147. );
  148. // because this may be an ajax callback, the theme_pager will set the URL to be
  149. // "system/ajax", so we need to reset that
  150. global $base_path;
  151. $pager = str_replace($base_path . "system/ajax", "", $pager) ;
  152. $form[$type]['pager'] = array(
  153. '#type' => 'item',
  154. '#markup' => theme('pager', $pager),
  155. );
  156. $type_index++;
  157. }
  158. return $form;
  159. }
  160. /**
  161. * Process the import buttons.
  162. *
  163. * @param $form
  164. * @param $form_state
  165. */
  166. function tripal_core_extensions_form_submit($form, &$form_state) {
  167. // get the guid
  168. $clicked_button = $form_state['clicked_button']['#name'];
  169. $guid = preg_replace('/^import-(\d+)$/', "$1", $clicked_button);
  170. if ($guid) {
  171. $namespace = "http://tripal.info/rss/extensions/";
  172. $item = $form_state['values']['item-' . $guid];
  173. $type = $item->category;
  174. switch ($type) {
  175. case 'Bulk Loader Template':
  176. break;
  177. case 'Materialized View':
  178. $modulename = 'tripal_core';
  179. $mview_name = (string) $item->children($namespace)->mview_name;
  180. $mview_schema = (string) $item->children($namespace)->mview_schema;
  181. $mview_sql = (string) $item->children($namespace)->mview_sql;
  182. // Validate the contents of the schema array.
  183. // TODO: security issue!! Before using 'eval' on this string
  184. // we should make sure the array is valid and there is no hidden
  185. // PHP code.
  186. $schema_array = array();
  187. $success = eval("\$schema_array = $mview_schema;");
  188. $error = chado_validate_custom_table_schema($schema_array);
  189. if ($error) {
  190. drupal_set_message("Cannot import Materialized View. $error");
  191. }
  192. tripal_add_mview($mview_name, $modulename, $schema_array, $mview_sql);
  193. break;
  194. case 'Extension Module':
  195. break;
  196. default:
  197. break;
  198. }
  199. }
  200. }
  201. /**
  202. * The theme function for rendering each element's table.
  203. *
  204. * @param $variables
  205. */
  206. function theme_tripal_core_extensions_form_tables($variables) {
  207. $element = $variables['element'];
  208. $headers = array(
  209. array(
  210. 'data' => drupal_render($element['header']),
  211. 'colspan' => 2,
  212. )
  213. );
  214. $button = array_key_exists('import', $element) ? drupal_render($element['import']) : '&nbsp;';
  215. $rows = array(
  216. array(
  217. array(
  218. 'data' => drupal_render($element['details']),
  219. ),
  220. array(
  221. 'data' => $button,
  222. 'width' => '5%',
  223. 'align' => 'right',
  224. ),
  225. ),
  226. );
  227. $table = array(
  228. 'header' => $headers,
  229. 'rows' => $rows,
  230. 'attributes' => array(),
  231. 'sticky' => FALSE,
  232. 'caption' => '',
  233. 'colgroups' => array(),
  234. 'empty' => '',
  235. );
  236. return theme_table($table);
  237. }