Pull to refresh

Модуль Views — API. Основы

Reading time 6 min
Views 11K
Наверняка, многие, работающие с друпалом, знакомы с модулем Views. Как гласит Drupaler.ru, модуль Views — это Настройка и контроль за отображением любого типа контента в любом месте сайта, т.е. он позволяет создавать страницы, блоки, подменять содержимое нод, страниц пользователей и многое другое, формируя контент из любых доступных полей на сайте. Но что делать, когда необходимо вывести информацию, предоставляемую сторонним модулем, и к которой доступа из Views у нас нет?

Чтобы было понятно, далее всё на живом примере:

На сайте я использую модуль PrivateMSG. Он позволяет пользователям отправлять друг другу личные сообщения. С помощью Views я собрал блок, в котором отображается информация о текущем пользователе.

Задача: Отобразить в блоке количество новых сообщений и количество всех сообщений в папке «Входящие» текущего пользователя.

Решение: Написать модуль, который добавил бы в конструктор Views необходимые значения.

К сожалению на просторах интернета очень мало информации по этому поводу, а мануал по Views API довольно сложен и непонятен.

Итак, приступим.
  1. Создаем новый модуль.
    Как положено, создаем директорию, называем её именем нашего будущего модуля. Я назвал его privatemsg_extraviews.
    В директории создаем файлы privatemsg_extraviews.info, privatemsg_extraviews.module, privatemsg_extraviews.views.inc. Далее нам понадобится создать еще 2 файла, но об этом позже.
  2. privatemsg_extraviews.info
    Этот файл содержит информацию о нашем модуле. Нужен, чтобы друпал опознал модуль.
    name = privatemsg_extraviews
    description = Добавляет поддержку views в Private Messages
    core = 6.x
    package = Mail
    version = "6.x-1.1"


    * This source code was highlighted with Source Code Highlighter.

    Этого достаточно, чтобы друпал опознал наш модуль.
  3. privatemsg_extraviews.module
    Основной файл модуля. В нем пишется вся структура модуля, все хуки, и вообще всё-всё.
    Нам нужно лишь указать, что модуль работает с Views.
    <?php

    /**
    * Implementation of hook_views_api().
    */
    function privatemsg_extraviews_views_api() {
     return array(
      'api' => 2, // Указываем версию API
      'path' => drupal_get_path('module', 'privatemsg_extraviews'), // Указываем откуда брать файл для Views
     );
    }


    * This source code was highlighted with Source Code Highlighter.

  4. privatemsg_extraviews.views.inc
    Самое интересное. В этом файле мы и пишем всю систему работы с Views. Модуль его сам найдет, т.к. мы указали директорию в хуке выше.
    Основной хук, который нам потребуется, это hook_views_data(). В нем мы определяем, какую таблицу БД мы добавляем, и какую информацию возвращаем.
    <?php
    function privatemsg_extraviews_views_data() {
      // Определяем новую группу во Views
      $data['privatemsg']['table']['group'] = t('Private Messages');
      // Указываем таблицы
      $data['privatemsg']['table']['join'] = array(
        // users - значит наши значения будут доступны только при выборке пользователей
        'users' => array(
          // Указываем ключи
          'left_field' => 'uid',
          'field' => 'uid',
        ),
      );
      // count - столбец таблицы, по которому будет выборка
      $data['privatemsg']['count'] = array(
        'title' => t('Количество входящих сообщений'),
        'help' => t('Количество сообщений в папке "Входящие"'),
        // Указываем возвращаемое поле
        'field' => array(
          // Обработчик для этого поля
          'handler' => 'privatemsg_extraviews_handler_field_count',
          // Доступна сортировка по этому полю
          'click sortable' => TRUE,
        ),
      );
      // Аналогично
      $data['privatemsg']['count_new'] = array(
        'title' => t('Количество новых сообщений'),
        'help' => t('Количество новых сообщений в папке "Входящие"'),
        'field' => array(
          'handler' => 'privatemsg_extraviews_handler_field_count_new',
          'click sortable' => TRUE,
        ),
      );
      return $data;
    }


    * This source code was highlighted with Source Code Highlighter.


    Далее нам потребуется hook_views_handlers() для инициализации обработчиков полей.
    function privatemsg_extraviews_views_handlers() {
      return array(
        // Обработчики
        'handlers' => array(
          'privatemsg_extraviews_handler_field_count' => array(
            // Указываем, что возвращаем числовое значение
            'parent' => 'views_handler_field_numeric',
            // И путь к файлу обработчика
            'path' => drupal_get_path('module', 'privatemsg_extraviews'),
          ),
          // Аналогично
          'privatemsg_extraviews_handler_field_count_new' => array(
            'parent' => 'views_handler_field_numeric',
            'path' => drupal_get_path('module', 'privatemsg_extraviews'),
          ),
        ),
      );
    }


    * This source code was highlighted with Source Code Highlighter.


    Как я уже и говорил выше, нам понадобится создать еще 2 файла — это как раз обработчики полей. Создадим в директории модуля файлы privatemsg_extraviews_handler_field_count.inc и privatemsg_extraviews_handler_field_count_new.inc.
  5. privatemsg_extraviews_handler_field_count.inc
    Обработчик для поля «Количество сообщений».
    <?php
    // Определяем обработчик, наследуем от стандартного класса "числовое значение"
    class privatemsg_extraviews_handler_field_count extends views_handler_field_numeric {
      // Запрос к БД
      function query() {
        // Определяем таблицу
        $table = $this->query->ensure_table('pm_index');
        // Запрашиваем количество сообщений
        $sql = "SELECT COUNT(DISTINCT thread_id) FROM {pm_index} p WHERE p.deleted = 0 AND p.uid = users.uid";
        // Указываем название для возвращаемого поля
        $this->query->add_field('', "($sql)", 'count');
        $this->field_alias = 'count';
      }
      // Возвращаем полученное значение
      function render($values) {
        $txt = $values->count;
        if ($txt) {
          return $txt;
        }
        else {
          return parent::render($values);
        }
      }
    }

    * This source code was highlighted with Source Code Highlighter.

  6. privatemsg_extraviews_handler_field_count_new.inc
    Обработчик для поля «Количество новых сообщений». (аналогично)
    <?php

    class privatemsg_extraviews_handler_field_count_new extends views_handler_field_numeric {
      function query() {
        $table = $this->query->ensure_table('pm_index');
        $sql = "SELECT COUNT(DISTINCT thread_id) FROM {pm_index} p WHERE p.deleted = 0 AND p.is_new = 1 AND p.uid = users.uid";
        $this->query->add_field('', "($sql)", 'count_new');
        $this->field_alias = 'count_new';
      }

      function render($values) {
        $txt = $values->count_new;
        if ($txt) {
          return $txt;
        }
        else {
          return parent::render($values);
        }
      }
    }


    * This source code was highlighted with Source Code Highlighter.



После всего проделанного Views сформирует запрос типа
SELECT users.uid AS uid,
  (SELECT COUNT(DISTINCT thread_id) FROM pm_index p WHERE p.deleted = 0 AND p.uid = users.uid) AS count,
  (SELECT COUNT(DISTINCT thread_id) FROM pm_index p WHERE p.deleted = 0 AND p.is_new = 1 AND p.uid = users.uid) AS count_new
FROM users users
WHERE users.uid = 1


* This source code was highlighted with Source Code Highlighter.

и вернет необходимые значения.

Надеюсь, инструкция окажется полезной для кого-то. Если будет интерес, могу написать более подробно о Views, там еще много интересного: как создать свои настройки для полей, как создавать поля, доступные в фильтрах и сортировках, свои аргументы и связи, и многое другое.

UPD: Перенес в блог «Drupal». Спасибо за карму.
Tags:
Hubs:
+28
Comments 29
Comments Comments 29

Articles