tripal_chado_views.views.inc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. <?php
  2. /**
  3. * @file
  4. * Chado Views Integration
  5. */
  6. include 'views/handlers/tripal_views_handler_area_action_links.inc';
  7. /**
  8. * Implements hook_views_handlers().
  9. *
  10. * Purpose: Register all custom handlers with views
  11. * where a handler describes either "the type of field",
  12. * "how a field should be filtered", "how a field should be sorted"
  13. *
  14. * @return
  15. * An array of handler definitions
  16. *
  17. * @ingroup tripal_chado_views
  18. */
  19. function tripal_chado_views_views_handlers() {
  20. return [
  21. 'info' => [
  22. 'path' => drupal_get_path('module', 'tripal_chado_views') . '/views/handlers',
  23. ],
  24. 'handlers' => [
  25. // Custom Tripal Field Handlers
  26. /** CANT FIX UNTIL Tripal Feature is working
  27. * 'tripal_views_handler_field_sequence' => array(
  28. * 'parent' => 'views_handler_field',
  29. * ),
  30. */
  31. // Custom area handler
  32. 'tripal_views_handler_area_action_links' => [
  33. 'parent' => 'views_handler_area',
  34. ],
  35. // Custom Tripal Filter Handlers
  36. 'tripal_views_handler_filter_no_results' => [
  37. 'parent' => 'views_handler_filter',
  38. ],
  39. 'tripal_views_handler_filter_select_cvterm' => [
  40. 'parent' => 'tripal_views_handler_filter_select_string',
  41. ],
  42. 'tripal_views_handler_filter_select_id' => [
  43. 'parent' => 'tripal_views_handler_filter_select_string',
  44. ],
  45. 'tripal_views_handler_filter_select_string' => [
  46. 'parent' => 'views_handler_filter_string',
  47. ],
  48. 'tripal_views_handler_filter_textarea' => [
  49. 'parent' => 'views_handler_filter',
  50. ],
  51. 'tripal_views_handler_filter_file_upload' => [
  52. 'parent' => 'views_handler_filter',
  53. ],
  54. /** D7 @todo: get handlers working
  55. */
  56. /** CANT FIX UNTIL Tripal Feature is working
  57. * 'tripal_views_handler_filter_sequence' => array(
  58. * 'parent' => 'chado_views_handler_filter_string',
  59. * ),
  60. */
  61. ],
  62. ];
  63. }
  64. /**
  65. * Implements hook_views_pre_render().
  66. *
  67. * Purpose: Intercepts the view after the query has been executed
  68. * All the results are stored in $view->result
  69. * Looking up the NID here ensures the query is only executed once
  70. * for all stocks in the table.
  71. *
  72. * @ingroup tripal_chado_views
  73. */
  74. function tripal_chado_views_views_pre_render(&$view) {
  75. // We need to unset the exposed_input for the view so we can repopulate that
  76. // variable. This is necessary if we're using the file_upload_combo
  77. // custom form element which adds the file_path variable to the $_GET after the
  78. // view has populated the $view->exposed_input variable
  79. unset($view->exposed_input);
  80. // Add css if tripal admin tagged view
  81. if ($view->tag == 'tripal admin') {
  82. $tripal_admin_view_css = drupal_get_path('module', 'tripal_chado_views') . '/theme/css/tripal_views_admin_views.css';
  83. drupal_add_css($tripal_admin_view_css);
  84. }
  85. }
  86. /**
  87. * Implements hook_views_data().
  88. *
  89. * Generates a dynamic data array for Views
  90. *
  91. * This function is a hook used by the Views module. It populates and
  92. * returns a data array that specifies for the Views module the base table,
  93. * the tables it joins with and handlers. The data array is populated
  94. * using the data stored in the tripal_views tables.
  95. *
  96. * @return a data array formatted for the Views module
  97. *
  98. * D7 @todo: Add support for materialized views relationships using the new
  99. * method
  100. *
  101. * @ingroup tripal_chado_views
  102. */
  103. function tripal_chado_views_views_data() {
  104. $data = [];
  105. // Manually integrate the drupal.tripal_views* tables
  106. $data = tripal_chado_views_views_data_tripal_views_tables($data);
  107. // Determine the name of the chado schema
  108. $chado_schema = chado_get_schema_name('chado');
  109. // MAKE SURE ALL CHADO TABLES ARE INTEGRATED
  110. tripal_chado_views_integrate_all_chado_tables();
  111. // DEFINE GLOBAL FIELDS
  112. // Filter handler that lets the admin say:
  113. // "Show no results until they enter search parameters"
  114. $data['views']['search_results'] = [
  115. 'title' => t('Delay Results'),
  116. 'help' => t('Delay results until Apply/Search is clicked by the user.'),
  117. 'filter' => [
  118. 'handler' => 'tripal_views_handler_filter_no_results',
  119. ],
  120. ];
  121. $data['views']['action_links_area'] = [
  122. 'title' => t('Action Links'),
  123. 'help' => t('Add action links to the view.'),
  124. 'area' => [
  125. 'handler' => 'tripal_views_handler_area_action_links',
  126. ],
  127. ];
  128. $tvi_query = db_query('SELECT * FROM {tripal_views}');
  129. // INTEGRATE THE LIGHTEST SETUP FOR EACH TABLE
  130. foreach ($tvi_query as $tvi_row) {
  131. // check to see if this is the lightest (drupal-style) priority setup for this table
  132. // if not then don't use this definition
  133. $lightest_priority_setup = tripal_is_lightest_priority_setup($tvi_row->setup_id, $tvi_row->table_name);
  134. if (!$lightest_priority_setup) {
  135. continue;
  136. }
  137. // ids we'll use for queries
  138. $setup_id = $tvi_row->setup_id;
  139. $mview_id = $tvi_row->mview_id;
  140. // holds the base table name and fields
  141. $base_table = '';
  142. $base_fields = [];
  143. // indicated whether the current table is a base table or not
  144. $is_base_table = $tvi_row->base_table;
  145. // POPULATE THE BASE TABLE NAME AND FIELDS
  146. // If an $mview_id is given then get the materialized view info,
  147. // otherwise get the Chado table info
  148. $legacy_mview = FALSE;
  149. if ($mview_id) {
  150. // get the base table name from the materialized view
  151. // D7 TODO: Check DBTNG changes work
  152. $sql = "SELECT name, mv_specs FROM {tripal_mviews} WHERE mview_id = :id";
  153. $mview_table = db_query($sql, [':id' => $mview_id]);
  154. $mview_table = $mview_table->fetchObject();
  155. if ($mview_table) {
  156. $base_table = $mview_table->name;
  157. if (!empty($mview_table->mv_specs)) {
  158. $legacy_mview = TRUE;
  159. }
  160. }
  161. else {
  162. continue;
  163. }
  164. }
  165. if ($legacy_mview) {
  166. // get the columns in this materialized view. They are separated by commas
  167. // where the first word is the column name and the rest is the type
  168. $columns = explode(",", $mview_table->mv_specs);
  169. foreach ($columns as $column) {
  170. $column = trim($column); // trim trailing and leading spaces
  171. preg_match("/^(.*?)\ (.*?)$/", $column, $matches);
  172. $column_name = $matches[1];
  173. $column_type = $matches[2];
  174. $base_fields[$column_name] = [
  175. 'column_name' => $column_name,
  176. 'type' => $column_type,
  177. ];
  178. }
  179. // get the field name and descriptions
  180. // D7 TODO: Check DBTNG changes work
  181. $sql = "SELECT * FROM {tripal_views_field} WHERE setup_id=:setup";
  182. $query = db_query($sql, [':setup' => $setup_id]);
  183. foreach ($query as $field) {
  184. $base_fields[$field->column_name]['name'] = $field->name;
  185. $base_fields[$field->column_name]['help'] = $field->description;
  186. }
  187. }
  188. // if this is not a legacy materialized view
  189. else {
  190. $base_table = $tvi_row->table_name;
  191. // get the table description
  192. $table_desc = chado_get_schema($base_table);
  193. $fields = $table_desc['fields'];
  194. if (!is_array($fields)) {
  195. $fields = [];
  196. }
  197. foreach ($fields as $column => $attrs) {
  198. $base_fields[$column] = [
  199. 'column_name' => $column,
  200. // Add a default for type since module developers may sometimes need to use a
  201. // PostgreSQL-specific type.
  202. 'type' => (isset($attrs['type'])) ? $attrs['type'] : 'text',
  203. ];
  204. // If PostgreSQL-specifc types are needed the module developer should be given
  205. // a way to set the most closely matching type for views. They should also be
  206. // allowed to override the type for views. This can be done by adding a views_type
  207. // to the schema definition :-).
  208. if (isset($attrs['views_type'])) {
  209. $base_fields[$column]['type'] = $attrs['views_type'];
  210. }
  211. // Tell admin about this feature and warn them that we made an assumption for them.
  212. if (!isset($attrs['type']) AND !isset($attrs['views_type'])) {
  213. tripal_report_error(
  214. 'tripal_views',
  215. TRIPAL_WARNING,
  216. "Unable to determine the type for %column thus we have defaulted to type 'text'.
  217. Tip: This may be due to setting a postgresql-specific type. Solution: Add a
  218. 'views_type' to your schema definition to specify what type should be used.",
  219. ['%column' => $column]
  220. );
  221. }
  222. }
  223. // get the field name and descriptions
  224. $sql = "SELECT * FROM {tripal_views_field} WHERE setup_id=:setup";
  225. $query = db_query($sql, [':setup' => $setup_id]);
  226. foreach ($query as $field) {
  227. $base_fields[$field->column_name]['name'] = $field->name;
  228. $base_fields[$field->column_name]['help'] = $field->description;
  229. }
  230. }
  231. // SETUP THE BASE TABLE INFO IN THE DATA ARRAY
  232. $data[$base_table]['table']['group'] = t("$tvi_row->name");
  233. if ($is_base_table) {
  234. $data[$base_table]['table']['base'] = [
  235. 'group' => "$tvi_row->name",
  236. 'title' => "$tvi_row->name",
  237. 'help' => $tvi_row->comment,
  238. 'search_path' => $chado_schema,
  239. ];
  240. }
  241. else {
  242. $data[$base_table]['table'] = [
  243. 'group' => "$tvi_row->name",
  244. 'title' => "$tvi_row->name",
  245. 'help' => $tvi_row->comment,
  246. 'search_path' => $chado_schema,
  247. ];
  248. }
  249. // ADD THE FIELDS TO THE DATA ARRAY
  250. foreach ($base_fields as $column_name => $base_field) {
  251. if (!isset($base_field['name'])) {
  252. $data[$base_table][$column_name] = [
  253. 'title' => t($column_name),
  254. 'help' => t($column_name),
  255. 'field' => [
  256. 'click sortable' => TRUE,
  257. ],
  258. ];
  259. tripal_report_error(
  260. 'tripal_chado_views',
  261. TRIPAL_DEBUG,
  262. "The name and help were not set for %table.%column. As a consequence the column
  263. name has been used... You should ensure that the 'name' and 'help' keys for
  264. this field are set in the integration array (priority = %priority)",
  265. [
  266. '%table' => $base_table,
  267. '%column' => $column_name,
  268. '%priority' => $tvi_row->priority,
  269. ]
  270. );
  271. }
  272. else {
  273. $data[$base_table][$column_name] = [
  274. 'title' => t($base_field['name']),
  275. 'help' => t($base_field['help']),
  276. 'field' => [
  277. 'click sortable' => TRUE,
  278. ],
  279. ];
  280. }
  281. // now add the handlers
  282. $sql = "SELECT * FROM {tripal_views_handlers} WHERE setup_id = :setup AND column_name = :column";
  283. $handlers = db_query($sql, [
  284. ':setup' => $setup_id,
  285. ':column' => $column_name,
  286. ]);
  287. $num_handlers = 0;
  288. foreach ($handlers as $handler) {
  289. $num_handlers++;
  290. $data[$base_table][$column_name][$handler->handler_type]['handler'] = $handler->handler_name;
  291. // Add in any additional arguments
  292. // This should be a serialized array including (at a minimum) name => <handler name>
  293. if ($handler->arguments) {
  294. $data[$base_table][$column_name][$handler->handler_type] = array_merge($data[$base_table][$column_name][$handler->handler_type], unserialize($handler->arguments));
  295. }
  296. };
  297. // If there were no handlers applied to the current field then warn the administrator!
  298. if ($num_handlers == 0) {
  299. tripal_report_error(
  300. 'tripal_chado_views',
  301. TRIPAL_DEBUG,
  302. "No handlers were registered for %table.%column. This means there is no views
  303. functionality for this column. To register handlers, make sure the 'handlers'
  304. key for this field is set in the integration array (priority = %priority).
  305. The supported keys include 'field', 'filter', 'sort', 'relationship'. Look
  306. at the tripal_add_views_integration() for additional details.",
  307. [
  308. '%table' => $base_table,
  309. '%column' => $column_name,
  310. '%priority' => $tvi_row->priority,
  311. ]
  312. );
  313. }
  314. }
  315. // ADD JOINS & RELATIONSHIPS TO DATA ARRAY
  316. // only add joins if this is a base table
  317. // this keeps the list of available fields manageable
  318. // all other tables should be added via relationships
  319. $sql = "SELECT * FROM {tripal_views_join} WHERE setup_id = :setup";
  320. $joins = db_query($sql, [':setup' => $setup_id]);
  321. if (!isset($joins)) {
  322. $joins = [];
  323. }
  324. foreach ($joins as $join) {
  325. $left_table = $join->left_table;
  326. $left_field = $join->left_field;
  327. $base_table = $join->base_table;
  328. $base_field = $join->base_field;
  329. $handler = $join->handler;
  330. $base_title = ucwords(str_replace('_', ' ', $base_table));
  331. $left_title = ucwords(str_replace('_', ' ', $left_table));
  332. // if the 'node' table is in our integrated list then
  333. // we want to skip it. It shouldn't be there.
  334. if ($left_table == 'node') {
  335. continue;
  336. }
  337. // add join entry
  338. if (!$join->relationship_only) {
  339. $data[$left_table]['table']['join'][$base_table] = [
  340. 'left_field' => $base_field,
  341. 'field' => $left_field,
  342. ];
  343. if ($handler) {
  344. $data[$left_table]['table']['join'][$base_table]['handler'] = $handler;
  345. }
  346. if (!empty($join->arguments)) {
  347. array_merge($data[$left_table]['table']['join'][$base_table], unserialize($join->arguments));
  348. }
  349. }
  350. // warn if deprecated method of relationship addition was used (ie: through handlers)
  351. if (isset($data[$base_table][$base_field]['relationship'])) {
  352. tripal_report_error('tripal_chado_views', TRIPAL_NOTICE,
  353. 'DEPRECATED: Currently using tripal_views_handlers to store relationship for %base => %left when you should be using tripal_views_joins.',
  354. ['%base' => $base_table, '%left' => $left_table]);
  355. }
  356. // Add relationship entry.
  357. // NOTE: we use a fake field name to allow us to have multiple
  358. // relationships for the same field (ie: feature.feature_id has many
  359. // Many relationships but views only supports a single one).
  360. $fake_field = $base_field . '_to_' . $left_table;
  361. // Bug Fix: The old $fake_field used above doesn't take into account
  362. // multiple relationships to the same left table. To keep backwards
  363. // compatibility, this old fake_field needs to continue to be used for
  364. // the LAST recorded relationship. However, for all previously set
  365. // relationships we can use an improved fake name which takes into
  366. // account the left field and ensures all relationships for a single
  367. // left table are not condensed into a single relationship.
  368. if (array_key_exists($fake_field, $data[$base_table])) {
  369. // Again, note that we can't just change the fake_name after finding
  370. // there is more than one relationship because then the FIRST
  371. // relationship would keep the old fake_name rather than the LAST
  372. // which keeps backwards compatiblity since the old naming caused all
  373. // previous relationships be be overridden by the next one.
  374. // Thus we first need to determine the left field of the previous
  375. // join for this table combination and then use that to form our
  376. // improved fake field.
  377. $previous_left_field = $data[$base_table][$fake_field]['relationship']['base field'];
  378. $improved_fake_field = $base_field . '_to_' . $left_table . "." . $previous_left_field;
  379. $data[$base_table][$improved_fake_field] = $data[$base_table][$fake_field];
  380. }
  381. $data[$base_table][$fake_field] = [
  382. 'title' => "$base_title.$base_field => $left_title.$left_field",
  383. 'help' => t("Joins @base to @left", [
  384. '@base' => "$base_title.$base_field",
  385. '@left' => "$left_title.$left_field",
  386. ]),
  387. 'relationship' => [
  388. 'handler' => $join->relationship_handler,
  389. 'title' => t("$base_field => $left_title ($left_field)"),
  390. 'label' => t("$base_field => $left_title ($left_field)"),
  391. 'real field' => $base_field,
  392. 'base' => $left_table,
  393. 'base field' => $left_field,
  394. ],
  395. ];
  396. if (!empty($join->arguments)) {
  397. array_merge($data[$base_table][$fake_field]['relationship'], unserialize($join->arguments));
  398. }
  399. }
  400. }
  401. return $data;
  402. }
  403. /**
  404. * Describes the tripal views integration tables to views for the
  405. * administration views
  406. *
  407. * @ingroup tripal_chado_views
  408. */
  409. function tripal_chado_views_views_data_tripal_views_tables($data) {
  410. $data['tripal_views']['table']['group'] = t('Chado Views Integration');
  411. $data['tripal_views']['table']['base'] = [
  412. 'field' => 'setup_id', // This is the identifier field for the view.
  413. 'title' => t('Chado Views Integration'),
  414. 'help' => t('Specifications on how to integrate various tables with Drupal Views'),
  415. 'weight' => -10,
  416. ];
  417. // Implicit Join to Materialized Views
  418. $data['tripal_views']['table']['join'] = [
  419. 'tripal_mviews' => [
  420. 'left_field' => 'mview_id',
  421. 'field' => 'mview_id',
  422. ],
  423. ];
  424. // setup_id
  425. $data['tripal_views']['setup_id'] = [
  426. 'title' => t('Setup ID'),
  427. 'help' => t('Primary key of the integration'),
  428. 'field' => [
  429. 'handler' => 'views_handler_field_numeric',
  430. 'click sortable' => TRUE,
  431. ],
  432. 'filter' => [
  433. 'handler' => 'views_handler_filter_numeric',
  434. ],
  435. 'sort' => [
  436. 'handler' => 'views_handler_sort',
  437. ],
  438. ];
  439. // mview_id
  440. $data['tripal_views']['mview_id'] = [
  441. 'title' => t('Materialized View ID'),
  442. 'help' => t('The primary key of the Mview integrated.'),
  443. 'field' => [
  444. 'handler' => 'views_handler_field_numeric',
  445. 'click sortable' => TRUE,
  446. ],
  447. 'filter' => [
  448. 'handler' => 'views_handler_filter_numeric',
  449. ],
  450. 'sort' => [
  451. 'handler' => 'views_handler_sort',
  452. ],
  453. ];
  454. // base_table
  455. $data['tripal_views']['base_table'] = [
  456. 'title' => t('Base Table?'),
  457. 'help' => t('Whether the table being integrated should be considered a base table.'),
  458. 'field' => [
  459. 'handler' => 'views_handler_field_boolean',
  460. 'click sortable' => TRUE,
  461. ],
  462. 'filter' => [
  463. 'handler' => 'views_handler_filter_boolean_operator',
  464. 'label' => t('Base Table?'),
  465. 'type' => 'yes-no',
  466. 'use equal' => TRUE,
  467. ],
  468. 'sort' => [
  469. 'handler' => 'views_handler_sort',
  470. ],
  471. ];
  472. // table_name
  473. $data['tripal_views']['table_name'] = [
  474. 'title' => t('Chado Table Name'),
  475. 'help' => t('The name of the table being integrated'),
  476. 'field' => [
  477. 'handler' => 'views_handler_field',
  478. 'click sortable' => TRUE, // This is use by the table display plugin.
  479. ],
  480. 'sort' => [
  481. 'handler' => 'views_handler_sort',
  482. ],
  483. 'filter' => [
  484. 'handler' => 'views_handler_filter_string',
  485. ],
  486. 'argument' => [
  487. 'handler' => 'views_handler_argument_string',
  488. ],
  489. ];
  490. // priority
  491. $data['tripal_views']['priority'] = [
  492. 'title' => t('Priority'),
  493. 'help' => t('The priority of the integration.'),
  494. 'field' => [
  495. 'handler' => 'views_handler_field_numeric',
  496. 'click sortable' => TRUE,
  497. ],
  498. 'filter' => [
  499. 'handler' => 'views_handler_filter_numeric',
  500. ],
  501. 'sort' => [
  502. 'handler' => 'views_handler_sort',
  503. ],
  504. ];
  505. // name
  506. $data['tripal_views']['name'] = [
  507. 'title' => t('Name'),
  508. 'help' => t('The name of the integration'),
  509. 'field' => [
  510. 'handler' => 'views_handler_field',
  511. 'click sortable' => TRUE, // This is use by the table display plugin.
  512. ],
  513. 'sort' => [
  514. 'handler' => 'views_handler_sort',
  515. ],
  516. 'filter' => [
  517. 'handler' => 'views_handler_filter_string',
  518. ],
  519. 'argument' => [
  520. 'handler' => 'views_handler_argument_string',
  521. ],
  522. ];
  523. // comment
  524. $data['tripal_views']['comment'] = [
  525. 'title' => t('Description'),
  526. 'help' => t('Short description or comment about this integration.'),
  527. 'field' => [
  528. 'handler' => 'views_handler_field',
  529. 'click sortable' => TRUE, // This is use by the table display plugin.
  530. ],
  531. 'sort' => [
  532. 'handler' => 'views_handler_sort',
  533. ],
  534. 'filter' => [
  535. 'handler' => 'views_handler_filter_string',
  536. ],
  537. 'argument' => [
  538. 'handler' => 'views_handler_argument_string',
  539. ],
  540. ];
  541. return $data;
  542. }
  543. /**
  544. * Implements hook_views_data_alter().
  545. * Used to add Chado <-> Node Joins & Relationships
  546. * since you need to add to the $data['node'] to do this
  547. *
  548. * @see https://api.drupal.org/api/views/views.api.php/function/hook_views_data/7.x-3.x
  549. *
  550. * @ingroup tripal_chado_views
  551. */
  552. function tripal_chado_views_views_data_alter(&$data) {
  553. // ADD IN ENTITIES JOINS & RELATIONSHIPS
  554. // D7 @todo: Create custom handler to allow join from Entity => Base (ie: organism)
  555. // with the addition of a single relationship
  556. // D7 @todo: Create custom handler to allow join from Base (ie: organism)
  557. // with the addition of a single relationship
  558. // D7 @todo: Add support for Mview <-> Entity joins and relationships
  559. $bundle_query = db_select('chado_bundle', 'CB');
  560. $bundle_query->fields('CB', array('bundle_id', 'data_table'));
  561. $bundle_query->join('tripal_bundle', 'TB', 'CB.bundle_id = TB.id');
  562. $bundle_query->fields('TB', array('name', 'label'));
  563. $bundle_query->join('tripal_term', 'TT', 'TB.term_id = TT.id');
  564. $bundle_query->fields('TT', array('accession'));
  565. $bundle_query->join('tripal_vocab', 'TV', 'TT.vocab_id = TV.id');
  566. $bundle_query->fields('TV', array('vocabulary'));
  567. $bundles = $bundle_query->execute();
  568. // Look for the record ID in the appropriate chado table.
  569. foreach ($bundles as $bundle) {
  570. // Ids we'll use for queries.
  571. // Ex.: 'stock'.
  572. $base_table = $bundle->data_table;
  573. // Ex.: 'stock_id'.
  574. $base_id_field = $base_table . '_id';
  575. // Ex.:'Chado Stock'.
  576. $base_table_label = 'Chado ' . ucwords(str_replace('_', ' ', $base_table));
  577. // Ex.: 'chado_bio_data_21'.
  578. $linker_table = 'chado_' . $bundle->name;
  579. // Ex.: 'Germplasm Accession'
  580. $bundle_label = $bundle->label;
  581. // Ex.: 'CO_010__0000044'
  582. $bundle_internal_name = $bundle->vocabulary . '__' . $bundle->accession;
  583. // Add in joins to the tripal_entity tables if the Chado schema is local.
  584. $is_local = isset($GLOBALS["chado_is_local"]) && $GLOBALS["chado_is_local"];
  585. if ($is_local) {
  586. if (db_table_exists($linker_table)) {
  587. // Adds in a chado base table => entity relationship.
  588. // This allows controlled joining to multiple entities per line.
  589. // Use Case: link to feature and organism entities on a feature listing.
  590. // D7 todo: a custom relationship handler to get from feature.organism_id => organism node
  591. // without 1st needing to add relationship to organism table.
  592. $data[$linker_table]['table']['join'][$base_table] = array(
  593. 'left_field' => $base_id_field,
  594. 'field' => 'record_id',
  595. );
  596. $data[$linker_table]['table']['join']['tripal_entity'] = array(
  597. 'left_field' => 'id',
  598. 'field' => 'entity_id',
  599. );
  600. $data[$linker_table][$base_id_field] = array(
  601. 'group' => $base_table_label,
  602. 'title' => $base_table_label,
  603. 'help' => t(
  604. "Links @base_table_label to its Tripal Content Type '@bundle_label'.",
  605. array(
  606. '@base_table_label' => $base_table_label,
  607. '@bundle_label' => $bundle_label,
  608. )
  609. ),
  610. 'relationship' => array(
  611. 'handler' => 'views_handler_relationship',
  612. 'title' => t(
  613. "@base_table_label => @bundle_label",
  614. array(
  615. '@base_table_label' => $base_table_label,
  616. '@bundle_label' => $bundle_label,
  617. )
  618. ),
  619. 'label' => t(
  620. "@base_table_label => @bundle_label",
  621. array(
  622. '@base_table_label' => $base_table_label,
  623. '@bundle_label' => $bundle_label,
  624. )
  625. ),
  626. 'real field' => 'entity_id',
  627. 'base' => 'tripal_entity',
  628. 'base field' => 'id'
  629. ),
  630. );
  631. // Add Chado fields to a entity-based view
  632. // This will only be done with relationships.
  633. $data[$bundle_internal_name][$base_id_field] = array(
  634. 'group' => $bundle_label,
  635. 'title' => $bundle_label,
  636. 'help' => t(
  637. "Links @bundle_label to @base_table_label.",
  638. array(
  639. '@bundle_label' => $bundle_label,
  640. '@base_table_label' => $base_table_label,
  641. )
  642. ),
  643. 'relationship' => array(
  644. 'handler' => 'views_handler_relationship',
  645. 'title' => t(
  646. "@bundle_label => @base_table_label",
  647. array(
  648. '@bundle_label' => $bundle_label,
  649. '@base_table_label' => $base_table_label,
  650. )
  651. ),
  652. 'label' => t(
  653. "@bundle_label => @base_table_label",
  654. array(
  655. '@bundle_label' => $bundle_label,
  656. '@base_table_label' => $base_table_label,
  657. )
  658. ),
  659. 'real field' => 'id',
  660. 'base' => $base_table,
  661. 'base field' => $base_id_field
  662. ),
  663. );
  664. }
  665. }
  666. }
  667. return $data;
  668. }
  669. /**
  670. * Implementation of hook_views_pre_view().
  671. *
  672. * Merge the $_GET and $_POST into the $_GET. This is because
  673. * Views and Views Data Export modules only uses the $_GET variable but
  674. * file uploads require $_POST. We need to make sure these two modules
  675. * have access to everything needed for this view to work properly.
  676. *
  677. * @ingroup tripal_chado_views
  678. */
  679. function tripal_chado_views_views_pre_view(&$view, &$display_id, &$args) {
  680. $_GET = array_merge($_GET, $_POST);
  681. }