Я подивився далі, але не зміг знайти жодної документації, яка б описувала це.
Мені потрібен спосіб з'єднати таблицю користувачів з двома іншими таблицями, що містять дані для користувачів. Однак дві інші таблиці знаходяться у взаємозв'язку з таблицею користувачів, що означає, що я закінчуся декартовим приєднанням, якщо спробую одночасно приєднати таблицю користувачів з обома цими таблицями. . Однак, оскільки все, що мені потрібно, - це підрахувати кількість записів у двох інших таблицях, пов’язаних з будь-яким даним користувачем, підзапит повинен мати можливість виконувати трюк. Однак я не зміг знайти жодної документації щодо Переглядів та підзапитів - ось ось що я зробив.
- Створили два манекенні поля
Я створив два фіктивних поля (які я буду називати "завантаженнями" і "слухає") за допомогою mock_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',
),
)
),
);
Тепер, коли ви налаштуєте подання для користувачів, з'являться поля "Завантаження" та "Слухання". Однак спроба запустити запит тепер призведе до помилки, оскільки фіктивні поля зрештою є фіктивними полями. Їх не існує. Єдина мета цих полів - повідомити нашому впровадженню куки_види_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 подумає, що значення, повернене з підзапиту, насправді надходить із поля манекена (якого зрештою не існує).
Це так. Ми не отримуємо декартового приєднання, і "завантаження", і "прослуховування" зараховуються правильно.