Miré más allá, pero realmente no pude encontrar ninguna documentación que describa esto.
Lo que necesitaba era una forma de unir la tabla de usuarios con otras dos tablas con datos para los usuarios. Sin embargo, las otras dos tablas están en una relación 'uno a muchos' con la tabla de usuarios, lo que significa que terminaré con una unión cartesiana si intento unirme a la tabla de usuarios con ambas tablas al mismo tiempo . Sin embargo, dado que todo lo que necesito es contar el número de registros en las otras dos tablas asociadas con un usuario determinado, una subconsulta debería poder hacer el truco. Sin embargo, no pude encontrar ninguna documentación sobre Vistas y subconsultas, así que esto es lo que hice.
- Creado dos campos ficticios
Creé dos campos ficticios (que llamaré 'descargas' y 'escuchas') a través de hook_views_data (). La definición del campo se enumera a continuación.
function hook_views_data() {
$data['users'] = array(
'downloads' => array(
'title' => t('Downloads'),
'field' => array(
'handler' => 'views_handler_field_numeric',
'click sortable' => TRUE,
),
'filter' => array(
'handler' => 'views_handler_filter_numeric',
),
'sort' => array(
'handler' => 'views_handler_sort',
),
),
'listens' => array(
'title' => t('Listens'),
'field' => array(
'handler' => 'views_handler_field_numeric',
'click sortable' => TRUE,
),
'filter' => array(
'handler' => 'views_handler_filter_numeric',
),
'sort' => array(
'handler' => 'views_handler_sort',
),
)
),
);
Ahora, cuando configure una vista para usuarios, aparecerán los campos 'Descargas' y 'Escuchas'. Sin embargo, intentar ejecutar una consulta ahora generará un error ya que los campos ficticios, después de todo, son campos ficticios. Ellos no existen. El único propósito de estos campos es indicarle a nuestra implementación de hook_views_query_alter () que necesita hacer unos pocos replacemenets.
- Implementar hook_views_query_alter ()
El truco aquí es verificar si la consulta dada incluye los campos 'Descargas' o 'Escuchas'. Si lo hace, eliminaremos los campos de la consulta y los reemplazaremos con subconsultas. La implementación de esta función es la siguiente.
function mta_views_query_alter(&$view, &$query) {
foreach ($query->fields as $field_key => &$field_values) {
if ($field_values['table'] == 'users') {
switch ($field_values['field']) {
case 'downloads':
unset($query->fields[$field_key]);
$query->add_field(null, "(SELECT COUNT(*) FROM {fileusage} fu WHERE fu.externaluser = {users}.uid AND fu.action = 0)", $field_key);
break;
case 'listens':
unset($query->fields[$field_key]);
$query->add_field(null, "(SELECT COUNT(*) FROM {fileusage} fu WHERE fu.externaluser = {users}.uid AND fu.action = 1)", $field_key);
break;
}
}
}
}
Tenga en cuenta que estamos reutilizando el alias del campo eliminado para la subconsulta. De esa forma, Views pensará que el valor devuelto por la subconsulta en realidad proviene del campo ficticio (que, después de todo, no existe).
Esto es. No estamos obteniendo una unión cartesiana y tanto las 'descargas' como las 'escuchas' se cuentan correctamente.