Extra Block Types (EBT) - Nueva experiencia con Layout Builder❗

Extra Block Types (EBT): tipos de bloques con estilo y personalizables: Presentaciones de diapositivas, Pestañas, Tarjetas, Acordeones y muchos más. Configuraciones integradas para fondo, DOM Box y plugins de JavaScript. Experimenta hoy el futuro de la construcción de diseños.

Módulos de demostración EBT Descargar módulos EBT

❗Extra Paragraph Types (EPT) - Nueva experiencia con Paragraphs

Extra Paragraph Types (EPT): conjunto de módulos basado en párrafos de forma análoga.

Módulos de demostración EPT Descargar módulos EPT

Scroll

Trabajar con una base de datos en Drupal 7 - Lección 6 - Cambiar una consulta sobre la marcha (hook_query_alter)

12/05/2025, by Ivan

Una característica importante de las consultas de selección dinámicas es la posibilidad de que otros módulos modifiquen las consultas en tiempo real. Esto permite a los módulos insertar sus propias instrucciones en la consulta, influyendo así en su comportamiento o aplicando cambios durante la ejecución, por ejemplo, para establecer restricciones de acceso a nodos. Existen 3 componentes clave para modificar consultas dinámicas: etiquetas (tagging), metadatos (meta data) y hook_query_alter().

Etiquetado (Tagging)

Cualquier consulta de selección dinámica puede ser “etiquetada” con una o más cadenas. Estas etiquetas sirven para identificar el tipo de consulta y permiten a otros módulos detectar estas cadenas y realizar acciones en consecuencia. Las etiquetas deben estar en formato alfanumérico en minúsculas, siguiendo las mismas reglas que los nombres de variables en PHP. Para agregar una etiqueta a una consulta, se usa el método addTag():

<?php
$query->addTag('node_access');
?>

Para comprobar si una consulta tiene una etiqueta específica, existen tres métodos disponibles:

<?php
// TRUE si la consulta tiene la etiqueta.
$query->hasTag('example');

// TRUE si la consulta tiene todas las etiquetas indicadas.
$query->hasAllTags('example1', 'example2');

// TRUE si la consulta tiene al menos una de las etiquetas.
$query->hasAnyTag('example1', 'example2');
?>

Tanto hasAllTags() como hasAnyTag() aceptan dos parámetros, y su orden no afecta el resultado. Usar etiquetas es sencillo y Drupal ya ofrece etiquetas estándar como:

node_access
La consulta debe aplicar restricciones de acceso a nodos.
translatable
La consulta debe contener cadenas traducibles.
term_access
La consulta debe aplicar restricciones de acceso a términos.
views
La consulta ha sido generada por el módulo Views.

Metadatos (Meta data)

Las consultas también pueden tener metadatos asociados. Estos ofrecen una forma adicional de modificar la consulta en tiempo de ejecución. Los metadatos pueden ser cualquier valor PHP con una clave en formato de cadena.

<?php
$node = node_load($nid);
// ... crear objeto $query
$query->addMetaData('node', $node);
?>

Los metadatos no tienen efecto por sí solos sobre la consulta. Sirven únicamente como información adicional para ser usada en modificaciones a través de etiquetas. Para acceder a los metadatos se usa getMetaData():

<?php
$node = $query->getMetaData('node');
?>

Si no hay metadatos para la clave indicada, el método devuelve NULL.

hook_query_alter()

Ni las etiquetas ni los metadatos modifican por sí mismos la consulta. Solo brindan información para que hook_query_alter() pueda actuar. Todas las consultas de selección dinámicas pasan por este hook justo antes de ejecutar execute(), y justo antes de ser compiladas. Esto da a los módulos la oportunidad de modificar la consulta completamente. Este hook acepta un parámetro: el objeto de consulta.

<?php
/**
 * Implementación de hook_query_alter().
 */
function example_query_alter(QueryAlterableInterface $query) {
  // ...
}
?>

También puedes usar hook_query_TAGNAME_alter() para actuar solo sobre consultas con una etiqueta específica. Por ejemplo, para consultas con la etiqueta node_access:

<?php
function example_query_node_access_alter(QueryAlterableInterface $query) {
  // ...
}
?>

Hay dos observaciones importantes sobre hook_query_alter():

  1. El parámetro $query no se pasa por referencia, ya que en PHP5 los objetos se pasan siempre por referencia implícita. No es necesario usar &. Además, este hook no devuelve ningún valor.
  2. El tipo del parámetro está definido explícitamente como QueryAlterableInterface. Esto protege contra errores si se pasa un tipo incorrecto, y garantiza compatibilidad futura mejor que limitarse a SelectQuery.

hook_query_alter() puede modificar completamente la consulta, excepto ejecutar la misma consulta dentro del hook, lo cual causaría un bucle. Puedes usar etiquetas y metadatos para decidir qué acciones tomar. Los desarrolladores también pueden invocar métodos del objeto consulta como añadir campos, condiciones, ordenaciones, uniones, etc., o agregar restricciones de acceso. Incluso puedes eliminar o reescribir partes de la consulta con este hook.

<?php
$fields =& $query->getFields();
$expressions =& $query->getExpressions();
$tables =& $query->getTables();
$order =& $query->getOrderBy();
$where =& $query->conditions();
$having =& $query->havingConditions();
?>

Importante: estos métodos devuelven referencias, por lo que el hook alter accede directamente a la estructura interna del objeto. Todos estos métodos devuelven arrays, cuyas estructuras están documentadas en la clase SelectQuery en el archivo includes/database/select.inc.