2009-08-27 10 views
11

Potrzebuję zastosować operator OR między niektórymi filtrami w widoku Drupal. Domyślnie Drupal AND powoduje, że każdy filtr jest razem.Operator OR w Drupal Wyświetl filtry

Korzystając

hook_views_query_alter(&$view, &$query) 

mogę uzyskać dostęp do zapytania (var $ query) i mogę zmienić albo:

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

do 'lub' lub

$query->group_operator 

"LUB"

Problem jest jednak nie potrzebuję wszędzie OR. Próbowałem zmienić oba z nich osobno lub OR i nie przynosi to pożądanego rezultatu.

Wygląda na to, że zmienia się te wartości, umieszcza LUB wszędzie, a ja potrzebuję => (filtr 1 I filtr 2) LUB (filtr 3), a więc tylko 1 LUB.

może po prostu sprawdzić dla widoku, skopiuj go, modyfikować je i uruchom go poprzez db_query, ale to jest po prostu brudny ..

Wszelkie sugestie?

Thx z góry.

+0

W drugiej sekundzie do tego celu używane jest również zapytanie alter dla widoku - spróbuję tej trasy. http://www.brianfending.com/content/better-wheres-your-drupal-forums-hookviewsqueryalter – cgp

+0

Zmiana zapytania jest tym, co @Vodde nazywa "brudną", staramy się modyfikować klauzule zapytania za pomocą widoków Wywołanie API. –

+1

Byłoby miło podać wersje Drupal i widoki. –

Odpowiedz

2

jeśli chcesz zrobić to z hookiem view_query_alter, powinieneś użyć $ query-> add_where(), gdzie możesz określić, czy to AND i OR. Z widokiem/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

Próbowałem go sam i używając tej metody uzyskuje się '(filtr 1 LUB filtr 2) ORAZ (filtr 3 OR fliter 4)', który jest przeciwny temu, czego szukamy: '(filtr 1 I filtr 2) LUB (filtr 3 I filtr 4) '. –

7

Niestety nadal jest to brakująca funkcja w widokach2. It has long been asked for i został obiecany jakiś czas temu, ale wydaje się być trudnym dziełem i is now scheduled for Views3.

W międzyczasie możesz wypróbować moduł Views Or wspomniany w tym wątku. Na dzień dzisiejszy nadal jest w stanie deweloperskim, ale wygląda na to, że jest aktywnie konserwowany i nie wygląda na zły, więc warto spróbować.

+0

+1 To nie jest w widokach2.'$ this-> query-> where [$ group] ['type'] = 'OR';' nie działa, i '$ this-> query-> group_operator = 'OR';' konwertuje wszystkich operatorów pomiędzy WHERE klauzule do OR. Bardzo frustrujące. –

12

Jeśli używasz obejrzeń 3/Drupal 7 i szuka odpowiedzi na to pytanie, to piecze się prawo do widoków. Tam, gdzie jest napisane "dodaj" obok filtrów, kliknij menu, a następnie kliknij "i/lub; zmień kolejność". To powinno być oczywiste.

+0

+1 za to, robi dokładnie to, czego potrzebowałem. spójrz także na grupy w terenie, gdy już tam dotrzesz. To była jedyna część, która zajęła mi kilka minut, aby zdać sobie sprawę z tego, że – Zach

+1

Widoki +1 są fantastyczne! – bandolero

+0

Mam Widoki 3 i nie widzę "i/lub;" po prostu "przestawić"? – Brittany

1

Dodałem go przez konkatenację ciągu.

Jest to względnie specyficzne dla implementacji - ludzie będą musieli grać z polem, aby dopasować dla OR - node.title w poniższym kodzie i pole, aby dopasować je do - node_revisions.body w tym przypadku.

Dodatkowa część kodu, aby upewnić się, że węzeł_wejścia.body znajduje się w zapytaniu.

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