Eu olhei mais longe, mas não consegui encontrar nenhuma documentação descrevendo isso.
O que eu precisava era de uma maneira de ingressar na tabela de usuários com outras duas tabelas contendo dados para os usuários. No entanto, as outras duas tabelas estão em um relacionamento "um para muitos" com a tabela de usuários, o que significa que eu terminarei com uma junção cartesiana se tentar associar a tabela de usuários com essas duas tabelas ao mesmo tempo . No entanto, como tudo o que preciso é contar o número de registros nas duas outras tabelas associadas a um determinado usuário, uma subconsulta deve ser capaz de executar o truque. No entanto, não consegui encontrar nenhuma documentação sobre Views e subconsultas - então, aqui está o que eu fiz.
- Criou dois campos fictícios
Criei dois campos fictícios (que chamarei de 'downloads' e 'escuta') por meio de hook_views_data (). A definição do campo está listada abaixo.
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',
),
)
),
);
Agora, quando você configura uma visualização para usuários, os campos 'Downloads' e 'Escuta' aparecerão. No entanto, tentar executar uma consulta agora resultará em um erro, pois os campos fictícios, afinal, são campos fictícios. Eles não existem. O único objetivo desses campos é sinalizar para nossa implementação de hook_views_query_alter () que ele precisa executar alguns substituintes.
- Implementar hook_views_query_alter ()
O truque aqui é verificar se a consulta fornecida inclui os campos 'Downloads' ou 'Escuta'. Nesse caso, removeremos os campos da consulta e os substituiremos por subconsultas. A implementação desta função é a seguinte.
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;
}
}
}
}
Observe que estamos reutilizando o alias do campo removido para a subconsulta. Dessa forma, o Views pensará que o valor retornado da subconsulta realmente vem do campo fictício (que, afinal, não existe).
Isso é. Não estamos recebendo uma junção cartesiana e os downloads e as escutas são contados corretamente.