欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

Is it possible with Drupal Views to have AND and OR in a filter set? 可以不看

Is it possible with Drupal Views to have AND and OR in a filter set?

 

 

I am attempting to build a view with four filters (A, B, C, D). With Views 3 it is possible to select whether you want these filters to be chained with AND statements or OR statements. Is there a way to configure views so as to chain some of them with AND and others with OR?

For example, ending up with a query that is similar to:

SELECT * 
FROM {table} 
WHERE A = 0
  AND B = 0
  AND (C = 1 OR D = 1)`
shareimprove this question
 

2 Answers 正确答案 

 

Looks like this is entirely possible with the Views 3.x branch. You can create custom Filter groups directly in the Views UI itself, and set the AND/OR for each group separately.

shareimprove this answer
 
2 
This is possible in Views 2.x with the Views OR module, but it is much more confusing than the interface in Views 3.x. – tim.plunkett Mar 3 '11 at 4:15
   
The easiest way to do this in Views 2.x is probably with: api.lullabot.com/hook_views_query_alter – Alex Mar 12 '11 at 3:23
   
Can Views 3.x nest? e.g. ((x OR y) OR (a AND b)) AND (i AND j) – alexkb Jul 11 '13 at 5:48
1 
To answer, my question, you can do that, but you have to duplicate things, e.g. ((x OR y) AND (i AND j)) OR ((a AND b) AND (i AND j)). The other problem is, if some of these conditions are exposed, then you can't do it. Discussed here: drupal.org/node/1244772#comment-7430080 – alexkb Jul 11 '13 at 5:59


自 http://drupal.stackexchange.com/questions/143/is-it-possible-with-drupal-views-to-have-and-and-or-in...


 

是否有可能使用Drupal意见有AND和OR在过滤器设置?

 

 

我试图建立与四个滤波器(A,B,C,D)的景色。随着浏览次数3,可以选择是否要这些过滤器与AND陈述或OR语句被链接。有没有意见配置,以连锁其中一些带有AND和其他人还是有办法?

例如,结束了一个查询是类似于:

SELECT * 
FROM {table} 
WHERE A = 0
  AND B = 0
  AND (C = 1 OR D = 1)`
分享改善这个问题,
 

2回答 正确答案 

 

看起来这是完全有可能与浏览3.X分支。您可以在浏览UI本身直接创建自定义过滤器组,并分别设置和/或每个组。

分享提高这个答案
 
2 
这是可能与视图2.x的观点或模块,但它远比在浏览3.x的界面更加混乱 -  tim.plunkett 3月3日'11 4:15
   
在视图2.x到最简单的方法是可能与:api.lullabot.com/hook_views_query_alter -  亚历 3月12日在'11 3:23
   
可以在视图3.X窝?例如:((X或Y)或(A和B))和(i和j) -  alexkb 7月11日在'13 5:48
1 
要回答,我的问题,你可以做到这一点,但你必须重复的事情,如((x或y)和(i和j))OR((A和B)和(i和j))。另一个问题是,如果一些这些条件暴露出来,那么你不能做到这一点。这里讨论:drupal.org/node/1244772#comment-7430080 -  alexkb 7月11日在'13 5:59

如果您仍然希望使用views2像我一样,你可以编写自己的过滤器。

虽然,在我的情况下,唯一的要求是放置OR field IS NULL在查询..所以它的工作对我来说..我希望它可以进一步延长。如果有人喜欢这个想法。我可以上传的代码..这里..! !



自 http://drupal.stackexchange.com/questions/143/is-it-possible-with-drupal-views-to-have-and-and-or-in...


 

如何使用意见上下文过滤器或?

 

 

 

浏览网和SE的看来,我过了一段时间,没有很好地解决了2相结合contextual filters使用OR(而不是默认的AND)。

这篇文章提到了一个PHP黑客这个职位有一些链接到一个问题,说明在最近的一次改变观点7.x的-3.1它还使用mentiones hook_views_query_alter(&$view, &$query)修改视图。

有没有人有一个工作示例或更好的解决方案?

分享改善这个问题,
 
   
我不认为这是一个更好的解决方案,截至目前。正如你指出的线程说,这显然是一个持续的问题。我同样的问题,本周迷迷糊糊的,只好找带有附件的解决方法。不过,它并没有给混合列表,但两个相连的人,它不适合所有需求。 -  Countzero 5月23日在'12 18:42

4回答

 

尝试修补这个问题:从参数上拉过滤值

它可以让你从上下文过滤器传递值“普通过滤器”。在那里,你可以做你的先进条件。

分享提高这个答案
 

注释线程开始在这里介绍一种有效的解决方法。MotoTribe链接到同一线程,但在他的问题的时候,有该网页上没有工作实施例。现在有,具体如下:

在你的模块,实现hook_views_api()

function MODULENAME_views_api() {
  return array(
    'api' => 3,
  );
}

然后,一个新的文件添加到您的模块调用MODULENAME.views.inc,并实现hook_views_query_alter()

function MODULENAME_views_query_alter(&$view, &$query) {
  if ($view->name == 'whatever_your_view_is_called') {
    $query->where[0]['type'] = 'OR';
  }
}

另外要注意这个警告的:

显然,“内容:发布的(是)”过滤器,自带的每一个视图被认为是相同的滤波器组作为上下文过滤器(组0)的一部分。因此,为了使我的观点仅显示发表属于任何由上下文过滤器指定的组节点(发表AND(OR ARG1 ARG2 OR ...)),我不得不搬到“内容:发布的(是)”进新的过滤器组(使用“和/或重新排列”对话框)。需要注意的是UI没有显示“内容:发布的(是)”不同的过滤任何后我把它变成一个新的组(没有发现任何其他组),但在查询对象被传递到hook_views_query_alter()它做的举动它从组0到组1,使代码在上述功能不再影响它。

分享提高这个答案
 
1 
这是更好地至少套用引用到OP的问题的相关性。链接只答案是沮丧,因为链接可能无法持续。 -  三曲腿图 5月16日在'13 0:34
   
@Triskelion:啊,你是绝对正确的。我已经编辑我的反应,以解决这个问题。 -  CoreDumpError 5月16日在'13 5:12

有哪些改变意见的处理程序,使与使用或代替和上下文过滤器模块: 查看上下文过滤器或

分享提高这个答案
 

的情况语境过滤器过滤器组的确是惨淡。这里是上的执行线程有关此toppic,其具有相同的溶液如通过@CoreDumpError说明。

https://drupal.org/node/1451218

此外,这里是一个模块,可以帮助解决冲突的语境和暴露的过滤器... 查看过滤泛

自 http://drupal.stackexchange.com/questions/32019/how-to-use-a-views-contextual-filter-or

 

How to use a views contextual filter OR?

 

 

After browsing the net and SE for a while it appears to me there is no good solution to combine 2 contextual filters with OR (rather than the default AND).

This post mentions a PHP hack and this post has some links to an issue stating a recent change inviews 7.x-3.1. It also mentiones using hook_views_query_alter(&$view, &$query) to modify the view.

Does anyone have a working example or a better solution?

shareimprove this question
 
   
I don't think there is a better solution as of now. As said in the threads you pointed, it's an ongoing issue apparently. I stumbled on the same problem this week, and had to find a workaround with attachments. But then, it doesn't give a mixed list but two connected ones, which doesn't fit all needs. – Countzero May 23 '12 at 18:42

4 Answers

 

正确答案
Try the patch in this issue : Pull filter value from an argument

It allows you to pass the value from the contextual filter to the "normal filter". There you can do your advanced conditions.

shareimprove this answer
 

The comment thread starting here describes an effective workaround. MotoTribe linked to the same thread, but at the time of his question, there was no working example on that page. Now there is, as follows:

In your module, implement hook_views_api():

function MODULENAME_views_api() {
  return array(
    'api' => 3,
  );
}

Then add a new file to your module called MODULENAME.views.inc, and implement hook_views_query_alter():

function MODULENAME_views_query_alter(&$view, &$query) {
  if ($view->name == 'whatever_your_view_is_called') {
    $query->where[0]['type'] = 'OR';
  }
}

Also be aware of this caveat:

Apparently, the "Content: Published (Yes)" filter that comes with every View is considered to be a part of the same filter group as the contextual filters (group 0). So in order to make my view display onlypublished nodes which belong to any of the groups specified by contextual filters (published AND (arg1 OR arg2 OR ...)), I had to move the "Content: Published (Yes)" into a new filter group (using the "And/Or, Rearrange" dialog). Note that the UI didn't display the "Content: Published (Yes)" filter any differently after I moved it into a new group (there weren't any other groups), but in the query object that gets passed into hook_views_query_alter() it did move it from group 0 into group 1, causing the code in the above functions to no longer affect it.

shareimprove this answer
 
1 
It is better to at least paraphrase the relevance of the references to the OP's question. Link only answers are discouraged because links may not persist. – Triskelion May 16 '13 at 0:34
   
@Triskelion: Ah, you're absolutely right. I've edited my response to fix that. – CoreDumpError May 16 '13 at 5:12

There is a module which changes handlers of Views to make contextual filters to be used with OR instead of AND: Views Contextual Filters OR

shareimprove this answer
 

The situation with Contextual Filters and Filter Groups is indeed bleak. Here is thread on D.o about this toppic, which has the same solution as stated by @CoreDumpError.

https://drupal.org/node/1451218

Also, here is a module that can help resolve conflicting contextual and exposed filters... Views Filter Harmonizer

自 http://drupal.stackexchange.com/questions/32019/how-to-use-a-views-contextual-filter-or


 

在Drupal查看过滤器或操作员

 

 
 

我需要实现一些过滤器之间的OR运算符在一个Drupal视图。默认情况下,Drupal和的每一个过滤器在一起。

通过使用

hook_views_query_alter(&$view, &$query)

我可以访问该查询(VAR $查询),我可以改变之一:

$query->where[0]['type'] 

到'或',或

$query->group_operator 

到'或'

但问题是,我不需要或不无处不在。我试着他们两个更改为或单独,它不会产生期望的结果。

这似乎改变这些值,看跌或无处不在,而我需要=>(过滤器1和过滤2)或(3过滤器),因此只需1〜。

我可以简单的视图的查询,复制,修改,并通过db_query运行它,但是这只是脏了..

有什么建议么 ?

THX在前进。

分享改善这个问题,
 
   
作为第二,虽然这一点,这里还使用查询改变了看法-我要去尝试这条路线。brianfending.com/content/... - altCognito 2月15日在'10 19:56
   
查询改变是@Vodde是指为'脏',我们试图通过浏览API调用来修改查询子句。 -  业余咖啡师 4月22日'11此部分从2:51
1 
将是不错的指定Drupal和意见的版本。 -  皮埃尔Buyle 12月15日在'11 6:51

4回答 正确答案

 

如果你想与view_query_alter挂钩做到这一点,你应该使用$查询 - > add_where()在哪里,如果是AND或OR可以指定。从意见/有/ 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)
分享提高这个答案
 
1 
我尝试过自己在使用这种方法的结果( filter 1 OR filter 2 ) AND ( filter 3 OR fliter 4 ),这就是我们正在寻找的反对:( filter 1 AND filter 2 ) OR ( filter 3 AND filter 4 ) -  业余咖啡师4月22日在'11 2点53分

如果您在使用浏览3/7的Drupal和寻找这个问题的答案,它是烘烤出来右转进入查看。它说:“增加”旁边的过滤器,单击下拉,然后单击“;和/或重新安排”。它应该是显而易见的,从那里。

分享提高这个答案
 
   
+1对于这一点,它确实正是我需要的。还看场组,一旦你到达那里。这是我花了几分钟的时间来实现的唯一部件 -  扎克- 11月19日在'13 0:56
1 
+1意见是太棒了! -  bandolero 11月29日在'13 11:07
   
我有3次,我不看“;和/或” 只是“重新安排”? -  布列塔尼 5月26日在22:02

不幸的是仍处于Views2缺少的功能。长期以来,人们一直要求,并在不久前答应了,但似乎是一个棘手的一件作品和现定于Views3

在此期间,你可以试试观点或在该线程提到的模块。截至今日,它仍然是在开发中的地位,但似乎是积极维护和问题队列看起来不坏,所以你可能想给它一个尝试。

分享提高这个答案
 
   
+1,这不是在Views2。$this->query->where[$group]['type'] = 'OR';不工作,并且$this->query->group_operator = 'OR';将所有的WHERE子句来之间或运营商。非常令人沮丧。 -  业余咖啡师 04月22日在'11 2:57

我通过连接字符串添加它。

这是比较具体的实现 - 人们会需要与现场发挥,以匹配或者 - 在下面的代码,并现场与匹配它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++;
    }
  }
}
分享提高这个答案

来自  http://stackoverflow.com/questions/1340423/or-operator-in-drupal-view-filters




OR operator in Drupal View Filters

 

 
 

I need to implement an OR operator between some filters in a Drupal View. By default, Drupal AND's every filter together.

By using

hook_views_query_alter(&$view, &$query)

I can access the query ( var $query ) , and I can change either :

$query->where[0]['type'] 

to 'OR', or

$query->group_operator 

to 'OR'

The problem is however, that I do not need OR's everywhere. I've tried changing both of them to OR seperately, and it doesn't yield the desired result.

It seems changing those values, puts OR's everywhere, while I need => ( filter 1 AND filter 2 ) OR ( filter 3 ), so just 1 OR.

I could just check the Query of the View, copy it, modify it, and run it through db_query, but that's just dirty ..

Any suggestions ?

Thx in advance.

shareimprove this question
 
   
As a second though to this, there is also using the query alter for the view -- I'm going to try this route.brianfending.com/content/… – altCognito Feb 15 '10 at 19:56
   
The query alter is what @Vodde is referring to as 'dirty', we are trying to modify the query clauses via a Views API call. – amateur barista Apr 22 '11 at 2:51
1 
Would be nice to specify Drupal and Views versions. – Pierre Buyle Dec 15 '11 at 6:51

4 Answers 正确答案

 

if you want do it with view_query_alter hook, you should use $query->add_where() where you can specify if it's AND or OR. From views/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)
shareimprove this answer
 
1 
I tried it myself and using this method results in ( filter 1 OR filter 2 ) AND ( filter 3 OR fliter 4 ), which is opposed to what we are looking for: ( filter 1 AND filter 2 ) OR ( filter 3 AND filter 4 ). – amateur barista Apr 22 '11 at 2:53

If you are using Views 3 / Drupal 7 and looking for the answer to this question, it is baked right into Views. Where it says "add" next to filters, click the dropdown, then click "and/or; rearrange". It should be obvious from there.

shareimprove this answer
 
   
+1 for this, It does exactly what I needed. also look at field groups once you get there. That was the only part that took me a few minutes to realize – Zach Nov 19 '13 at 0:56
1 
+1 Views is fantastic! – bandolero Nov 29 '13 at 11:07
   
I have Views 3, and I don't see "and/or;" just "rearrange"? – Brittany May 26 at 22:02

Unfortunately this is still a missing feature in Views2. It has long been asked for and was promised a while ago, but seems to be a tricky piece of work and is now scheduled for Views3.

In the meantime you could try the Views Or module mentioned in that thread. As of today, it is still in dev status, but seems to be actively maintained and the issue queue does not look to bad, so you might want to give it a try.

shareimprove this answer
 
   
+1 That this is not in Views2. $this->query->where[$group]['type'] = 'OR'; does not work, and$this->query->group_operator = 'OR'; converts all the operators between WHERE clauses to OR. Very frustrating. – amateur barista Apr 22 '11 at 2:57

I added it by concatenating the string.

It is relatively specific to the implementation - people would need to play with field to match for OR - node.title in the following code and the field to match it with - node_revisions.body in this case.

Extra piece of code to make sure that node_revisions.body is in the query.

/**
 * 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++;
    }
  }
}
shareimprove this answer


来自 http://stackoverflow.com/questions/1340423/or-operator-in-drupal-view-filters
 

普通分类: