2009-08-27 2 views
11

Ho bisogno di implementare un operatore OR tra alcuni filtri in una vista Drupal. Per impostazione predefinita, Drupal mostra tutti i filtri insieme.Operatore OR in Drupal View Filters

Utilizzando

hook_views_query_alter(&$view, &$query) 

posso accedere alla query (var $ query), e posso cambiare o:

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

a 'O', o

$query->group_operator 

a "OR"

Il problema è tuttavia, che non ho bisogno di OR ovunque. Ho provato a modificarli entrambi in OR separatamente e non produce il risultato desiderato.

Sembra modificare questi valori, inserisce OR ovunque, mentre ho bisogno di => (filtro 1 AND filtro 2) O (filtro 3), quindi solo 1 OR.

ho potuto solo controllare la query della vista, copiarlo, modificarlo, e gestito attraverso db_query, ma questo è solo sporca ..

Qualche suggerimento?

Thx in anticipo.

+0

Come secondo a questo, c'è anche l'uso della query alter per la vista - ho intenzione di provare questa rotta. http://www.brianfending.com/content/better-wheres-your-drupal-forums-hookviewsqueryalter – cgp

+0

La query alter è ciò che @Vodde si riferisce a 'dirty', stiamo cercando di modificare le clausole della query tramite una vista Chiamata API –

+1

Sarebbe bello specificare le versioni Drupal e Views. –

risposta

2

se si desidera eseguire l'hook con view_query_alter, è necessario utilizzare $ query-> add_where() in cui è possibile specificare se è AND o OR. Da 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

L'ho provato io stesso e usando questo metodo si ottiene '(filtro 1 OR filtro 2) AND (filtro 3 O fliter 4)', che è opposto a quello che stiamo cercando: '(filtro 1 AND filtro 2) OR (filtro 3 E filtro 4) '. –

7

Purtroppo questa è ancora una caratteristica mancante in Views2. It has long been asked for ed è stato promesso qualche tempo fa, ma sembra essere un lavoro difficile e is now scheduled for Views3.

Nel frattempo è possibile provare il modulo Views Or menzionato in quella discussione. A partire da oggi, è ancora in stato di sviluppo, ma sembra essere attivamente mantenuto e the issue queue non sembra male, quindi si potrebbe voler fare un tentativo.

+0

+1 Che questo non è in Views2.'$ this-> query-> dove [$ group] ['type'] = 'OR';' non funziona, e '$ this-> query-> group_operator = 'OR';' converte tutti gli operatori tra WHERE clausole a OR. Molto frustrante. –

12

Se si utilizza Vista 3/Drupal 7 e cercando la risposta a questa domanda, è cotto a destra in Visite. Dove dice "aggiungi" accanto ai filtri, fai clic sul menu a discesa, quindi fai clic su "e/o; riorganizza". Dovrebbe essere ovvio da lì.

+0

+1 per questo, fa esattamente quello di cui avevo bisogno. guarda anche i gruppi sul campo una volta arrivato. Questa è stata l'unica parte che mi ha portato a pochi minuti per realizzare – Zach

+1

+1 Views è fantastico! – bandolero

+0

Ho visualizzazioni 3 e non vedo "e/o;" solo "riorganizzare"? – Brittany

1

L'ho aggiunto concatenando la stringa.

è relativamente specifico per l'attuazione - la gente avrebbe bisogno di giocare con il campo da abbinare a favore o - node.title nel seguente codice e il campo da abbinare con - node_revisions.body in questo caso.

Parte aggiuntiva di codice per assicurarsi che node_revisions.body sia nella 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++; 
    } 
    } 
}