tripal_views_integration.inc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. <?php
  2. /**
  3. * Purpose: Provide Guidance to new Tripal Admin
  4. *
  5. * @return
  6. * HTML Formatted text
  7. *
  8. * @ingroup tripal_views_integration
  9. */
  10. function tripal_core_views_description_page() {
  11. $text .= '<h3>Tripal Views Quick Links:</h3>';
  12. $text .= "<ul>
  13. <li><a href=\"".url("admin/tripal/views/mviews") . "\">List of Materialized Views (MViews)</a></li>
  14. <li><a href=\"".url("admin/tripal/views/mviews/new") . "\">Create a new MViews</a></li>
  15. <li><a href=\"".url("admin/tripal/views/integration/mviews") . "\">List of integrated MViews</a></li>
  16. <li><a href=\"".url("admin/tripal/views/integration/mviews/new"). "\">Integrate a MView</a></li>
  17. <li><a href=\"".url("admin/tripal/views/integration/chado"). "\">List of integrated Chado tables</a></li>
  18. <li><a href=\"".url("admin/tripal/views/integration/chado/new"). "\">Integrate a Chado tables</a></li>
  19. </ul>";
  20. $text .= '<h3>Views Integartion Description:</h3>';
  21. $text .= '<p>Tripal Views provides an interface for integrating <a href="http://drupal.org/project/views">Drupal Views</a>
  22. with Tripal materialized views. This will allow site administrators to create custom queries for the materialized views
  23. and in turn provide custom content pages, custom blocks and custom search forms. The forms allow a site administrator
  24. to select a materialized view and associate other Chado tables on which the view can join. Usage of this module requires
  25. a good understanding of foreign-key relationships in Chado.
  26. </p>';
  27. $text .= '<h3>Setup Instructions:</h3>';
  28. $text .= '<p>After installation of the Tripal core module. The following tasks should be performed
  29. <ol>
  30. <li><b>Set Permissions</b>: To allow access to site administrators for this module, simply
  31. <a href="'.url('admin/user/permissions').'">assign permissions</a> to the appropriate user roles for the
  32. permission type "manage tripal_views_integration". </li>
  33. </ol>
  34. </p>';
  35. $text .= '<h3>Usage Instructions:</h3>';
  36. $text .= "<p>To use Tripal Views integration follow these steps:
  37. <ol>
  38. <li><b>Identify or create a materialized view:</b> Using the <a href=\"".url("admin/tripal/views/mviews") . "\">
  39. Tripal materialized View</a> interface, identify the view you would like to integrate or create a new one.</li>
  40. <li><b>Setup the Views Integration</b>: Navigate to the <a href=\"".url("admin/tripal/views/integration/mviews/new") . "\">
  41. Tripal views integration setup page</a> to integrate the selected materialized view. Provide a user friendly name
  42. and description to help you remember the purpose for integrating the view. Next, select the view you want to integrate
  43. from the provided select box. If your materialized view has fields that can join with other Chado tables, you may
  44. provide those relationships in the provided form. Finally, if your fields require a special handler for display, you
  45. may select it from the drop down provided</li>
  46. <li><b>Create custom pages/block/search form</b>: After saving setup information from step 2 above, you will be redirected to the
  47. Drupal Views interface</a> where you can create a custom page, block or search form.</li>
  48. <li><b>Review your integrated views</b>: A page providing a
  49. <a href=\"".url("admin/tripal/views/integration/mviews/list") . "\">list of all integrated views</a> is provided. You may
  50. view this page to see all integrated views, but also to remove any unwanted integrations.</li>
  51. </ol>
  52. </p>";
  53. return $text;
  54. }
  55. /**
  56. *
  57. * @ingroup tripal_views_integration
  58. */
  59. function tripal_core_views_integration_admin_form(){
  60. $form = array();
  61. $form['#theme'] = 'tripal';
  62. $query_results = db_query('SELECT * FROM tripal_views');
  63. $header = array('Setup ID', 'Name', 'MView ID', 'Table Name', 'Comment');
  64. $rows = array();
  65. $results = array();
  66. while($result = db_fetch_object($query_results)){
  67. $rows[] = array($result->setup_id, $result->name, $result->mview_id, $result->base_table_name, $result->comment);
  68. $results[] = $result;
  69. }
  70. $options = array();
  71. foreach ($results as $key => $value) {
  72. if(!empty($value))
  73. $options[] = $value->setup_id;// . ' | ' . $value->name . ' | ' . $value->mview_id . ' | ' . $value->base_table_name;
  74. }
  75. $form['existing_rows'] = array(
  76. '#type' => 'select',
  77. '#options' => $options,
  78. '#description' => '<strong>Select a View Setup to delete from the database.</strong>',
  79. '#prefix' => theme('table', $header, $rows),
  80. );
  81. $form['submit'] = array(
  82. '#type' => 'submit',
  83. '#value' => t('Remove'),
  84. );
  85. $form['new'] = array(
  86. '#type' => 'markup',
  87. '#value' => l(t(' Add a New MView'), 'admin/tripal/views/integration/mviews/new'),
  88. );
  89. return $form;
  90. }
  91. /**
  92. *
  93. * @ingroup tripal_views_integration
  94. */
  95. function tripal_core_views_integration_admin_form_submit($form, &$form_state){
  96. $value = $form['existing_rows']['#options'][$form_state['values']['existing_rows']];
  97. db_query("DELETE FROM public.tripal_views WHERE setup_id = $value;");
  98. db_query("DELETE FROM public.tripal_views_handlers WHERE setup_id = $value;");
  99. db_query("DELETE FROM public.tripal_views_join WHERE setup_id = $value;");
  100. }
  101. /**
  102. *
  103. * @ingroup tripal_views_integration
  104. */
  105. function tripal_core_views_integration_new_setup_form(&$form_state){
  106. $form = array();
  107. $data = array();
  108. $form['#cache'] = TRUE;
  109. //ahah_helper requires this to register the form with it's module
  110. ahah_helper_register($form, $form_state);
  111. // field for the name of the
  112. $form['row_name'] = array(
  113. '#title' => t('View Type Name'),
  114. '#type' => 'textfield',
  115. '#size' => 60,
  116. '#maxlength' => 128,
  117. '#description' => 'Provide the view type name. This is the name that will appear in the Drupal Views interface when adding a new view.',
  118. '#required' => TRUE,
  119. );
  120. $form['row_description'] = array(
  121. '#title' => t('Comment'),
  122. '#type' => 'textarea',
  123. '#description' => '(Optional). Provide any details regarding this setup you would like.',
  124. '#required' => FALSE,
  125. );
  126. $mview_query = db_query("SELECT mview_id,name FROM {tripal_mviews} ORDER BY name;");
  127. $mview_options = array();
  128. $mview_options['0'] = 'Select';
  129. while ($mview_option = db_fetch_array($mview_query)){
  130. $mview_options[$mview_option['mview_id']] = $mview_option['name'];
  131. }
  132. $form['mview_id'] = array(
  133. '#title' => t('Materialized View'),
  134. '#type' => 'select',
  135. '#options' => $mview_options,
  136. '#description' => 'Which materialized view to use.',
  137. '#required' => TRUE,
  138. '#default_value' => $mview_default_value,
  139. '#ahah' => array(
  140. 'path' => ahah_helper_path(array('view_setup_table')),
  141. 'wrapper' => 'table-rows-div',
  142. 'effect' => 'fade',
  143. 'event' => 'change',
  144. 'method' => 'replace',
  145. ),
  146. );
  147. $form['view_setup_table'] = array(
  148. '#type' => 'item',
  149. '#prefix' => '<div id="table-rows-div">',
  150. '#suffix' => '</div>',
  151. );
  152. if ($form_state['storage']['mview_id']){
  153. $mview_id = $form_state['storage']['mview_id'];
  154. $form['view_setup_table'] = array(
  155. '#type' => 'fieldset',
  156. '#title' => 'Join Selection',
  157. '#prefix' => '<div id="fieldset-table-rows-wrapper">',
  158. '#suffix' => '</div>',
  159. );
  160. // get the columns in this materialized view. They are separated by commas
  161. // where the first word is the column name and the rest is the type
  162. $sql = "SELECT mv_specs FROM {tripal_mviews} WHERE mview_id = $mview_id";
  163. $mview = db_fetch_object(db_query($sql));
  164. $columns = explode(",",$mview->mv_specs);
  165. $i=1;
  166. $chado_tables = tripal_core_get_chado_tables();
  167. $chado_tables = array_merge(array('Select a Join Table',), $chado_tables);
  168. $form['view_setup_table']["instructions"] = array(
  169. '#type' => 'markup',
  170. '#value' => "Select an optional table to which the fields of the materialized view can join. If a field does not need to join you may leave the selection blank.",
  171. );
  172. $data['field_types'] = array();
  173. // get list of all handlers
  174. $all_handlers = tripal_core_views_integration_discover_handlers();
  175. $handlers_fields = array();
  176. $handlers_filters = array();
  177. $handlers_sort = array();
  178. $handlers_arguments = array();
  179. $handlers_join = array();
  180. $handlers_rel = array();
  181. $handlers_fields[0] = "Select a field handler";
  182. $handlers_filters[0] = "Select a filter handler";
  183. $handlers_sort[0] = "Select a sort handler";
  184. $handlers_argument[0] = "Select an argument handler";
  185. $handlers_join[0] = "Select a join handler";
  186. $handlers_rel[0] = "Select a relationship handler";
  187. foreach($all_handlers as $handler){
  188. if(preg_match("/views_handler_field/",$handler)){
  189. $handlers_fields[$handler] = $handler;
  190. }
  191. if(preg_match("/views_handler_filter/",$handler)){
  192. $handlers_filters[$handler] = $handler;
  193. }
  194. if(preg_match("/views_handler_sort/",$handler)){
  195. $handlers_sort[$handler] = $handler;
  196. }
  197. if(preg_match("/views_handler_argument/",$handler)){
  198. $handlers_argument[$handler] = $handler;
  199. }
  200. if(preg_match("/views_handler_join/",$handler)){
  201. $handlers_join[$handler] = $handler;
  202. }
  203. if(preg_match("/views_handler_relationship/",$handler)){
  204. $handlers_rel[$handler] = $handler;
  205. }
  206. }
  207. foreach ($columns as $column){
  208. $column = trim($column); // trim trailing and leading spaces
  209. preg_match("/^(.*?)\ (.*?)$/",$column,$matches);
  210. $column_name = $matches[1];
  211. $column_type = $matches[2];
  212. $form['view_setup_table']["fields_start_$mview_id-$i"] = array(
  213. '#type' => 'markup',
  214. '#value' => "<div class=\"fields-new-row\">",
  215. );
  216. $form['view_setup_table']["fields_name_$mview_id-$i"] = array(
  217. '#type' => 'markup',
  218. '#attributes' => array('class' => 'fields-column-name'),
  219. '#value' => "<div class=\"column-id\">".
  220. "<span class=\"column-name\">$column_name</span>".
  221. "<br><span class=\"column-type\">$column_type</span>".
  222. "</div>".
  223. "<div class=\"column-form-fields\"><div class=\"column-one\">",
  224. );
  225. $data['field_types'][$column_name] = $column_type;
  226. $table = $form_state['storage']["fields_join_$mview_id-$i"];
  227. $form['view_setup_table']["fields_join_$mview_id-$i"] = array(
  228. '#type' => 'select',
  229. '#prefix' => "<div class=\"fields-column-join\">",
  230. '#suffix' => "</div>",
  231. '#options' => $chado_tables,
  232. '#required' => FALSE,
  233. '#default_value' => $table,
  234. '#ahah' => array(
  235. 'path' => ahah_helper_path(array("view_setup_table","fields_join_column_$mview_id-$i")),
  236. 'wrapper' => "fields-column-join-column-$mview_id-$i",
  237. 'effect' => 'fade',
  238. 'event' => 'change',
  239. 'method' => 'replace',
  240. ),
  241. );
  242. $columns = array();
  243. if($table){
  244. $table_desc = module_invoke_all('chado_'.$table.'_schema');
  245. foreach ($table_desc['fields'] as $column => $def){
  246. $columns[$column] = $column;
  247. }
  248. } else {
  249. $columns = array('Select Join Column');
  250. }
  251. $form['view_setup_table']["fields_join_column_$mview_id-$i"] = array(
  252. '#type' => 'select',
  253. '#prefix' => " <div id=\"fields-column-join-column-$mview_id-$i\" class=\"fields-column-join-column\">",
  254. '#suffix' => "</div></div>",
  255. '#options' => $columns,
  256. '#required' => FALSE,
  257. );
  258. $form['view_setup_table']["fields_field_handler_$mview_id-$i"] = array(
  259. '#type' => 'select',
  260. '#prefix' => "<div class=\"column-two\">".
  261. "<div class=\"fields-field-handler\">",
  262. '#suffix' => "</div>",
  263. '#options' => $handlers_fields,
  264. '#required' => FALSE,
  265. );
  266. $form['view_setup_table']["fields_filter_handler_$mview_id-$i"] = array(
  267. '#type' => 'select',
  268. '#prefix' => "<div class=\"fields-filter-handler\">",
  269. '#suffix' => "</div>",
  270. '#options' => $handlers_filters,
  271. '#required' => FALSE,
  272. );
  273. $form['view_setup_table']["fields_sort_handler_$mview_id-$i"] = array(
  274. '#type' => 'select',
  275. '#prefix' => "<div class=\"fields-sort-handler\">",
  276. '#suffix' => "</div>",
  277. '#options' => $handlers_sort,
  278. '#required' => FALSE,
  279. );
  280. $form['view_setup_table']["fields_argument_handler_$mview_id-$i"] = array(
  281. '#type' => 'select',
  282. '#prefix' => "<div class=\"fields-argument-handler\">",
  283. '#suffix' => "</div>",
  284. '#options' => $handlers_argument,
  285. '#required' => FALSE,
  286. );
  287. $form['view_setup_table']["fields_relationship_handler_$mview_id-$i"] = array(
  288. '#type' => 'select',
  289. '#prefix' => "<div class=\"fields-relationship-handler\">",
  290. '#suffix' => "</div>",
  291. '#options' => $handlers_rel,
  292. '#required' => FALSE,
  293. );
  294. $form['view_setup_table']["fields_join_handler_$mview_id-$i"] = array(
  295. '#type' => 'select',
  296. '#prefix' => "<div class=\"fields-join-handler\">",
  297. '#suffix' => "</div></div>",
  298. '#options' => $handlers_join,
  299. '#required' => FALSE,
  300. );
  301. $form['view_setup_table']["fields_end_$i"] = array(
  302. '#type' => 'markup',
  303. '#value' => "</div></div>",
  304. );
  305. $i++;
  306. }
  307. $form['view_setup_table']['save'] = array(
  308. '#type' => 'submit',
  309. '#value' => t('Save'),
  310. );
  311. $data['row_count'] = $i - 1;
  312. }
  313. //use this to put values into $form_state['values']
  314. $form['data'] = array();
  315. //need to find out if storing $form['data'][$key]['#value'] = $value <- is an issue
  316. //since it will give me errors if i try to stare an array instead of $value
  317. //and yet $value can be an array ie "field_types"
  318. foreach ($data as $key => $value) {
  319. $form['data'][$key] = array(
  320. '#type' => 'hidden',
  321. '#value' => $value,
  322. );
  323. }
  324. return $form;
  325. }
  326. /**
  327. *
  328. * @ingroup tripal_views_integration
  329. */
  330. function tripal_core_views_integration_new_setup_form_validate($form, &$form_state){
  331. $name_array = explode(" ", $form_state['values']['row_name']);
  332. if(count($name_array) > 1){
  333. form_set_error($form_state['values']['row_name'], 'Name must be ONE word only.');
  334. }
  335. //TODO: write validation function for this new form
  336. }
  337. /**
  338. *
  339. * @ingroup tripal_views_integration
  340. */
  341. function tripal_core_views_integration_new_setup_form_submit($form, &$form_state){
  342. $name = $form_state['values']['row_name'];
  343. $mview_id = $form_state['values']['mview_id'];
  344. $table_name = $form_state['values']['table_name'];
  345. $sql = "SELECT * FROM {tripal_mviews} WHERE mview_id = $mview_id";
  346. $mview = db_fetch_object(db_query($sql));
  347. // If this is for a materialized view then we want to add that record
  348. $tripal_views_record = array();
  349. if($mview_id){
  350. $tripal_views_record = array(
  351. 'mview_id' => $mview_id,
  352. 'name' => $name,
  353. 'comment' => $form_state['values']['row_description'],
  354. );
  355. if(!drupal_write_record('tripal_views', $tripal_views_record)){
  356. drupal_set_message("Failed to add setup.");
  357. return;
  358. }
  359. }
  360. // if not a materialized view then just keep track of the table name
  361. if($table_name){
  362. $tripal_views_record = array(
  363. 'table_name' => $table_name,
  364. 'name' => $name,
  365. 'comment' => $form_state['values']['row_description'],
  366. );
  367. drupal_write_record('tripal_views', $tripal_views_record);
  368. }
  369. // iterate through the columns of the form and add
  370. // the joins if provided, and the handlers
  371. $i = 1;
  372. foreach ($form_state['values']['field_types'] as $key => $value){
  373. // first add the join if it exists
  374. $left_table = $form_state['values']["fields_join_$mview_id-$i"];
  375. $left_column = $form_state['values']["fields_join_column_$mview_id-$i"];
  376. if($left_column){
  377. $view_join_record = array(
  378. 'setup_id' => $tripal_views_record['setup_id'],
  379. 'base_table' => $mview->mv_table,
  380. 'base_field' => $key,
  381. 'left_table' => $left_table,
  382. 'left_field' => $left_column,
  383. );
  384. drupal_write_record('tripal_views_join', $view_join_record);
  385. }
  386. // add the hanlders
  387. $handlers = array('filter','field','sort','argument','join','relationship');
  388. foreach($handlers as $handler){
  389. $handler_name = $form_state['values']["fields_".$handler."_handler_$mview_id-$i"];
  390. if($handler_name){
  391. $handler_record = array(
  392. 'setup_id' => $tripal_views_record['setup_id'],
  393. 'column_name' => $key,
  394. 'handler_type' => $handler,
  395. 'handler_name' => $handler_name,
  396. );
  397. drupal_write_record('tripal_views_handlers', $handler_record);
  398. }
  399. }
  400. $i++;
  401. }
  402. }
  403. /**
  404. *
  405. * @ingroup tripal_views_integration
  406. */
  407. function tripal_core_views_integration_discover_handlers() {
  408. $handlers = array();
  409. // Get handlers from all modules.
  410. foreach (module_implements('views_handlers') as $module) {
  411. $function = $module . '_views_handlers';
  412. $result = $function();
  413. if (!is_array($result)) {
  414. continue;
  415. }
  416. foreach ($result['handlers'] as $handler => $parent){
  417. $handlers[] = $handler;
  418. }
  419. }
  420. // these handlers are hard coded because I could not
  421. // get the views_views_handlers() function to be called
  422. // in the code above. However, we will be creating
  423. // Chado wrappers for many of these and once that work
  424. // is done these will no longer be needed.
  425. // argument handlers
  426. $handlers[] = 'views_handler_argument';
  427. $handlers[] = 'views_handler_argument_numeric';
  428. $handlers[] = 'views_handler_argument_formula';
  429. $handlers[] = 'views_handler_argument_date';
  430. $handlers[] = 'views_handler_argument_string';
  431. $handlers[] = 'views_handler_argument_many_to_one';
  432. $handlers[] = 'views_handler_argument_null';
  433. // field handlers
  434. $handlers[] = 'views_handler_field';
  435. $handlers[] = 'views_handler_field_date';
  436. $handlers[] = 'views_handler_field_boolean';
  437. $handlers[] = 'views_handler_field_markup';
  438. $handlers[] = 'views_handler_field_xss';
  439. $handlers[] = 'views_handler_field_url';
  440. $handlers[] = 'views_handler_field_file_size';
  441. $handlers[] = 'views_handler_field_prerender_list';
  442. $handlers[] = 'views_handler_field_numeric';
  443. $handlers[] = 'views_handler_field_custom';
  444. $handlers[] = 'views_handler_field_counter';
  445. // filter handlers
  446. $handlers[] = 'views_handler_filter';
  447. $handlers[] = 'views_handler_filter_equality';
  448. $handlers[] = 'views_handler_filter_string';
  449. $handlers[] = 'views_handler_filter_boolean_operator';
  450. $handlers[] = 'views_handler_filter_boolean_operator_string';
  451. $handlers[] = 'views_handler_filter_in_operator';
  452. $handlers[] = 'views_handler_filter_numeric';
  453. $handlers[] = 'views_handler_filter_float';
  454. $handlers[] = 'views_handler_filter_date';
  455. $handlers[] = 'views_handler_filter_many_to_one';
  456. // relationship handlers
  457. $handlers[] = 'views_handler_relationship';
  458. // sort handlers
  459. $handlers[] = 'views_handler_sort';
  460. $handlers[] = 'views_handler_sort_formula';
  461. $handlers[] = 'views_handler_sort_date';
  462. $handlers[] = 'views_handler_sort_menu_hierarchy';
  463. $handlers[] = 'views_handler_sort_random';
  464. return $handlers;
  465. }