Я посмотрел дальше, но не смог найти никакой документации, описывающей это.
Мне нужен был способ объединения таблицы пользователей с двумя другими таблицами, содержащими данные для пользователей. Однако две другие таблицы находятся в отношении «один ко многим» с таблицей пользователей, что означает, что я получу декартово объединение, если я попытаюсь объединить таблицу пользователей с обеими этими таблицами одновременно , Тем не менее, поскольку все, что мне нужно, это подсчитать количество записей в двух других таблицах, связанных с любым данным пользователем, подзапрос должен быть в состоянии сделать свое дело. Однако я не смог найти никакой документации по представлениям и подзапросам - вот что я сделал.
- Создано два фиктивных поля
Я создал два фиктивных поля (которые я назову «downloads» и «listens») с помощью hook_views_data (). Определение поля приведено ниже.
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',
),
)
),
);
Теперь, когда вы настраиваете представление для пользователей, появятся поля «Загрузки» и «Прослушивания». Однако попытка выполнить запрос сейчас приведет к ошибке, поскольку все фиктивные поля являются фиктивными. Их не существует. Единственная цель этих полей - сообщить нашей реализации hook_views_query_alter (), что ей нужно выполнить несколько замен.
- Реализуйте hook_views_query_alter ()
Хитрость заключается в том, чтобы проверить, включает ли данный запрос поля «Загрузки» или «Прослушивает». Если это произойдет, мы удалим поля из запроса и заменим их подзапросами. Реализация этой функции идет следующим образом.
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;
}
}
}
}
Обратите внимание, что мы повторно используем псевдоним удаленного поля для подзапроса. Таким образом, Views будет думать, что значение, возвращаемое из подзапроса, на самом деле происходит из фиктивного поля (которое в конце концов не существует).
Вот это. Мы не получаем декартово объединение, и «загрузки» и «прослушивания» учитываются правильно.