diff --git includes/processor.inc includes/processor.inc index e1745e5..ed7b2ff 100644 --- includes/processor.inc +++ includes/processor.inc @@ -136,12 +136,38 @@ abstract class SearchApiAbstractProcessor implements SearchApiProcessorInterface } public function configurationForm() { - return array(); + $form['#attached']['css'][] = drupal_get_path('module', 'search_api') . '/search_api.admin.css'; + + $fields = empty($this->index->options['fields']) ? _search_api_admin_get_fields($this->index, $this->index->entityWrapper()) : $this->index->options; + $fields = $fields['fields']; + $field_options = array(); + $default_fields = isset($this->options['fields']) ? $this->options['fields'] : array(); + foreach ($fields as $name => $field) { + if ($field['indexed']) { + $field_options[$name] = $field['name']; + if (!isset($this->options['fields']) && $this->testField($name, $field)) { + $default_fields[$name] = $name; + } + } + } + + $form['fields'] = array( + '#type' => 'checkboxes', + '#title' => t('Fields to run on'), + '#options' => $field_options, + '#default_value' => $default_fields, + '#attributes' => array('class' => array('search-api-processor-fields')), + ); + + return $form; } public function configurationFormValidate(array $form, array &$values, array &$form_state) { } public function configurationFormSubmit(array $form, array &$values, array &$form_state) { + if (isset($values['fields'])) { + $values['fields'] = array_filter($values['fields']); + } $this->options = $values; return $values; } @@ -298,7 +324,10 @@ abstract class SearchApiAbstractProcessor implements SearchApiProcessorInterface * TRUE, iff the field should be processed. */ protected function testField($name, array $field) { - return $this->testType($field['type']); + if (empty($this->options['fields'])) { + return $this->testType($field['type']); + } + return !empty($this->options['fields'][$name]); } /** diff --git includes/processor_html_filter.inc includes/processor_html_filter.inc index 9974ace..205723a 100644 --- includes/processor_html_filter.inc +++ includes/processor_html_filter.inc @@ -31,7 +31,8 @@ class SearchApiHtmlFilter extends SearchApiAbstractProcessor { } public function configurationForm() { - $form = array( + $form = parent::configurationForm(); + $form += array( 'title' => array( '#type' => 'checkbox', '#title' => t('Index title attribute'), diff --git includes/processor_ignore_case.inc includes/processor_ignore_case.inc index 1f046cf..fd5d7e9 100644 --- includes/processor_ignore_case.inc +++ includes/processor_ignore_case.inc @@ -5,30 +5,6 @@ */ class SearchApiIgnoreCase extends SearchApiAbstractProcessor { - public function configurationForm() { - $form = array( - 'strings' => array( - '#type' => 'checkbox', - '#title' => t('Process strings'), - '#description' => t('Determines whether this processor will process string fields, too.'), - ), - ); - - if (!empty($this->options)) { - $form['strings']['#default_value'] = $this->options['strings']; - } - - return $form; - } - - public function testType($type) { - $allowed = array('text', 'tokens'); - if (!empty($this->options['strings'])) { - $allowed[] = 'string'; - } - return search_api_is_text_type($type, $allowed);; - } - protected function process(&$value) { $value = drupal_strtolower($value); } diff --git includes/processor_tokenizer.inc includes/processor_tokenizer.inc index bd445d6..f635ed1 100644 --- includes/processor_tokenizer.inc +++ includes/processor_tokenizer.inc @@ -17,7 +17,8 @@ class SearchApiTokenizer extends SearchApiAbstractProcessor { protected $ignorable; public function configurationForm() { - $form = array( + $form = parent::configurationForm(); + $form += array( 'spaces' => array( '#type' => 'textfield', '#title' => t('Whitespace characters'), diff --git search_api.admin.css search_api.admin.css index 63eb0ea..2141cd0 100644 --- search_api.admin.css +++ search_api.admin.css @@ -34,7 +34,8 @@ input.search-api-cron-limit { text-align: right; } -.search-api-alter-add-aggregation-fields { +.search-api-alter-add-aggregation-fields, +.search-api-processor-fields { max-height: 12em; overflow: auto; } diff --git search_api.install search_api.install index 3b180ca..a1d5908 100644 --- search_api.install +++ search_api.install @@ -678,3 +678,44 @@ function search_api_update_7106() { } } } + +/** + * Initialize the "Fields to run on" settings for processors. + */ +function search_api_update_7107() { + $rows = db_select('search_api_index', 'i') + ->fields('i', array('id', 'options')) + ->execute() + ->fetchAllKeyed(); + foreach ($rows as $id => $options) { + $opt = unserialize($options); + $processors = &$opt['processors']; + // Only update our own processors, don't mess with others. + $check_processors = array( + 'search_api_case_ignore' => 1, + 'search_api_html_filter' => 1, + 'search_api_tokenizer' => 1, + ); + foreach (array_intersect_key($processors, $check_processors) as $name => $info) { + $types = array('text'); + if (!empty($info['settings']['strings'])) { + $types[] = 'string'; + unset($processors[$name]['settings']['strings']); + } + foreach ($opt['fields'] as $field => $info) { + if ($info['indexed'] && search_api_is_text_type($info['type'], $types)) { + $processors[$name]['settings']['fields'][$field] = $field; + } + } + } + $opt = serialize($opt); + if ($opt != $options) { + db_update('search_api_index') + ->fields(array( + 'options' => $opt, + )) + ->condition('id', $id) + ->execute(); + } + } +} diff --git search_api.test search_api.test index 88d4fa8..3ba65a1 100644 --- search_api.test +++ search_api.test @@ -184,11 +184,18 @@ class SearchApiWebTest extends DrupalWebTestCase { 'callbacks[search_api_alter_add_aggregation][weight]' => 10, 'processors[search_api_case_ignore][status]' => 1, 'processors[search_api_case_ignore][weight]' => 0, - 'processors[search_api_case_ignore][settings][strings]' => 0, + 'processors[search_api_case_ignore][settings][fields][title]' => 1, + 'processors[search_api_case_ignore][settings][fields][body]' => 1, + 'processors[search_api_case_ignore][settings][fields][parent:title]' => 1, + 'processors[search_api_case_ignore][settings][fields][parent:body]' => 1, 'processors[search_api_tokenizer][status]' => 1, 'processors[search_api_tokenizer][weight]' => 20, 'processors[search_api_tokenizer][settings][spaces]' => '[^\p{L}\p{N}]', 'processors[search_api_tokenizer][settings][ignorable]' => '[-]', + 'processors[search_api_tokenizer][settings][fields][title]' => 1, + 'processors[search_api_tokenizer][settings][fields][body]' => 1, + 'processors[search_api_tokenizer][settings][fields][parent:title]' => 1, + 'processors[search_api_tokenizer][settings][fields][parent:body]' => 1, ); $this->drupalPost(NULL, $values, t('Add new field')); $values = array( @@ -473,7 +480,7 @@ class SearchApiUnitTest extends DrupalWebTestCase { public function checkIgnoreCaseProcessor() { $types = search_api_field_types(); $orig = 'Foo bar BaZ, ÄÖÜÀÁ<>»«.'; - $processed = 'foo bar baz, äöüàá<>»«.'; + $processed = drupal_strtolower($orig); $items = array( 1 => array( 'name' => array( @@ -508,11 +515,11 @@ class SearchApiUnitTest extends DrupalWebTestCase { array('mail', 'bar', '='), ); - $processor = new SearchApiIgnoreCase($this->index, array('strings' => FALSE)); + $processor = new SearchApiIgnoreCase($this->index, array('fields' => array('name' => 'name'))); $tmp = $items; $processor->preprocessIndexItems($tmp); - $this->assertEqual($tmp[1]['name']['value'], $processed, t('!type field was processed.', array('!type' => $types['text']))); - $this->assertEqual($tmp[1]['mail']['value'], $orig, t("!type field wasn't processed.", array('!type' => $types['string']))); + $this->assertEqual($tmp[1]['name']['value'], $processed, t('!type field was processed.', array('!type' => 'name'))); + $this->assertEqual($tmp[1]['mail']['value'], $orig, t("!type field wasn't processed.", array('!type' => 'mail'))); $query = new SearchApiQuery($this->index); $query->keys('Foo "baR BaZ" fOObAr1'); @@ -522,11 +529,11 @@ class SearchApiUnitTest extends DrupalWebTestCase { $this->assertEqual($query->getKeys(), $keys1, t('Search keys were processed correctly.')); $this->assertEqual($query->getFilter()->getFilters(), $filters1, t('Filters were processed correctly.')); - $processor = new SearchApiIgnoreCase($this->index, array('strings' => TRUE)); + $processor = new SearchApiIgnoreCase($this->index, array('fields' => array('name' => 'name', 'mail' => 'mail'))); $tmp = $items; $processor->preprocessIndexItems($tmp); - $this->assertEqual($tmp[1]['name']['value'], $processed, t('!type field was processed.', array('!type' => $types['text']))); - $this->assertEqual($tmp[1]['mail']['value'], $processed, t('!type field was processed.', array('!type' => $types['string']))); + $this->assertEqual($tmp[1]['name']['value'], $processed, t('!type field was processed.', array('!type' => 'name'))); + $this->assertEqual($tmp[1]['mail']['value'], $processed, t('!type field was processed.', array('!type' => 'mail'))); $query = new SearchApiQuery($this->index); $query->keys('Foo "baR BaZ" fOObAr1'); @@ -598,7 +605,7 @@ class SearchApiUnitTest extends DrupalWebTestCase { ), ); - $processor = new SearchApiTokenizer($this->index, array('spaces' => '[^\p{L}\p{N}]', 'ignorable' => '[-]')); + $processor = new SearchApiTokenizer($this->index, array('fields' => array('name' => 'name'), 'spaces' => '[^\p{L}\p{N}]', 'ignorable' => '[-]')); $tmp = $items; $processor->preprocessIndexItems($tmp); $this->assertEqual($tmp[1]['name']['value'], $processed1, t('Value was correctly tokenized with default settings.')); @@ -608,7 +615,7 @@ class SearchApiUnitTest extends DrupalWebTestCase { $processor->preprocessSearchQuery($query); $this->assertEqual($query->getKeys(), 'foo barbaz foobar1', t('Search keys were processed correctly.')); - $processor = new SearchApiTokenizer($this->index, array('spaces' => '[-a]', 'ignorable' => '\s')); + $processor = new SearchApiTokenizer($this->index, array('fields' => array('name' => 'name'), 'spaces' => '[-a]', 'ignorable' => '\s')); $tmp = $items; $processor->preprocessIndexItems($tmp); $this->assertEqual($tmp[1]['name']['value'], $processed2, t('Value was correctly tokenized with custom settings.')); @@ -677,9 +684,9 @@ END; ); $tmp = $items; - $processor = new SearchApiHtmlFilter($this->index, array('title' => TRUE, 'alt' => TRUE, 'tags' => $tags)); + $processor = new SearchApiHtmlFilter($this->index, array('fields' => array('name' => 'name'), 'title' => TRUE, 'alt' => TRUE, 'tags' => $tags)); $processor->preprocessIndexItems($tmp); - $processor = new SearchApiTokenizer($this->index, array('spaces' => '[\s.:]', 'ignorable' => '')); + $processor = new SearchApiTokenizer($this->index, array('fields' => array('name' => 'name'), 'spaces' => '[\s.:]', 'ignorable' => '')); $processor->preprocessIndexItems($tmp); $this->assertEqual($tmp[1]['name']['value'], $processed1, t('Text was correctly processed.')); }