entity_views_handler_relationship_by_bundle.inc 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. <?php
  2. /**
  3. * @file
  4. * Contains the entity_views_handler_relationship_by_bundle class.
  5. */
  6. /**
  7. * Relationship handler for entity relationships that may limit the join to one or more bundles.
  8. *
  9. * This handler is only applicable for entities that are using bundle entities,
  10. * i.e. entities having the 'bundle of' entity info key set.
  11. *
  12. * For example, this allows a relationship from users to profiles of a certain
  13. * profile type.
  14. *
  15. * @see entity_crud_hook_entity_info()
  16. * @ingroup views_field_handlers
  17. */
  18. class entity_views_handler_relationship_by_bundle extends views_handler_relationship {
  19. function option_definition() {
  20. $options = parent::option_definition();
  21. $options['bundle_types'] = array('default' => array());
  22. return $options;
  23. }
  24. /**
  25. * Add an entity type option.
  26. */
  27. function options_form(&$form, &$form_state) {
  28. parent::options_form($form, $form_state);
  29. // Get the entity type and info from the table data for the base on the
  30. // right hand side of the relationship join.
  31. $table_data = views_fetch_data($this->definition['base']);
  32. $entity_type = $table_data['table']['entity type'];
  33. $entity_info = entity_get_info($entity_type);
  34. // Get the info of the bundle entity.
  35. foreach (entity_get_info() as $type => $info) {
  36. if (isset($info['bundle of']) && $info['bundle of'] == $entity_type) {
  37. $entity_bundle_info = $info;
  38. break;
  39. }
  40. }
  41. $plural_label = isset($entity_bundle_info['plural label']) ? $entity_bundle_info['plural label'] : $entity_bundle_info['label'] . 's';
  42. $bundle_options = array();
  43. foreach ($entity_info['bundles'] as $name => $info) {
  44. $bundle_options[$name] = $info['label'];
  45. }
  46. $form['bundle_types'] = array(
  47. '#title' => $plural_label,
  48. '#type' => 'checkboxes',
  49. '#description' => t('Restrict this relationship to one or more @bundles.', array('@bundles' => strtolower($entity_bundle_info['plural label']))),
  50. '#options' => $bundle_options,
  51. '#default_value' => $this->options['bundle_types'],
  52. );
  53. }
  54. /**
  55. * Make sure only checked bundle types are left.
  56. */
  57. function options_submit(&$form, &$form_state) {
  58. $form_state['values']['options']['bundle_types'] = array_filter($form_state['values']['options']['bundle_types']);
  59. parent::options_submit($form, $form_state);
  60. }
  61. /**
  62. * Called to implement a relationship in a query.
  63. *
  64. * Mostly the same as the parent method, except we add an extra clause to
  65. * the join.
  66. */
  67. function query() {
  68. $table_data = views_fetch_data($this->definition['base']);
  69. $base_field = empty($this->definition['base field']) ? $table_data['table']['base']['field'] : $this->definition['base field'];
  70. $this->ensure_my_table();
  71. $def = $this->definition;
  72. $def['table'] = $this->definition['base'];
  73. $def['field'] = $base_field;
  74. $def['left_table'] = $this->table_alias;
  75. $def['left_field'] = $this->field;
  76. if (!empty($this->options['required'])) {
  77. $def['type'] = 'INNER';
  78. }
  79. // Add an extra clause to the join if there are bundle types selected.
  80. if ($this->options['bundle_types']) {
  81. $entity_info = entity_get_info($table_data['table']['entity type']);
  82. $def['extra'] = array(
  83. array(
  84. // The table and the IN operator are implicit.
  85. 'field' => $entity_info['entity keys']['bundle'],
  86. 'value' => $this->options['bundle_types'],
  87. ),
  88. );
  89. }
  90. if (!empty($def['join_handler']) && class_exists($def['join_handler'])) {
  91. $join = new $def['join_handler'];
  92. }
  93. else {
  94. $join = new views_join();
  95. }
  96. $join->definition = $def;
  97. $join->construct();
  98. $join->adjusted = TRUE;
  99. // Use a short alias for this.
  100. $alias = $def['table'] . '_' . $this->table;
  101. $this->alias = $this->query->add_relationship($alias, $join, $this->definition['base'], $this->relationship);
  102. }
  103. }