tripal_views_handler_filter_select_cvterm.inc

  1. 2.x tripal_views/views/handlers/tripal_views_handler_filter_select_cvterm.inc
  2. 3.x tripal_chado_views/views/handlers/tripal_views_handler_filter_select_cvterm.inc
  3. 1.x tripal_views/views/handlers/tripal_views_handler_filter_select_cvterm.inc

Contains tripal_views_handler_filter_select_cvterm

File

tripal_views/views/handlers/tripal_views_handler_filter_select_cvterm.inc
View source
  1. <?php
  2. /**
  3. * @file
  4. * Contains tripal_views_handler_filter_select_cvterm
  5. */
  6. /**
  7. * This Handler provides a select list for the type field
  8. *
  9. * NOTE: This handler only works when applied to the type_id field in the
  10. * base_table of the view.
  11. *
  12. * @ingroup tripal_views
  13. */
  14. class tripal_views_handler_filter_select_cvterm extends tripal_views_handler_filter_select_string {
  15. /**
  16. * {@inheritdoc}
  17. */
  18. /**
  19. * Provide the options used in the select list.
  20. * Override this function in extended handlers to easily change option list.
  21. *
  22. * @return
  23. * An array of options where the key is the value of this field in the
  24. * database
  25. */
  26. function get_select_options() {
  27. // If the admin has set the "Show All" option then we want to show all the
  28. // cvterms regardless of whether they are used in the base table or not.
  29. if (isset($this->options['show_all']) AND $this->options['show_all'] == TRUE) {
  30. // Get a list of cvs currently used.
  31. // If the filter is for a field in the cvterm table (weird, I know but
  32. // we can't assume that tripal admin won't do this) then we only need
  33. // to make one-hop to the cv table.
  34. if ($this->table == 'cvterm') {
  35. $return = $this->get_select_option_where($this->table);
  36. $where_clauses = $return['where_clauses'];
  37. $arguments = $return['arguments'];
  38. $base_where = '';
  39. if (!empty($where_clauses)) {
  40. $base_where = implode(' AND ', $where_clauses);
  41. }
  42. // Using a "Loose Index Scan" to get a list of all the cvs used
  43. // in the cvterm table (ie: all the cv's with at least one term).
  44. // See https://wiki.postgresql.org/wiki/Loose_indexscan
  45. $sql = "
  46. WITH RECURSIVE t AS (
  47. SELECT MIN(cv_id) AS col FROM {!table}
  48. " . ($base_where == '' ? '' : "WHERE " . $base_where) . "
  49. UNION ALL
  50. SELECT (SELECT MIN(cv_id) FROM {!table} WHERE cv_id > col " . ($base_where == '' ? '' : " AND " . $base_where) . ")
  51. FROM t WHERE col IS NOT NULL
  52. )
  53. SELECT cv_id, name
  54. FROM {cv}
  55. WHERE cv_id IN (SELECT col FROM t where col IS NOT NULL)
  56. ORDER BY cv.name ASC";
  57. $sql = format_string($sql, array('!table' => $this->table));
  58. }
  59. // Otherwise, (most often the case) we need to make two-hops
  60. // to the cv table through the cvterm table.
  61. else {
  62. // There are actually two sets of conditions we care about and of course
  63. // they are placed in different places in the query :p.
  64. // 1. Restrictions on the cvterm table. This lets users specify: only
  65. // show these exact types.
  66. $return = $this->get_select_option_where('cvterm');
  67. $where_clauses = $return['where_clauses'];
  68. $cvterm_args = $return['arguments'];
  69. $cvterm_where = '';
  70. if (!empty($where_clauses)) {
  71. $cvterm_where = implode(' AND ', $where_clauses);
  72. }
  73. // 2. Restrictions on the filter table Since those affect which types
  74. // have been used.
  75. $return = $this->get_select_option_where($this->table);
  76. $where_clauses = $return['where_clauses'];
  77. $base_args = $return['arguments'];
  78. $base_where = '';
  79. if (!empty($where_clauses)) {
  80. $base_where = implode(' AND ', $where_clauses);
  81. }
  82. // We only supply one set or arguments those so merge the two.
  83. $arguments = array_merge($cvterm_args, $base_args);
  84. // Using a "Loose Index Scan" to get a list of all the cvs used
  85. // in the table the drop-down filter is from.
  86. // See https://wiki.postgresql.org/wiki/Loose_indexscan
  87. $sql = "
  88. WITH RECURSIVE t AS (
  89. SELECT MIN(cvterm.cv_id) AS col
  90. FROM {!table} filter_table
  91. LEFT JOIN {cvterm} ON filter_table.!field=cvterm.cvterm_id
  92. " . ($base_where == '' ? '' : "WHERE " . $base_where) . "
  93. UNION ALL
  94. SELECT (
  95. SELECT MIN(cv_id)
  96. FROM {!table} filter_table
  97. LEFT JOIN {cvterm} ON filter_table.!field=cvterm.cvterm_id
  98. WHERE cv_id > col " . ($base_where == '' ? '' : " AND " . $base_where) . "
  99. )
  100. FROM t WHERE col IS NOT NULL
  101. )
  102. SELECT cvterm_id, name
  103. FROM {cvterm}
  104. WHERE cv_id IN (SELECT col FROM t where col IS NOT NULL) " . ($cvterm_where == '' ? '' : " AND " . $cvterm_where) . "
  105. ORDER BY cvterm.name ASC";
  106. $sql = format_string($sql, array('!table' => $this->table, '!field' => $this->field));
  107. }
  108. $resource = chado_query($sql, $arguments);
  109. // Now actually gerenate the select list
  110. // based on the results from the above query.
  111. $cvterms = array();
  112. foreach ($resource as $r) {
  113. $cvterms[$r->cvterm_id] = $r->name;
  114. }
  115. }
  116. // Otherwise, show the user the much smaller list of all cvterms used in
  117. // the base table.
  118. else {
  119. // There are actually two sets of conditions we care about and of course
  120. // they are placed in different places in the query :p.
  121. // 1. Restrictions on the cvterm table. This lets users specify: only
  122. // show these exact types.
  123. $return = $this->get_select_option_where('cvterm');
  124. $where_clauses = $return['where_clauses'];
  125. $cvterm_args = $return['arguments'];
  126. $cvterm_where = '';
  127. if (!empty($where_clauses)) {
  128. $cvterm_where = implode(' AND ', $where_clauses);
  129. }
  130. // 2. Restrictions on the filter table Since those affect which types
  131. // have been used.
  132. $return = $this->get_select_option_where($this->table);
  133. $where_clauses = $return['where_clauses'];
  134. $base_args = $return['arguments'];
  135. $base_where = '';
  136. if (!empty($where_clauses)) {
  137. $base_where = implode(' AND ', $where_clauses);
  138. }
  139. // We only supply one set or arguments those so merge the two.
  140. $arguments = array_merge($cvterm_args, $base_args);
  141. // Using a "Loose Index Scan" to get a list of all the cvterms used
  142. // in the base table. See https://wiki.postgresql.org/wiki/Loose_indexscan
  143. $sql = "
  144. WITH RECURSIVE t AS (
  145. SELECT MIN(!field) AS col FROM {!table}
  146. " . ($base_where == '' ? '' : "WHERE " . $base_where) . "
  147. UNION ALL
  148. SELECT (
  149. SELECT MIN(!field)
  150. FROM {!table}
  151. WHERE !field > col " . ($base_where == '' ? '' : " AND " . $base_where) . "
  152. )
  153. FROM t WHERE col IS NOT NULL
  154. )
  155. SELECT cvterm_id, name
  156. FROM {cvterm}
  157. WHERE cvterm_id IN (SELECT col FROM t where col IS NOT NULL) " . ($cvterm_where == '' ? '' : " AND " . $cvterm_where) . "
  158. ORDER BY cvterm.name ASC";
  159. $sql = format_string($sql, array('!table' => $this->table, '!field' => $this->field));
  160. $resource = chado_query($sql, $arguments);
  161. $cvterms = array();
  162. // Add an "- Any - " option to allow a type to not be set by default.
  163. if ($this->options['select_optional']) {
  164. $cvterms['All'] = '- Any -';
  165. }
  166. // Now actually gerenate the select list
  167. // based on the results from the above query.
  168. foreach ($resource as $r) {
  169. $cvterms[$r->cvterm_id] = $r->name;
  170. }
  171. }
  172. return $cvterms;
  173. }
  174. /**
  175. * For the SQL generating the options, determine the WHERE clauses
  176. *
  177. * @return
  178. * An array of full qualified where clauses (ie: table.myfield = 'fred')
  179. */
  180. function get_select_option_where($table = NULL, $generic_placeholder = TRUE) {
  181. return parent::get_select_option_where($table, $generic_placeholder);
  182. }
  183. /*
  184. // build a where clause that will filter the list in the drop box
  185. // using fields that are not exposed and that are for the table
  186. // from whcih the values in the drop box will be slected and
  187. // we only want to use non-exposed fields because these are not
  188. // available to the user to edit--they're fixed.
  189. $filters = (is_array($this->view->filter)) ? $this->view->filter : array();
  190. foreach ($filters as $filter_name => $details) {
  191. // we only want to inclue non-exposed filters
  192. if ($details->options['exposed'] == FALSE) {
  193. $value = $details->value;
  194. if (is_array($details->value) AND isset($details->value['value'])) {
  195. $value = $details->value['value'];
  196. }
  197. $field = $details->field;
  198. if (($this->table == $this->view->base_table) AND ($details->field == 'type_id')) {
  199. $field = 'cvterm_id';
  200. }
  201. if (is_array($value)) {
  202. // we only want to filter on the table we're getting the list from
  203. if (strcmp($details->table, $this->table)==0 AND !empty($value)) {
  204. $where[] = "$field IN (" . implode(', ', $value) . ')';
  205. }
  206. }
  207. else {
  208. // we only want to filter on the table we're getting the list from
  209. if (strcmp($details->table, 'cvterm')==0 AND !empty($value)) {
  210. $where[] = "$field $details->operator " . $value;
  211. }
  212. }
  213. }
  214. }
  215. return $where;
  216. }
  217. */
  218. /**
  219. * {@inheritdoc}
  220. */
  221. function option_definition() {
  222. return parent::option_definition();
  223. }
  224. /**
  225. * {@inheritdoc}
  226. */
  227. function expose_form(&$form, &$form_state) {
  228. parent::expose_form($form, $form_state);
  229. return $form;
  230. }
  231. /**
  232. * {@inheritdoc}
  233. */
  234. function expose_submit($form, &$form_state) {
  235. parent::expose_submit($form, $form_state);
  236. }
  237. /**
  238. * {@inheritdoc}
  239. */
  240. function expose_options() {
  241. parent::expose_options();
  242. }
  243. /**
  244. * {@inheritdoc}
  245. */
  246. function value_form(&$form, &$form_state) {
  247. parent::value_form($form, $form_state);
  248. }
  249. }