Ho guardato oltre, ma non sono riuscito a trovare alcuna documentazione che descriva questo.
Ciò di cui avevo bisogno era un modo per unire la tabella degli utenti con altre due tabelle che contenevano dati per gli utenti. Tuttavia, le altre due tabelle hanno una relazione "uno-a-molti" con la tabella degli utenti, il che significa che finirò con un join cartesiano se provo a unire la tabella degli utenti con entrambe queste tabelle contemporaneamente . Tuttavia, poiché tutto ciò di cui ho bisogno è contare il numero di record nelle altre due tabelle associate a un determinato utente, una sottoquery dovrebbe essere in grado di fare il trucco. Tuttavia, non sono riuscito a trovare documentazione su Views e sottoquery, quindi ecco cosa ho fatto.
- Creato due campi fittizi
Ho creato due campi fittizi (che chiamerò "download" e "ascolta") tramite hook_views_data (). La definizione del campo è elencata di seguito.
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',
),
)
),
);
Ora, quando configuri una vista per gli utenti, appariranno i campi "Download" e "Ascolta". Tuttavia, il tentativo di eseguire una query ora comporterà un errore poiché i campi fittizi dopo tutto sono campi fittizi. Non esistono. L'unico scopo di questi campi è di segnalare alla nostra implementazione di hook_views_query_alter () che è necessario eseguire alcuni sostituitori.
- Implementa hook_views_query_alter ()
Il trucco qui è verificare se la query fornita include i campi "Download" o "Ascolta". In tal caso, rimuoveremo i campi dalla query e li sostituiremo con le subquery. L'implementazione di questa funzione è la seguente.
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;
}
}
}
}
Tieni presente che stiamo riutilizzando l'alias del campo rimosso per la sottoquery. In questo modo, Views penserà che il valore restituito dalla sottoquery provenga effettivamente dal campo fittizio (che dopotutto non esiste).
Questo è. Non stiamo ottenendo un join cartesiano e sia i "download" che gli "ascolti" vengono conteggiati correttamente.