2009-08-27 19 views
11

Necesito implementar un operador OR entre algunos filtros en una vista Drupal. De forma predeterminada, Drupal AND tiene todos los filtros juntos.operador O en Drupal View Filters

Mediante el uso de

hook_views_query_alter(&$view, &$query) 

puedo acceder a la consulta ($ var query), y puedo cambiar ya sea:

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

a 'O', o

$query->group_operator 

a 'O'

El problema es sin embargo, no necesito quirófanos en todas partes. He intentado cambiarlos a O por separado y no da el resultado deseado.

Parece que cambiar esos valores, pone OR en todas partes, mientras que necesito => (filtro 1 Y filtro 2) O (filtro 3), por lo que solo 1 OR.

tan sólo pudiera comprobar la consulta de la vista, copiarlo, modificarlo, y ejecutarlo a través db_query, pero eso es bastante sucio ..

¿Alguna sugerencia?

Thx de antemano.

+0

Como segundo a esto, también está usando la consulta alterar para la vista - Voy a probar esta ruta. http://www.brianfending.com/content/better-wheres-your-drupal-forums-hookviewsqueryalter – cgp

+0

La consulta alterar es a lo que @Vodde se refiere como 'sucio', estamos tratando de modificar las cláusulas de consulta a través de un Vistas Llamada API –

+1

Sería bueno especificar las versiones de Drupal y Vistas. –

Respuesta

2

si quieres hacerlo con view_query_alter hook, debes usar $ query-> add_where() donde puedes especificar si es AND u OR. Desde puntos de vista/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

Lo probé yo mismo y con este método resulta en '(filtro 1 O filtro 2) AND (filtro 3 O fliter 4)', que se opone a lo que estamos buscando: '(filtro 1 Y filtro 2) O (filtro 3 Y filtro 4) '. –

7

Desafortunadamente, esta sigue siendo una característica que falta en Views2. It has long been asked for y fue prometido hace un tiempo, pero parece ser un trabajo complicado y is now scheduled for Views3.

Mientras tanto, puede probar el módulo Views Or mencionado en ese hilo. A día de hoy, todavía está en estado de desarrollo, pero parece que se mantiene activamente y the issue queue no se ve mal, por lo que es posible que desee probarlo.

+0

+1 que esto no está en Views2.'$ this-> query-> donde [$ group] ['type'] = 'OR';' no funciona, y '$ this-> query-> group_operator = 'OR';' convierte todos los operadores entre WHERE cláusulas a OR. Muy frustrante. –

12

Si está utilizando Vistas 3/Drupal 7 y en busca de la respuesta a esta pregunta, se cuece al horno a la derecha en Vistas. Donde dice "agregar" al lado de los filtros, haga clic en el menú desplegable y luego haga clic en "y/o reorganizar". Debería ser obvio a partir de ahí.

+0

+1 para esto, hace exactamente lo que necesitaba. también mire grupos de campo una vez que llegue allí. Esa fue la única parte que me llevó unos minutos darme cuenta – Zach

+1

+1 ¡Las vistas son fantásticas! – bandolero

+0

Tengo vistas 3 y no veo "y/o". solo "reorganizar"? – Brittany

1

Lo agregué concatenando la cuerda.

Es relativamente específico para la implementación: las personas tendrían que jugar con el campo para que coincida con OR - node.title en el siguiente código y el campo para que coincida con - node_revisions.body en este caso.

Pieza adicional de código para asegurarse de que node_revisions.body está en la consulta.

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