handler_filter_fulltext.inc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. <?php
  2. /**
  3. * Views filter handler class for handling fulltext fields.
  4. */
  5. class SearchApiViewsHandlerFilterFulltext extends SearchApiViewsHandlerFilterText {
  6. /**
  7. * Specify the options this filter uses.
  8. */
  9. public function option_definition() {
  10. $options = parent::option_definition();
  11. $options['mode'] = array('default' => 'keys');
  12. $options['fields'] = array('default' => array());
  13. return $options;
  14. }
  15. /**
  16. * Extend the options form a bit.
  17. */
  18. public function options_form(&$form, &$form_state) {
  19. parent::options_form($form, $form_state);
  20. $form['mode'] = array(
  21. '#title' => t('Use as'),
  22. '#type' => 'radios',
  23. '#options' => array(
  24. 'keys' => t('Search keys – multiple words will be split and the filter will influence relevance.'),
  25. 'filter' => t("Search filter – use as a single phrase that restricts the result set but doesn't influence relevance."),
  26. ),
  27. '#default_value' => $this->options['mode'],
  28. );
  29. $fields = $this->getFulltextFields();
  30. if (!empty($fields)) {
  31. $form['fields'] = array(
  32. '#type' => 'select',
  33. '#title' => t('Searched fields'),
  34. '#description' => t('Select the fields that will be searched. If no fields are selected, all available fulltext fields will be searched.'),
  35. '#options' => $fields,
  36. '#size' => min(4, count($fields)),
  37. '#multiple' => TRUE,
  38. '#default_value' => $this->options['fields'],
  39. );
  40. }
  41. else {
  42. $form['fields'] = array(
  43. '#type' => 'value',
  44. '#value' => array(),
  45. );
  46. }
  47. if (isset($form['expose'])) {
  48. $form['expose']['#weight'] = -5;
  49. }
  50. }
  51. /**
  52. * Add this filter to the query.
  53. */
  54. public function query() {
  55. while (is_array($this->value)) {
  56. $this->value = $this->value ? reset($this->value) : '';
  57. }
  58. // Catch empty strings entered by the user, but not "0".
  59. if ($this->value === '') {
  60. return;
  61. }
  62. $fields = $this->options['fields'];
  63. $fields = $fields ? $fields : array_keys($this->getFulltextFields());
  64. // If something already specifically set different fields, we silently fall
  65. // back to mere filtering.
  66. $filter = $this->options['mode'] == 'filter';
  67. if (!$filter) {
  68. $old = $this->query->getFields();
  69. $filter = $old && (array_diff($old, $fields) || array_diff($fields, $old));
  70. }
  71. if ($filter) {
  72. $filter = $this->query->createFilter('OR');
  73. foreach ($fields as $field) {
  74. $filter->condition($field, $this->value, $this->operator);
  75. }
  76. $this->query->filter($filter);
  77. return;
  78. }
  79. $this->query->fields($fields);
  80. $old = $this->query->getOriginalKeys();
  81. $this->query->keys($this->value);
  82. if ($this->operator != '=') {
  83. $keys = &$this->query->getKeys();
  84. if (is_array($keys)) {
  85. $keys['#negation'] = TRUE;
  86. }
  87. else {
  88. // We can't know how negation is expressed in the server's syntax.
  89. }
  90. }
  91. if ($old) {
  92. $keys = &$this->query->getKeys();
  93. if (is_array($keys)) {
  94. $keys[] = $old;
  95. }
  96. elseif (is_array($old)) {
  97. // We don't support such nonsense.
  98. }
  99. else {
  100. $keys = "($old) ($keys)";
  101. }
  102. }
  103. }
  104. /**
  105. * Helper method to get an option list of all available fulltext fields.
  106. */
  107. protected function getFulltextFields() {
  108. $fields = array();
  109. $index = search_api_index_load(substr($this->table, 17));
  110. if (!empty($index->options['fields'])) {
  111. $f = $index->getFields();
  112. foreach ($index->getFulltextFields() as $name) {
  113. $fields[$name] = $f[$name]['name'];
  114. }
  115. }
  116. return $fields;
  117. }
  118. }