views_handler_filter_combine.inc 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <?php
  2. /**
  3. * @file
  4. * Definition of views_handler_filter_combine.
  5. */
  6. /**
  7. * Filter handler which allows to search on multiple fields.
  8. *
  9. * @ingroup views_field_handlers
  10. */
  11. class views_handler_filter_combine extends views_handler_filter_string {
  12. /**
  13. * @var views_plugin_query_default
  14. */
  15. public $query;
  16. /**
  17. * {@inheritdoc}
  18. */
  19. public function option_definition() {
  20. $options = parent::option_definition();
  21. $options['fields'] = array('default' => array());
  22. return $options;
  23. }
  24. /**
  25. * {@inheritdoc}
  26. */
  27. public function options_form(&$form, &$form_state) {
  28. parent::options_form($form, $form_state);
  29. $this->view->init_style();
  30. // Allow to choose all fields as possible.
  31. if ($this->view->style_plugin->uses_fields()) {
  32. $options = array();
  33. foreach ($this->view->display_handler->get_handlers('field') as $name => $field) {
  34. $options[$name] = $field->ui_name(TRUE);
  35. }
  36. if ($options) {
  37. $form['fields'] = array(
  38. '#type' => 'select',
  39. '#title' => t('Choose fields to combine for filtering'),
  40. '#description' => t("This filter doesn't work for very special field handlers."),
  41. '#multiple' => TRUE,
  42. '#options' => $options,
  43. '#default_value' => $this->options['fields'],
  44. );
  45. }
  46. else {
  47. form_set_error('', t('You have to add some fields to be able to use this filter.'));
  48. }
  49. }
  50. }
  51. /**
  52. * {@inheritdoc}
  53. */
  54. public function query() {
  55. $this->view->_build('field');
  56. $fields = array();
  57. // Only add the fields if they have a proper field and table alias.
  58. foreach ($this->options['fields'] as $id) {
  59. // Field access checks may have removed this handler.
  60. if (!isset($this->view->field[$id])) {
  61. continue;
  62. }
  63. $field = $this->view->field[$id];
  64. // Always add the table of the selected fields to be sure a table alias
  65. // exists.
  66. $field->ensure_my_table();
  67. if (!empty($field->table_alias) && !empty($field->real_field)) {
  68. $fields[] = "$field->table_alias.$field->real_field";
  69. }
  70. }
  71. if ($fields) {
  72. $count = count($fields);
  73. $separated_fields = array();
  74. foreach ($fields as $key => $field) {
  75. $separated_fields[] = $field;
  76. if ($key < $count - 1) {
  77. $separated_fields[] = "' '";
  78. }
  79. }
  80. $expression = implode(', ', $separated_fields);
  81. $expression = "CONCAT_WS(' ', $expression)";
  82. $info = $this->operators();
  83. if (!empty($info[$this->operator]['method'])) {
  84. $this->{$info[$this->operator]['method']}($expression);
  85. }
  86. }
  87. }
  88. /**
  89. * By default things like op_equal uses add_where, that doesn't support
  90. * complex expressions, so override all operators.
  91. */
  92. public function op_equal($field) {
  93. $placeholder = $this->placeholder();
  94. $operator = $this->operator();
  95. $this->query->add_where_expression($this->options['group'], "$field $operator $placeholder", array($placeholder => $this->value));
  96. }
  97. /**
  98. *
  99. */
  100. public function op_contains($field) {
  101. $placeholder = $this->placeholder();
  102. $this->query->add_where_expression($this->options['group'], "$field LIKE $placeholder", array($placeholder => '%' . db_like($this->value) . '%'));
  103. }
  104. /**
  105. *
  106. */
  107. public function op_word($field) {
  108. $where = $this->operator == 'word' ? db_or() : db_and();
  109. // Don't filter on empty strings.
  110. if (empty($this->value)) {
  111. return;
  112. }
  113. preg_match_all('/ (-?)("[^"]+"|[^" ]+)/i', ' ' . $this->value, $matches, PREG_SET_ORDER);
  114. foreach ($matches as $match) {
  115. $phrase = FALSE;
  116. // Strip off phrase quotes.
  117. if ($match[2]{0} == '"') {
  118. $match[2] = substr($match[2], 1, -1);
  119. $phrase = TRUE;
  120. }
  121. $words = trim($match[2], ',?!();:-');
  122. $words = $phrase ? array($words) : preg_split('/ /', $words, -1, PREG_SPLIT_NO_EMPTY);
  123. $placeholder = $this->placeholder();
  124. foreach ($words as $word) {
  125. $where->where($field . " LIKE $placeholder", array($placeholder => '%' . db_like(trim($word, " ,!?")) . '%'));
  126. }
  127. }
  128. if (!$where) {
  129. return;
  130. }
  131. // Previously this was a call_user_func_array() but that's unnecessary
  132. // as views will unpack an array that is a single arg.
  133. $this->query->add_where($this->options['group'], $where);
  134. }
  135. /**
  136. *
  137. */
  138. public function op_starts($field) {
  139. $placeholder = $this->placeholder();
  140. $this->query->add_where_expression($this->options['group'], "$field LIKE $placeholder", array($placeholder => db_like($this->value) . '%'));
  141. }
  142. /**
  143. *
  144. */
  145. public function op_not_starts($field) {
  146. $placeholder = $this->placeholder();
  147. $this->query->add_where_expression($this->options['group'], "$field NOT LIKE $placeholder", array($placeholder => db_like($this->value) . '%'));
  148. }
  149. /**
  150. *
  151. */
  152. public function op_ends($field) {
  153. $placeholder = $this->placeholder();
  154. $this->query->add_where_expression($this->options['group'], "$field LIKE $placeholder", array($placeholder => '%' . db_like($this->value)));
  155. }
  156. /**
  157. *
  158. */
  159. public function op_not_ends($field) {
  160. $placeholder = $this->placeholder();
  161. $this->query->add_where_expression($this->options['group'], "$field NOT LIKE $placeholder", array($placeholder => '%' . db_like($this->value)));
  162. }
  163. /**
  164. *
  165. */
  166. public function op_not($field) {
  167. $placeholder = $this->placeholder();
  168. $this->query->add_where_expression($this->options['group'], "$field NOT LIKE $placeholder", array($placeholder => '%' . db_like($this->value) . '%'));
  169. }
  170. /**
  171. *
  172. */
  173. public function op_regex($field) {
  174. $placeholder = $this->placeholder();
  175. $this->query->add_where_expression($this->options['group'], "$field RLIKE $placeholder", array($placeholder => $this->value));
  176. }
  177. /**
  178. *
  179. */
  180. public function op_not_regex($field) {
  181. $placeholder = $this->placeholder();
  182. $this->query->add_where_expression($this->options['group'], "$field NOT RLIKE $placeholder", array($placeholder => $this->value));
  183. }
  184. /**
  185. *
  186. */
  187. public function op_empty($field) {
  188. if ($this->operator == 'empty') {
  189. $operator = "IS NULL";
  190. }
  191. else {
  192. $operator = "IS NOT NULL";
  193. }
  194. $this->query->add_where_expression($this->options['group'], "$field $operator");
  195. }
  196. }