Блог

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

Первым делом создаем таблицу в базе данных: 

/**
 * Implements hook_schema().
 */
function example_module_schema() {
  $schema['example_table'] = array(
    'fields' => array(
      'nid' => array(
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => FALSE,
        'default' => 0,
        'description' => 'Node {node}.nid.',
      ),
      'uid' => array(
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => FALSE,
        'default' => 0,
        'description' => 'User {users}.uid.',
      ),
      'plai_text_field' => array(
        'description' => 'Example textfield.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'timestamp_field' => array(
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
        'description' => 'Some timestamp.',
      ),
    ),
    'primary key' => array('nid'),
  );
  
  return $schema;
}

Будем записывать в таблицу идентификатор ноды, uid пользователя, какой-то текст относящийся к ноде и пользователю (отзыв, комментарий) и временную метку.

Далее в своем модуле объявляем о том, что мы будем использовать API вьюшек:

/**
 * Implements hook_views_api().
 */
function example_module_views_api() {
  return array(
    'api' => 3,
    'path' => drupal_get_path('module', 'example_module'),
  );
}

Затем создаем файл example_module.views.inc и в нем объявляем hook_views_data(). Первым идет раздел описания таблицы, в котором указываем следующие свойства:

  • "group" - название группы, в которой наша настройка будет выводиться. Например: "Node: Node ID", "Taxonomy: Term description". Это свойство важно для целостности, так как пользовательский интерфейс вьюшек сортирует поля по группам и это облегчит поиск
  • "title" - название поля, оно должно быть понятным и интуитивным
  • "help" - Более подробное описание

Обычно используется только свойство "group".

Если вы хотите, чтобы ваша таблица была центральной во вьюшке, вы можете определить ее как базовую.

В этом случае можно указать следующие свойства:

  • "field" - primary key для объявляемой таблицы. Если вы хотите объявить таблицу базовой, primary key обязателен. Для таблички node primary key - это nid, для users - uid
  • "title" - название таблицы, которое будет отображаться в пользовательском интерфесе
  • "help" - более подробное описание
  • "database" - в случае, если таблица, которую вы объявляете находится в другой базе данных, это поле обязательно

Также мы можем создать неявную связь нашей таблицы с любой другой(в данном примере с таблицей "node"). Для этого в разделе "join" мы можем указать следующие свойства:

  • "handler" -  обработчик, который будет использоваться. По умолчанию это "views_join". Вы можете использовать свой, но для решения общих задач этого не надо
  • "table" - таблица, к которой мы будем присоединятся. Опциональное свойство и в общих случаях бесполезно
  • "field" - поле по которому будем присоединять таблицу - это обязательное свойство
  • "left_table" - следующий шаг для достижение целевой таблицы - промежуточная таблица. Если нет промежуточной, то не указываем это свойство
  • "left_field" - поле по которому будем присоединять таблицу "слева" - это обязательное свойство 
  • "type" - LEFT (по умолчанию) либо INNER
/**
 * Implements hook_views_data()
 */
function example_module_views_data() {
  // The 'group' index will be used as a prefix in the UI for any of this
  // table's fields, sort criteria, etc. so it's easy to tell where they came
  // from.
  $data['example_table']['table']['group'] = t('Example table');

  // Define this as a base table. In reality this is not very useful for
  // this table, as it isn't really a distinct object of its own, but
  // it makes a good example.
  $data['example_table']['table']['base'] = array(
    'field' => 'nid',
    'title' => t('Example table'),
    'help' => t("Example table contains example content and can be related to nodes."),
    'weight' => -10,
  );

  // This table references the {node} table.
  // This creates an 'implicit' relationship to the node table, so that when 'Node'
  // is the base table, the fields are automatically available.
  $data['example_table']['table']['join'] = array(
    // Index this array by the table name to which this table refers.
    // 'left_field' is the primary key in the referenced table.
    // 'field' is the foreign key in this table.
    'node' => array(
      'left_field' => 'nid',
      'field' => 'nid',
    ),
  );

Итак, таблицу мы объявили. Далее нужно описать поля в таблице. Поля могут иметь следующие свойства:

  • "group", "title", "help" - как и для таблицы, значения этих полей используются в пользовательском интерфейсе
  • "real field" - если поле - это синоним, то здесь нужно указать реальное имя поля
  • "field" - объявление массива обработчика для секции "Field". По умолчанию используется "views_handler_field". Если этот параметр указан, то поле появится в списке полей для вывода. Атрибут "click_sortable", установленный в TRUE позволяет сортировку по этому полю(в таблицах например)
  • "filter" - объявление массива обработчика для секции "Filters". По умолчанию используется "views_handler_filter". Если этот параметр указан, то поле появится в списке полей для фильтрации
  • "sort" - объявление массива обработчика для секции "Sort criteria". По умолчанию используется "views_handler_sort". Если этот параметр указан, то поле появится в списке полей для сортировки
  • "relationship" - позволяет добавлять связи по этому полю - секция "Relationship". По умолчанию используется обработчик "views_handler_relationship". Обязательно нужно указать таблицу базовую таблицу для присоединения - элемент "base" и поле, по которому это присоединение будет происходить - элемент "field"
  • "argument" - объявление массива обработчика для секции "Contextual Filters". По умолчанию используется обработчик "views_handler_argument"
 // Next, describe each of the individual fields in this table to Views. For
  // each field, you may define what field, sort, argument, and/or filter
  // handlers it supports. This will determine where in the Views interface you
  // may use the field.

  // Node ID field.
  $data['example_table']['nid'] = array(
    'title' => t('Example content'),
    'help' => t('Some example content that references a node.'),
    // Because this is a foreign key to the {node} table. This allows us to
    // have, when the view is configured with this relationship, all the fields
    // for the related node available.
    'relationship' => array(
      'base' => 'node',
      'field' => 'nid',
      'handler' => 'views_handler_relationship',
      'label' => t('Example node'),
    ),
  );

  // Example plain text field.
  $data['example_table']['plain_text_field'] = array(
    'title' => t('Plain text field'),
    'help' => t('Just a plain text field.'),
    'field' => array(
      'handler' => 'views_handler_field',
      'click sortable' => TRUE,
    ),
    'sort' => array(
      'handler' => 'views_handler_sort',
    ),
    'filter' => array(
      'handler' => 'views_handler_filter_string',
    ),
    'argument' => array(
      'handler' => 'views_handler_argument_string',
    ),
  );


  // Example timestamp field.
  $data['example_table']['timestamp_field'] = array(
    'title' => t('Timestamp field'),
    'help' => t('Just a timestamp field.'),
    'field' => array(
      'handler' => 'views_handler_field_date',
      'click sortable' => TRUE,
    ),
    'sort' => array(
      'handler' => 'views_handler_sort_date',
    ),
    'filter' => array(
      'handler' => 'views_handler_filter_date',
    ),
  );

  return $data;
}

В результате получаем весьма удобный интерфейс, отсутствие необходимости писать миллионы своих запросов и удобство в обслуживании сайта.

Дополнительную информацию можно почерпнуть здесь.

Спасибо за внимание.

Join the conversation
0 Comments