Cómo personalizar un filtro de Search API en Drupal 7

Author Top
enzo

La semana pasada les muestre Cómo agregar campos personalizados en SOLR index usando Entity API & Search API en Drupal 7, hoy continuando con esa línea de concepto vengo a mostrarles cómo manipular una consulta de Search API para incluir una lógica personalizada en sus consultas.

En primer lugar, vamos a imaginar un escenario hipotético en que tenemos que ejecutar una consulta diferente para los usuarios anónimos y registrados.

Usando los campos personalizados creados la entrada de blog referencia anteriormente, vamos a mostrar la lista del día hoy , por otro lado para los usuarios registrados vamos a mostrar todos los  eventos en curso (incluyendo eventos que pasan durante varios días) y los eventos que vienen pronto.

Alterar consulta Search API

Para modificar nuestras consultas usaremos el hook hook_search_api_query_alter() como se puede ver en el siguiente ejemplo

function MYMODULE_search_api_query_alter(SearchApiQueryInterface $query) {
  global $user;
  // Filter from where the Search API query will be trigger 
  if(arg(0) == 'events' && arg(1) == 'list') {

    $start_day = strtotime(date('Y-m-d'));

    if($user->uid == 0 ) {
      $query->condition('event_start_day', $start_day, '<=');
      $query->condition('event_end_day', $start_day, '>=');
    }
    else {
      // Select events in progress
      $left_filter = $query->createFilter('AND');
      $left_filter->condition('event_start_day', $start_day, '<=');
      $left_filter->condition('event_end_day', $start_day, '>=');

      // Select events with a start date in the future
      $right_filter = $query->createFilter('AND');
      $right_filter->condition('event_start_day', time(), '>=');

      $main_filter = $query->createFilter('OR');
      $main_filter->filter($left_filter);
      $main_filter->filter($right_filter);

      $query->filter($main_filter);
     }
}     

Permítanme desmenuzar de código anterior. Si el usuario es anónimo vamos a user el método SearchApiQueryInterface::condition para incluir nuevos filtros que nos permitan determinar los eventos del día, sin importar si son eventos que suceden en un rango de días.

En el caso de usuarios registrados, utilizamos el mismo método pero con una variación sutil. Por defecto se añaden todas las condiciones usando el operador AND, que está bien la mayoría de las veces. Sin embargo, en nuestro caso, es necesario incluir grupos de validación a la consulta por esa razón necesitamos el uso del operador OR.

Utilizando el método SearchApiQueryInterface::createFilter es posible crear grupos de filtros escogiendo que operador usar AND o OR.

Adicionalmente, utilizando el método SearchApiQueryInterface::filter es posible incluir los grupo de filtros dentro  de un objeto SearchApiQueryInterface.

En resumen, el fragmento de código anterior crea un filtro similar a la siguiente lógica de SQL

(event_start_day <= time() AND event_end_day >= time()) OR (event_start_day >= time())

Usted puede crear cualquier combinación de filtros necesarios en su lógica.

Espero que hayas encontrado este artículo útil.