Hero

Introducción a EntityFieldQuery para Drupal 7

Enero 21, 2013

kenneth
APIs
Drupal

Drupal 7 tiene una muy buena abstracción de capa de datos la cual nos facilita las cosas a la hora de hacer consultas a la base de datos, sin embargo de una manera u otra continuamos construyendo código SQL. EntityFieldQuery nos permite crear consultas sin tener un conocimiento avanzado de SQL, además EntityFieldQuery es una clase que pertenece al núcleo de Drupa dentro de la capa de abstracción de datos, lo que nos permite recuperar información los registros de las entidades (Nodos, Taxonomías, Usuarios) basándose en las propiedades de la entidad.

Podemos recorrer diferentes tipos de entidades por medio del EntityFieldQuery, además si necesitáramos extender o modificar la lógica de nuestra consulta podemos utilizar el hook_entity_query_alter().

Este tipo de consulta se puede agregar en cualquier contenido de Drupal que acepte el PHP filter lo cual no es del todo recomendado ó bien dentro de módulos personalizados. Para conocer un poco mas sobre como crear módulos personalizados puede revisar en el Recetario Drupal: receta # 2.

A continuación un ejemplo que presentara las facilidades que nos ofrece el EntityFieldQuery.

  1. Definición del tipo de contenido de prueba.

Se debe crear un tipo de contenido con la siguiente estructura:

content type fields 0

  1. Creación de la consulta.

Suponiendo que necesitamos seleccionar todo los contenidos que tienen el campo “Date” igual a la fecha actual y el campo “Notificated” como FALSE, entonces a continuación el código,

$today = new DateTime(date('m/d/y'));
$query = new EntityFieldQuery();
$result = $query->entityCondition('entity_type', 'node')
    ->entityCondition('bundle', 'reminder')
    ->propertyCondition('status', NODE_PUBLISHED, '=')
    ->fieldCondition('field_date', 'value', $today->format('Y-m-d'), '=')
    ->fieldCondition('field_notificated', 'value', 0, '=')
    ->execute();

Una de las ventajas más notables con las que cuenta esta clase es la concatenación de métodos para ir construyendo nuestra consulta de una manera fácil de comprender, iremos explicando cada uno de las líneas de código:

$today = new DateTime(date(‘m/d/y’));

Primero se crea una nueva instancia de la clase DateTime() en la variable $today pasando por el constructor el resultado de la función date(‘m/d/y’), esto para el manejo de fechas, puesto que nos brinda mucha lógica encapsulada.

$query = new EntityFieldQuery();

En segunda línea instanciamos un objeto de la clase EntityFieldQuery() en la variable $query con la cual iremos construyendo nuestra consulta.

$query->entityCondition(‘entity_type’, ‘node’)

El primer método llamado es el “entityCondition($name, $value)” este nos permite definir las diferentes condiciones de una entidad, existen cuatro valores soportados:

entity_type: Donde podemos seleccionar el tipo de entidad, ya sea ‘node’, ‘user’, ‘file’, ‘comment’, ‘taxonomy_term’.

bundle: Se utiliza para especificar el tipo de entidad a seleccionar, ya sea ‘page’, ‘article’ o bien un tipo de contenido creado, como nuestro caso ‘reminder’. También es posible seleccionar más de dos entidades, definiéndolos en un arreglo, por ejemplo: entityCondition(‘bundle’, array(‘page’, ‘article’));

revision_id y entity_id: Es posible definir valores enteros para filtrar por las llaves primarias entity_id y revision_id, además podríamos usar varios valores definiéndolo dentro de un arreglo, por ejemplo: entityCondition(‘entity_id’, array(17, 21,422), ‘IN’);

propertyCondition

Utilizado para definir propiedades genéricas de las entidades como el estado (Publicado, No Publicado, etc.), también se puede definir como tercer parámetro el operador propertyCondition(‘status’, NODE_PUBLISHED, ’=‘)

fieldCondition

Por último usamos el método “fieldCondition” para definir las propiedades de los campos específicos de nuestro tipo de contenido, los primeros cuatro parámetros soportados son los siguientes:

$field: Es el nombre de máquina que se le ha asignado a un campo específico, por ejemplo en el campo ‘field_notificated’, para el cual el nombre de la tabla en la base de datos sera ‘field_data_field_notificated’. Entonces el nombre para el parámetro “field” seria únicamente “field_notificated”.

$column: Las columnas de las tablas que contienen datos seria las siguientes: ‘value’, ‘summary’, ‘format’, y ‘language’, estos serian los únicos argumentos validos para poder utilizar. Ahora para los campos que son referencias a otras entidades el valor de la columna seria: ‘target_id’ y si es una taxonomía seria el ‘tid’.

$value: Representa el valor específico por buscar en los campos de la entidad.

$operator: El operador de SQL usado para hacer la comparación en la base de datos, ya sea el igual, mayor que, menor que, entre y demás existentes, etc.

Con toda la estructura de la consulta construida solo resta llamar al método execute() para hacer la consulta sobre la base de datos, con esto obtendremos en la variable $result un arreglo asociativo con el contenido de la consulta usando entidades.

  1. Procesar resultados de la consulta.

por ultimo se deben procesar los resultados, primero consultando si ha retornado valores preguntando si la clave “node” está definida, luego recuperando todos los índices podremos cargar todas las entidades, como se muestra en el siguiente código.

if (isset($result['node'])) {
  $entites = entity_load('node', array_keys($result['node']));
  foreach ($entites as $reminder) {

    /* Procesos por realizar; eventualmente si modificamos
      Algún valor lo podemos hacer persistente usando:
      entity_save('node', $reminder);
     */
  }
}

Con esto completamos el ejemplo de cómo utilizar EntityFieldQuery, el cual nos entrega muchas facilidades a la hora de desarrollar nuestros módulos personalizados.

Espero que les haya sido de ayuda.

Recibe consejos y oportunidades de trabajo 100% remotas y en dólares de weKnow Inc.