views_handler_filter_boolean_operator.inc 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. <?php
  2. /**
  3. * @file
  4. * Definition of views_handler_filter_boolean_operator.
  5. */
  6. /**
  7. * Simple filter to handle matching of boolean values
  8. *
  9. * Definition items:
  10. * - label: (REQUIRED) The label for the checkbox.
  11. * - type: For basic 'true false' types, an item can specify the following:
  12. * - true-false: True/false (this is the default)
  13. * - yes-no: Yes/No
  14. * - on-off: On/Off
  15. * - enabled-disabled: Enabled/Disabled
  16. * - accept null: Treat a NULL value as false.
  17. * - use equal: If you use this flag the query will use = 1 instead of <> 0.
  18. * This might be helpful for performance reasons.
  19. *
  20. * @ingroup views_filter_handlers
  21. */
  22. class views_handler_filter_boolean_operator extends views_handler_filter {
  23. /**
  24. * Exposed filter options.
  25. */
  26. public $always_multiple = TRUE;
  27. /**
  28. * Don't display empty space where the operator would be.
  29. */
  30. public $no_operator = TRUE;
  31. /**
  32. * Whether to accept NULL as a false value or not.
  33. */
  34. public $accept_null = FALSE;
  35. /**
  36. * {@inheritdoc}
  37. */
  38. public function construct() {
  39. $this->value_value = t('True');
  40. if (isset($this->definition['label'])) {
  41. $this->value_value = $this->definition['label'];
  42. }
  43. if (isset($this->definition['accept null'])) {
  44. $this->accept_null = (bool) $this->definition['accept null'];
  45. }
  46. elseif (isset($this->definition['accept_null'])) {
  47. $this->accept_null = (bool) $this->definition['accept_null'];
  48. }
  49. $this->value_options = NULL;
  50. parent::construct();
  51. }
  52. /**
  53. * Return the possible options for this filter.
  54. *
  55. * Child classes should override this function to set the possible values
  56. * for the filter. Since this is a boolean filter, the array should have
  57. * two possible keys: 1 for "True" and 0 for "False", although the labels
  58. * can be whatever makes sense for the filter. These values are used for
  59. * configuring the filter, when the filter is exposed, and in the admin
  60. * summary of the filter. Normally, this should be static data, but if it's
  61. * dynamic for some reason, child classes should use a guard to reduce
  62. * database hits as much as possible.
  63. */
  64. public function get_value_options() {
  65. if (isset($this->definition['type'])) {
  66. if ($this->definition['type'] == 'yes-no') {
  67. $this->value_options = array(1 => t('Yes'), 0 => t('No'));
  68. }
  69. if ($this->definition['type'] == 'on-off') {
  70. $this->value_options = array(1 => t('On'), 0 => t('Off'));
  71. }
  72. if ($this->definition['type'] == 'enabled-disabled') {
  73. $this->value_options = array(1 => t('Enabled'), 0 => t('Disabled'));
  74. }
  75. }
  76. // Provide a fallback if the above didn't set anything.
  77. if (!isset($this->value_options)) {
  78. $this->value_options = array(1 => t('True'), 0 => t('False'));
  79. }
  80. }
  81. /**
  82. * {@inheritdoc}
  83. */
  84. public function option_definition() {
  85. $options = parent::option_definition();
  86. $options['value']['default'] = FALSE;
  87. return $options;
  88. }
  89. /**
  90. * {@inheritdoc}
  91. */
  92. public function operator_form(&$form, &$form_state) {
  93. $form['operator'] = array();
  94. }
  95. /**
  96. * {@inheritdoc}
  97. */
  98. public function value_form(&$form, &$form_state) {
  99. if (empty($this->value_options)) {
  100. // Initialize the array of possible values for this filter.
  101. $this->get_value_options();
  102. }
  103. if (!empty($form_state['exposed'])) {
  104. // Exposed filter: use a select box to save space.
  105. $filter_form_type = 'select';
  106. }
  107. else {
  108. // Configuring a filter: use radios for clarity.
  109. $filter_form_type = 'radios';
  110. }
  111. $form['value'] = array(
  112. '#type' => $filter_form_type,
  113. '#title' => $this->value_value,
  114. '#options' => $this->value_options,
  115. '#default_value' => $this->value,
  116. );
  117. if (!empty($this->options['exposed'])) {
  118. $identifier = $this->options['expose']['identifier'];
  119. if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) {
  120. $form_state['input'][$identifier] = $this->value;
  121. }
  122. // If we're configuring an exposed filter, add an <Any> option.
  123. if (empty($form_state['exposed']) || empty($this->options['expose']['required'])) {
  124. $any_label = variable_get('views_exposed_filter_any_label', 'new_any') == 'old_any' ? '<Any>' : t('- Any -');
  125. if ($form['value']['#type'] != 'select') {
  126. $any_label = check_plain($any_label);
  127. }
  128. $form['value']['#options'] = array('All' => $any_label) + $form['value']['#options'];
  129. }
  130. }
  131. }
  132. /**
  133. * {@inheritdoc}
  134. */
  135. public function value_validate($form, &$form_state) {
  136. if ($form_state['values']['options']['value'] == 'All' && !empty($form_state['values']['options']['expose']['required'])) {
  137. form_set_error('value', t('You must select a value unless this is an non-required exposed filter.'));
  138. }
  139. }
  140. /**
  141. * {@inheritdoc}
  142. */
  143. public function admin_summary() {
  144. if ($this->is_a_group()) {
  145. return t('grouped');
  146. }
  147. if (!empty($this->options['exposed'])) {
  148. return t('exposed');
  149. }
  150. if (empty($this->value_options)) {
  151. $this->get_value_options();
  152. }
  153. // Now that we have the valid options for this filter, just return the
  154. // human-readable label based on the current value. The value_options
  155. // array is keyed with either 0 or 1, so if the current value is not
  156. // empty, use the label for 1, and if it's empty, use the label for 0.
  157. return $this->value_options[!empty($this->value)];
  158. }
  159. /**
  160. * {@inheritdoc}
  161. */
  162. public function expose_options() {
  163. parent::expose_options();
  164. $this->options['expose']['operator_id'] = '';
  165. $this->options['expose']['label'] = $this->value_value;
  166. $this->options['expose']['required'] = TRUE;
  167. }
  168. /**
  169. * {@inheritdoc}
  170. */
  171. public function query() {
  172. $this->ensure_my_table();
  173. $field = "$this->table_alias.$this->real_field";
  174. if (empty($this->value)) {
  175. if ($this->accept_null) {
  176. $or = db_or()
  177. ->condition($field, 0, '=')
  178. ->condition($field, NULL, 'IS NULL');
  179. $this->query->add_where($this->options['group'], $or);
  180. }
  181. else {
  182. $this->query->add_where($this->options['group'], $field, 0, '=');
  183. }
  184. }
  185. else {
  186. if (!empty($this->definition['use equal'])) {
  187. $this->query->add_where($this->options['group'], $field, 1, '=');
  188. }
  189. else {
  190. $this->query->add_where($this->options['group'], $field, 0, '<>');
  191. }
  192. }
  193. }
  194. }