10/27/2020, by Ivan

Модуль Views широко используется в экосистеме Drupal. Списки, таблицы, блоки, слайдшоу, экспорт данных - все это обычно выводится через Views. Если вы используете Типы материлов, Типы блоков или другие типы сущностей, то Views работает с ними автоматически и вы можете выводить свои данные через него. Но если вы пишите свой модуль и используете отдельную таблицу с данными, созданную вами, тогда вам нужно писать интеграцию со Views, чтобы данные были видны модулю Views.

Давайте рассмотрим интеграцию со Views в модуле Did this help:

https://www.drupal.org/project/did_this_help

Этот модуль использует свою отдельную таблицу для хранения данных. Среди данных есть строки, IDs, даты, поэтому мы должны указывать разные обработчики при интеграции с Views:

Did this help database

Сначала нам нужно добавить файл MODULENAME.views.inc, этот файл будет автоматически подключатся, так что нам не нужно допольнительно указывать где этот *.views.inc находится в файле описания модуля *.info.yml. В файле *.views.inc нужно добавить хук hook_views_data():

<?php

/**
 * @file
 * Provide views data for did_this_help.module.
 */

/**
 * Implements hook_views_data().
 */
function did_this_help_views_data() {

}

В этом хуке мы должны вернуть массив описывающий структуру таблицы базы данных нашего модуля.

https://api.drupal.org/api/drupal/core%21modules%21views%21views.api.php/function/hook_views_data/9.0.x

Сначала мы должны описать название таблицы:
 

  $data['did_this_help'] = [
    'table' => [
      'group' => t('Did this help?'),
      'base' => [
        'field' => 'id',
        'title' => t('Did this help? entries'),
        'help' => t('Contains a list of Did this help? entries.'),
      ],
    ],
  ];

Мы указываем название таблицы в ключе массива $data['did_this_help'], если вам нужно добавить интеграцию с несколькими таблицами, тогда нужно использовать разные ключи для массива $data: $data['did_this_help1'], $data['did_this_help2'].

Дальше во вложенном массиве 'table' идет описание таблицы:

group - позволяет группировать поля из разных таблиц в один раздел при выборе поля в UI Views.

base - указание serial ID для этой таблицы, в дальнейшем по serial ID можно строить связи с другими таблицами по внешним ключам.

Дальше мы описываем каждый из полей, которые хотим выводить через Views:

$data['did_this_help']['id']= [
  'real field' => 'id',
  'title' => t('Did this help? record ID'),
  'help' => t('Did this help? record.'),
  'field' => [
    'id' => 'standard',
  ],
  'sort' => [
    'id' => 'standard',
  ],
  'filter' => [
    'id' => 'numeric',
  ],
  'argument' => [
    'id' => 'numeric',
  ],  
];

real field - позволяет указать настоящее имя поля (колонки в таблице базы данных), если используются alias'ы (синонимы) полей. Для одного поля Drupal могут буть несколько разных значений, например у поля Link есть два значения Title и URI. Для каждого из значений есть своя колонка в таблице базы данных, название каждой колонки состоит из имени поля в сущности и имени значения (title, uri):

Link DB table

Названия этих колонок указываются для модуля Link автоматически, но для кастомных модулей значение "real field" нужно указывать в hook_views_data().

title, help - Информация, которая отображается в UI модуля Views.

Дальше идут IDs обработчиков (хэндлеров, handlers) для поля: field, sort, filter, argument. Handler определяет каким образом фильтровать и выводить поле, например дату нужно выводить в виде Date Format, а фильтровать с помощью Date Calendar Popup. Для чисел нужен фильтр >, < и =, для строк фильтр по длине строки.

Field handlers

Field handlers помогают в формирование SQL запроса для полей, после слова SELECT.

Список Views field handlers из ядра Drupal вы можете найти здесь:

https://api.drupal.org/api/drupal/core%21modules%21views%21src%21Plugin%21views%21field%21FieldPluginBase.php/group/views_field_handlers/8.6.x

Для кастомных модулей чаще всего нужно будет использовать standard для чисел и строк, для данных с датами использовать date.

Так например для поля id, мы используем field handler "standard":

    'id' => [
      'real field' => 'id',
      'title' => t('Did this help? record ID'),
      'help' => t('Did this help? record.'),
      'field' => [
        'id' => 'standard',
      ],
      'sort' => [
        'id' => 'standard',
      ],
      'filter' => [
        'id' => 'numeric',
      ],
      'argument' => [
        'id' => 'numeric',
      ],
    ],

Sort handlers

Sort handlers используются как для обычных сортировок, так и для exposed сортировок во Views. Sort handlers помогают сформировать часть SQL запроса после слов ORDER BY

Список sort handlers вы можете посмотреть здесь:

https://api.drupal.org/api/drupal/core%21modules%21views%21src%21Plugin%21views%21sort%21SortPluginBase.php/group/views_sort_handlers/8.6.x

Filter handlers

Filter handlers используются как для обычных фильтров, так и для exposed, contextual фильтров во Views. Filter handlers помогают сформировать SQL запрос после слова WHERE.

Список filter handlers вы можете посмотреть здесь:

https://api.drupal.org/api/drupal/core%21modules%21views%21src%21Plugin%21views%21filter%21FilterPluginBase.php/group/views_filter_handlers/8.6.x

Для того чтобы фильтровать даты с помощью Date Calendar popup мы будем использовать handler "date":

  $data['did_this_help']['created'] = [
    'title' => t('Created date for Did this help? record'),
    'help' => t('Created date for Did this help? record'),
    'field' => [
      'id' => 'date',
    ],
    'argument' => [
      'id' => 'date',
    ],
    'filter' => [
      'id' => 'date',
    ],
    'sort' => [
      'id' => 'date',
    ],
  ];

Relationship handler

Relationship handlers помогают добавить в SQL запрос join и выводить данные из нескольких таблиц сразу.

В таблице модуля Did this help? есть колонка с ID пользователями. С помощью relationship handler можно добавить связи в UI Views между строками did_this_help и пользователями и вывести данные сразу из таблиц пользователя и did_this_help:

  $data['did_this_help']['uid'] = [
    'title' => t('User ID for Did this help? record'),
    'help' => t('User ID for Did this help? record'),
    'field' => [
      'id' => 'standard',
    ],
    'sort' => [
      'id' => 'standard',
    ],
    'filter' => [
      'id' => 'numeric',
    ],
    'argument' => [
      'id' => 'numeric',
    ],
    'relationship' => [
      'title' => t('User'),
      'help' => t('The user on which the log entry as written.'),
      'base' => 'users_field_data',
      'base field' => 'uid',
      'id' => 'standard',
    ],
  ];

Для этого указываем relationship для поля, где указываем "base" c какой таблицей мы будем связывать нашу таблицу, по какому полю будем связывать в "base field", title и help для UI Views, id relationship handler. Какие доступны relationship вы можете посмотреть в этом списке:

https://api.drupal.org/api/drupal/core%21modules%21views%21src%21Plugin%21views%21relationship%21RelationshipPluginBase.php/group/views_relationship_handlers/8.6.x

Несмотря на то, что Views предоставляет широкий набор различных handler'ов, вы можете наследовать класс base handler'a и написать свой кастомный handler для поля, фильтра, сортировки. В следующей статье мы напишем свой кастомный фильтр с помощью views handler.

 

No war