views_handler_join_chado_through_linking.inc 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <?php
  2. module_load_include('inc', 'views', 'includes/base');
  3. module_load_include('inc', 'views', 'includes/handlers');
  4. /**
  5. * @file
  6. * Handler to allow joins between records via a linking table
  7. *
  8. * Example Usage:
  9. * To join the analysis table to the feature table through the analysisfeature table,
  10. * (ie: get analysis fields to show up in a feature view)
  11. * Use the following code in the analysis hook_views_data:
  12. * @code
  13. $data['analysis']['table']['join']['feature'] = array(
  14. 'linking' => array(
  15. 'table' => 'analysisfeature',
  16. 'left_field' => 'feature_id',
  17. 'field' => 'analysis_id',
  18. ),
  19. 'left_field' => 'feature_id',
  20. 'field' => 'analysis_id',
  21. 'handler' => 'views_handler_join_chado_through_linking'
  22. );
  23. * @endcode
  24. *
  25. * NOTE: If the right table is in the drupal schema rather then the chado schema
  26. * (ie: node, chado_feature) then add the following to the above join description:
  27. * @code
  28. 'table_is_drupal' => TRUE
  29. * @endcode
  30. * This will ensure the drupal table is surrounded by { } and as such any database
  31. * prefixes are added correctly. If the left table is in the drupal schema it should already
  32. * be defined by a previous join (or the From clause).
  33. */
  34. class views_handler_join_chado_through_linking extends views_join {
  35. // PHP 4 doesn't call constructors of the base class automatically from a
  36. // constructor of a derived class. It is your responsibility to propagate
  37. // the call to constructors upstream where appropriate.
  38. function construct($table = NULL, $left_table = NULL, $left_field = NULL, $field = NULL, $extra = array(), $type = 'LEFT', $added = NULL) {
  39. parent::construct($table, $left_table, $left_field, $field, $extra, $type);
  40. }
  41. /**
  42. * Creates SQL for both joins table => linking_table and linking_table => left_table
  43. * NOTE: Uses fields in definition as passed in from hook_views_data join definition
  44. */
  45. function join($table, &$query) {
  46. $output = '';
  47. $joins = array();
  48. $joins[] = $this->create_single_join(
  49. $query,
  50. array(
  51. 'table' => $this->definition['linking']['table'],
  52. 'field' => $this->definition['linking']['left_field'],
  53. 'is_drupal' => FALSE,
  54. ),
  55. array(
  56. 'table' => $this->definition['left_table'],
  57. 'field' => $this->definition['left_field'],
  58. ),
  59. 'LEFT'
  60. );
  61. $joins[] = $this->create_single_join(
  62. $query,
  63. array(
  64. 'table' => $this->definition['table'],
  65. 'field' => $this->definition['field'],
  66. 'is_drupal' => $this->definition['table_is_drupal'],
  67. ),
  68. array(
  69. 'table' => $this->definition['linking']['table'],
  70. 'field' => $this->definition['linking']['field'],
  71. ),
  72. 'LEFT'
  73. );
  74. $output .= implode("\n", $joins);
  75. return $output;
  76. }
  77. /**
  78. * Creates SQL for a single join based on parameters
  79. */
  80. function create_single_join(&$query, $right_spec, $left_spec, $join_type) {
  81. if ($right_spec['table']) {
  82. $right = $query->get_table_info($right_spec['table']);
  83. if (!$right['alias']) {
  84. $right['alias'] = $right_spec['table'];
  85. }
  86. $right_field = "$right[alias].$right_spec[field]";
  87. if ($right_spec['is_drupal']) {
  88. $right_table = '{' . $right_spec['table'] . '}';
  89. }
  90. else {
  91. $right_table = $right_spec['table'];
  92. }
  93. }
  94. if ($left_spec['table']) {
  95. $left = $query->get_table_info($left_spec['table']);
  96. if (!$left['alias']) {
  97. $left['alias'] = $left_spec['table'];
  98. }
  99. $left_field = "$left[alias].$left_spec[field]";
  100. }
  101. else {
  102. // This can be used if left_field is a formula or something. It should be used only *very* rarely.
  103. $left_field = $this->left_spec['field'];
  104. }
  105. $output = " $join_type JOIN $right_table $right[alias] ON $left_field = $right_field";
  106. return $output;
  107. }
  108. }