protected function SearchApiDbService::createFilterCondition in Search API Database Search 7
Creates a database query condition for a given search filter.
Used as a helper method in createDbQuery().
Parameters
SearchApiQueryFilterInterface $filter: The filter for which a condition should be created.
array $fields: Internal information about the index's fields.
SelectQueryInterface $db_query: The database query to which the condition will be added.
SearchApiIndex $index: (optional) The search index whose settings should be used.
Return value
DatabaseCondition|null The condition to set on the query, or NULL if none is necessary.
Throws
SearchApiException If an unknown field was used in the filter.
1 call to SearchApiDbService::createFilterCondition()
- SearchApiDbService::createDbQuery in ./
service.inc - Creates a database query for a search.
File
- ./
service.inc, line 1699 - Contains SearchApiDbService.
Class
- SearchApiDbService
- Indexes and searches items using the database.
Code
protected function createFilterCondition(SearchApiQueryFilterInterface $filter, array $fields, SelectQueryInterface $db_query, SearchApiIndex $index = NULL) {
$cond = db_condition($filter
->getConjunction());
// Store whether a JOIN already occurred for a field, so we don't JOIN
// repeatedly for OR filters.
$first_join = array();
// Store the table aliases for the fields in this condition group.
$tables = array();
foreach ($filter
->getFilters() as $f) {
if (is_object($f)) {
$c = $this
->createFilterCondition($f, $fields, $db_query, $index);
if ($c) {
$cond
->condition($c);
}
}
else {
list($field, $value, $operator) = $f;
if (!isset($fields[$field])) {
throw new SearchApiException(t('Unknown field in filter clause: @field.', array(
'@field' => $field,
)));
}
$field_info = $fields[$field];
$not_between = $operator === 'NOT BETWEEN';
$not_equals = $not_between || $operator === '<>' || $operator === '!=';
$text_type = search_api_is_text_type($field_info['type']);
// If the field is in its own table, we have to check for NULL values in
// a special way (i.e., check for missing entries in that table).
if ($value === NULL && ($field_info['column'] === 'value' || $text_type)) {
$query = $this->connection
->select($field_info['table'], 't')
->fields('t', array(
'item_id',
));
if ($text_type) {
$query
->condition('t.field_name', $field);
}
$cond
->condition('t.item_id', $query, $not_equals ? 'IN' : 'NOT IN');
continue;
}
if ($text_type) {
if (!isset($tokenizer_active)) {
$tokenizer_active = $index && static::isTokenizerActive($index);
}
$keys = $this
->prepareKeys($value, $tokenizer_active);
if (!isset($keys)) {
continue;
}
$query = $this
->createKeysQuery($keys, array(
$field => $field_info,
), $fields);
// We only want the item IDs, so we use the keys query as a nested query.
$query = $this->connection
->select($query, 't')
->fields('t', array(
'item_id',
));
$cond
->condition('t.item_id', $query, $not_equals ? 'NOT IN' : 'IN');
}
else {
$new_join = search_api_is_list_type($field_info['type']) && ($filter
->getConjunction() == 'AND' || empty($first_join[$field]));
if ($new_join || empty($tables[$field])) {
$tables[$field] = $this
->getTableAlias($field_info, $db_query, $new_join);
$first_join[$field] = TRUE;
}
$column = $tables[$field] . '.' . $field_info['column'];
if ($value === NULL) {
$method = $operator == '=' ? 'isNull' : 'isNotNull';
$cond
->{$method}($column);
}
elseif ($not_equals && search_api_is_list_type($field_info['type'])) {
// The situation is more complicated for multi-valued fields, since
// we must make sure that results are excluded if ANY of the field's
// values equals the one given in this condition.
$sub_operator = $not_between ? 'BETWEEN' : '=';
$query = $this->connection
->select($field_info['table'], 't')
->fields('t', array(
'item_id',
))
->condition($field_info['column'], $value, $sub_operator);
$cond
->condition('t.item_id', $query, 'NOT IN');
}
elseif ($not_between) {
$cond
->where("{$column} NOT BETWEEN {$value[0]} AND {$value[1]}");
}
else {
$cond
->condition($column, $value, $operator);
}
}
}
}
return count($cond
->conditions()) > 1 ? $cond : NULL;
}