OR в Drupal View Filters
Мне нужно реализовать оператор OR между некоторыми фильтрами в представлении Drupal.
По умолчанию Drupal И каждый фильтр вместе.
Используя
hook_views_query_alter(&$view, &$query)
Я могу получить доступ к запросу (var $query), и я могу изменить либо:
$query->where[0]['type']
до 'OR' или
$query->group_operator
в 'OR'
Однако проблема заключается в том, что мне не нужно ИЛИ всюду. Я попытался изменить оба из них на OR отдельно, и это не дает желаемого результата.
Кажется, меняют эти значения, помещает ИЛИ всюду, в то время как мне нужно = > (фильтр 1 И фильтр 2) ИЛИ (фильтр 3), поэтому просто 1 ИЛИ.
Я мог бы просто проверить Query of the View, скопировать его, изменить его и запустить через db_query, но это просто грязно..
Любые предложения?
спасибо заранее.
Ответы
Ответ 1
если вы хотите сделать это с помощью hook_view_query_alter, вы должны использовать $query- > add_where(), где вы можете указать, является ли это AND или OR. Из представлений /include/query.inc
/**
* Add a simple WHERE clause to the query. The caller is responsible for
* ensuring that all fields are fully qualified (TABLE.FIELD) and that
* the table already exists in the query.
*
* @param $group
* The WHERE group to add these to; groups are used to create AND/OR
* sections. Groups cannot be nested. Use 0 as the default group.
* If the group does not yet exist it will be created as an AND group.
* @param $clause
* The actual clause to add. When adding a where clause it is important
* that all tables are addressed by the alias provided by add_table or
* ensure_table and that all fields are addressed by their alias wehn
* possible. Please use %d and %s for arguments.
* @param ...
* A number of arguments as used in db_query(). May be many args or one
* array full of args.
*/
function add_where($group, $clause)
Ответ 2
Если вы используете Views 3/Drupal 7 и ищете ответ на этот вопрос, он испекает прямо в Views. Где он говорит "добавить" рядом с фильтрами, нажмите раскрывающийся список, затем нажмите "и/или перестроить". Это должно быть очевидно оттуда.
Ответ 3
К сожалению, это пока отсутствует в Views2. Он уже давно задан, и ему обещали некоторое время назад, но, похоже, это сложная работа и теперь запланировано для Views3.
Тем временем вы можете попробовать Views или модуль, упомянутый в этом потоке. На сегодняшний день он по-прежнему находится в статусе dev, но, похоже, активно поддерживается, и очередь ответов не выглядит плохой, поэтому вы можете захотеть чтобы попробовать.
Ответ 4
Я добавил его путем конкатенации строки.
Это относительно специфично для реализации - людям нужно будет играть с полем для соответствия для OR - node.title в следующем коде и поле для его соответствия - node_revisions.body в этом случае.
Дополнительный фрагмент кода, чтобы убедиться, что node_revisions.body находится в запросе.
/**
* Implementation of hook_views_api().
*/
function eventsor_views_api() { // your module name into hook_views_api
return array(
'api' => 2,
// might not need the line below, but in any case, the last arg is the name of your module
'path' => drupal_get_path('module', 'eventsor'),
);
}
/**
*
* @param string $form
* @param type $form_state
* @param type $form_id
*/
function eventsor_views_query_alter(&$view, &$query) {
switch ($view->name) {
case 'Events':
_eventsor_composite_filter($query);
break;
}
}
/**
* Add to the where clause.
* @param type $query
*/
function _eventsor_composite_filter(&$query) {
// If we see "UPPER(node.title) LIKE UPPER('%%%s%%')" - then add and to it.
if (isset($query->where)) {
$where_count = 0;
foreach ($query->where as $where) {
$clause_count = 0;
if (isset($where['clauses'])) {
foreach ($where['clauses'] as $clause) {
$search_where_clause = "UPPER(node.title) LIKE UPPER('%%%s%%')";
// node_data_field_long_description.field_long_description_value
$desirable_where_clause = "UPPER(CONCAT_WS(' ', node.title, node_revisions.body)) LIKE UPPER('%%%s%%')";
if ($clause == $search_where_clause) {
// $query->add_where('or', 'revisions.body = %s'); - outside of what we are looking for
$query->where[$where_count]['clauses'][$clause_count] = $desirable_where_clause;
// Add the field to the view, just in case.
if (!isset($query->fields['node_revisions_body'])) {
$query->fields['node_revisions_body'] = array(
'field' => 'body',
'table' => 'node_revisions',
'alias' => 'node_revisions_body'
);
}
}
$clause_count++;
}
}
$where_count++;
}
}
}