2009-08-27 11 views
11

Drupalビューの一部のフィルタ間にOR演算子を実装する必要があります。 デフォルトでは、DrupalはすべてのフィルタをまとめてANDします。DrupalビューフィルタのOR演算子

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

に 'OR'、または

$query->group_operator 

を:どちらかの私は、クエリ(変数$クエリ)にアクセスすることができ、私は変更することができ

hook_views_query_alter(&$view, &$query) 

を使用することにより

〜 'OR'

問題は次のとおりです。しかし、私はどこにでもORを必要としません。私はそれらの両方を別々に変更しようとしましたが、望む結果が得られません。

私は=>(フィルタ1とフィルタ2)または(フィルタ3)ORを必要としながら、これらの値を変えているようです。

任意の提案..

私はちょうどビューのクエリを確認することができ、それは、それを変更し、db_queryを介して実行コピーし、それはただ汚いですか?

Thxです。

+0

これにもう一度、ビューにquery alterを使用しています。このルートを試してみます。 http://www.brianfending.com/content/better-wheres-your-drupal-forums-hookviewsqueryalter – cgp

+0

クエリの変更は、@ Voddeが 'ダーティ'と呼んでいるもので、ビューを介してクエリ句を変更しようとしていますAPI呼び出し。 –

+1

DrupalとViewsのバージョンを指定するとよいでしょう。 –

答えて

2

view_query_alterフックでやりたい場合は、$ query-> add_where()を使用して、ANDかORかを指定できます。 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) 
+1

私はそれを自分で試してみました。このメソッドを使うと、探しているものとは反対の '(フィルタ1 ORフィルタ2)AND(フィルタ3 ORフィルタ4)'という結果になります。 '(フィルタ1 ANDフィルタ2)OR 3 ANDフィルタ4) 'となります。 –

7

残念ながら、これはViews2ではまだ欠けている機能です。 It has long been asked forとしばらく前に約束されていましたが、厄介な作業であると思われ、is now scheduled for Views3です。

その間に、そのスレッドに記載されているViews Orモジュールを試すことができます。今日の時点では、まだ開発状況にありますが、積極的に維持されているようです。the issue queueは悪く見えないので、試してみてください。

+0

+1これはViews2にはありません。$ this-> query-> group_operator = 'OR'; '$ this-> query->ここで[$ group] ['type'] = 'OR';は動作しません。 ORへの条項。非常にイライラ。 –

12

Views 3/Drupal 7を使用していて、この質問への回答を探している場合は、ビューに直接焼き付けられます。フィルタの横に「追加」と表示されている場合は、ドロップダウンをクリックしてから、「および/または再配置」をクリックします。それは明らかであるはずです。

+0

+1これは、私が必要としていたものです。一度そこに着くと、フィールドグループも見てください。それは実現するために私に数分かかった唯一の部分でした – Zach

+1

+1 Viewsは素晴らしいです! – bandolero

+0

私はViews 3を持っていますが、私は "and/or;"を見ません。ちょうど "並べ替える"? – Brittany

1

文字列を連結して追加しました。

これは比較的具体的です。次のコードでは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++; 
    } 
    } 
}