Spojrzałem dalej, ale tak naprawdę nie mogłem znaleźć żadnej dokumentacji opisującej to.
Potrzebowałem sposobu, aby połączyć tabelę użytkowników z dwoma innymi tabelami przechowującymi dane dla użytkowników. Jednak dwie pozostałe tabele są w relacji „jeden do wielu” z tabelą użytkowników, co oznacza, że skończę z kartezjańskim złączeniem, jeśli spróbuję dołączyć do tabeli użytkowników z tymi dwiema tabelami w tym samym czasie . Ponieważ jednak wszystko, czego potrzebuję, to policzyć liczbę rekordów w dwóch innych tabelach powiązanych z danym użytkownikiem, podzapytanie powinno być w stanie załatwić sprawę. Nie mogłem jednak znaleźć żadnej dokumentacji dotyczącej widoków i podkwerend - oto co zrobiłem.
- Utworzono dwa pola zastępcze
Utworzyłem dwa fikcyjne pola (które nazywam „pobierającymi” i „nasłuchującymi”) za pomocą hook_views_data (). Definicja pola znajduje się poniżej.
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',
),
)
),
);
Teraz, gdy skonfigurujesz widok dla użytkowników, pojawią się pola „Pobrane” i „Słuchaj”. Jednak próba uruchomienia zapytania spowoduje błąd, ponieważ pola zastępcze są przecież polami zastępczymi. Oni nie istnieją. Jedynym celem tych pól jest zasygnalizowanie naszej implementacji hook_views_query_alter (), że musi wykonać kilka wymian.
- Zaimplementuj hook_views_query_alter ()
Sztuczka polega na sprawdzeniu, czy dane zapytanie zawiera pola „Pobrane” lub „Słuchane”. Jeśli tak, usuniemy pola z zapytania i zastąpimy je podzapytaniami. Implementacja tej funkcji przebiega jak poniżej.
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;
}
}
}
}
Zauważ, że ponownie wykorzystujemy alias usuniętego pola dla podzapytania. W ten sposób widoki będą myśleć, że wartość zwrócona z podzapytania faktycznie pochodzi z pola zastępczego (które przecież nie istnieje).
To jest. Nie otrzymujemy przyłączenia kartezjańskiego i zarówno „pobieranie”, jak i „słuchanie” są liczone poprawnie.