Modificando la consulta de las vistas en Drupal 8 y 9

drupal.png
Solucionex
14
Mayo 21

Ocasionalmente, las consultas que hacen las vistas de Drupal a la base de datos no son suficientes para cubrir nuestras necesidades.

Las vistas de Drupal nos permiten crear relaciones para aumentar la información cruzada, renderizarla de distintas formas e incluso formatear y reescribrir cada campo a renderizar, implementando plantillas twig en la configuración de la propia vista. Esto puede resultar confuso a la hora de aplicar filtros y criterios de ordenación, puesto que para ciertos aspectos, dependemos de cómo lleguen los datos desde la base de datos.

Por ejemplo, imagina que recibes un campo que contiene un nombre y el primer apellido. Si quieres mostrar sólo el apellido, puedes pedir mostrar el campo y en la configuración del mismo modificarlo mediante twig. Drupal ha recibido el contenido del campo de base de datos, le has indicado cómo renderizarlo, y además le aplicas una reescritura.

Sin embargo, no puedes ordenar por el primer apellido. Esto pasa porque el orden está fijado por la consulta SQL. Puedes configurar la vista para que pida a la base de datos ordenar por el campo de nombre y apellido, pero si necesitas que sólo tome el apellido, necesitas que esto se aplique durante la propia consulta SQL mediante una expresión, la cual no es configurable desde la vista.

El hook hook_views_query_alter nos permite realizar cambios en la consulta. Drupal contiene la query en un array que podemos modificar como tal, pero lo más habitual será que las partes de la consulta que necesitemos alterar en el backend las creemos nuevas. En este enlace podéis ver todos los métodos aplicables sobre la query, de los cuales los más básicos son los siguientes:

  • addField - Añadir un campo a la consulta, posibilita ponerle un alias
  • addGroupBy - Añadir un criterio de agrupación
  • addHavingExpression - Añadir cláusula "having"
  • addOrderBy - Añadir un criterio de ordenación
  • addRelationship - Añadir una relación
  • addTable - Añadir una tabla a la consulta
  • addWhere - Añadir una condición
  • addWhereExpression - Añadir una expresión condicional

En el caso de ejemplo del apellido, sólo necesitaremos añadir un campo que se quede con la parte de la cadena que necesitamos, y utilizarlo para ordenación.

En el hook, lo primero que debemos hacer es seleccionar la vista y opcionalmente la display en la que vamos a aplicar la modificación de la consulta:

if ($view->id() == 'id_vista' && $view->getDisplay()->display['id'] == 'id_display')

 Dentro, creamos la expresión que se quede con la última palabra del campo, en mi caso, el título del nodo:

 $expresion = "substring_index(title, ' ', -1)";

 Y ahora, añadimos el campo a la query y añadimos la ordenación por dicho campo:

$query->addField(NULL, $expresion, "apellido");
$query->addOrderby(NULL, NULL, 'ASC', 'apellido');

En la página de configuración de la vista, se mostrará la query final que se está utilizando para mostrar la preview del resultado, por lo que podremos comprobar cómo se aplica la expresión identificada por "apellido", y cómo se utiliza "apellido" para establecer orden ascendente. Este order by se añadirá a la cola.