Entity API / Custom Date (Timestamp) and Date popup

В тех случаях когда у Вас есть необходимость в том, чтобы у Вашей сущности было свойство, которое бы хранило метку времени (timestamp), и при этом во Views была бы возможность работы с полем как с обычным полем даты (фильтр с использованием date popup) - Используйте hook_entity_property_info_alter или hook_date_views_fields.

Вариант номер 1 - Используем модуль Entity API

Если Вы уже используете модуль Enitty API, то использовать хук hook_entity_property_info_alter будет самым простым вариантом. Предположим свойство сущности, хранящее значение даты, будет иметь название 'date_property' тогда получим:

<?php
/**
 * Implementation of hook_entity_property_info_alter()
 */
function YOURMODULENAME_entity_property_info_alter(&$info) {
  $properties['date_property']['type'] = 'date';
}
?>

Теперь в фильтрах Views появится возможность выбрать новый фильтр - Date: Date [ENTITY_NAME] / Дата: Дата [ИМЯ СУЩНОСТИ]. Подробнее о том, как выбрать фильтр тут (в картинках).

Вариант номер 2 - Пользуемся базовым функционалом Drupal

Смотрим в модуль date views.

/**
 * Implements hook_date_views_fields().
 *
 * All modules that create custom fields that use the
 * 'views_handler_field_date' handler can provide
 * additional information here about the type of
 * date they create so the date can be used by
 * the Date API views date argument and date filter.
 */
function date_views_date_views_fields($field) {
  $values = array(
    // The type of date: DATE_UNIX, DATE_ISO, DATE_DATETIME.
    'sql_type' => DATE_UNIX,
    // Timezone handling options: 'none', 'site', 'date', 'utc' .
    'tz_handling' => 'site',
    // Needed only for dates that use 'date' tz_handling.
    'timezone_field' => '',
    // Needed only for dates that use 'date' tz_handling.
    'offset_field' => '',
    // Array of "table.field" values for related fields that should be
    // loaded automatically in the Views SQL.
    'related_fields' => array(),
    // Granularity of this date field's db data.
    'granularity' => array('year', 'month', 'day', 'hour', 'minute', 'second'),
  );
  switch ($field) {
    case 'users.created':
    case 'users.access':
    case 'users.login':
    case 'node.created':
    case 'node.changed':
    case 'node_revision.timestamp':
    case 'file_managed.timestamp':
    case 'comment.timestamp':
      return $values;
  }
}
/**
 * Implements hook_views_data_alter().
 */
function date_views_views_data_alter(&$data) {
  // Mark all the core date handlers as date fields.
  // This will identify all handlers that directly use the _date handlers,
  // will not pick up any that extend those handlers.
  foreach ($data as $module => &$table) {
    foreach ($table as $id => &$field) {
      foreach (array('field', 'sort', 'filter', 'argument') as $type) {
        if (isset($field[$type]) && isset($field[$type]['handler']) && ($field[$type]['handler'] == 'views_handler_' . $type . '_date')) {
          $field[$type]['is date'] = TRUE;
        }
      }
    }
  }
}

В функции date_views_date_views_fields говорится о том, что любой модуль, который внедряет поле, которое использует views_handler_field_date - должен также дать дополнительную информацию в хуке hook_date_views_fields, для того чтобы модуль date views знал как с ним работать.

В фунции date_views_data_alter - производятся дополнительные изменения, в том случае если вы назначите обработчиком класс с названием, который подходит под шаблон: 'views_handler_' . $type . '_date' - где $type это тип обработчика (фильтр, сортировка, поле или аргумент). И именно по значению элемента 'is date' - модуль date определяет необходимо ли использовать свой функционал.

Ну и в результате, что же нам надо сделать? Нам надо в свой модуль добавить следующее (опять представим, что работаем с полем date_property):

/**
 * Implements hook_views_data().
 */
function YOURMODULE_views_data() {
// .... Entity table descipttion
$data['ENTITYNAME']['date_property'] = array(
  'title' => t('ENTITYNAME - Date field'),
  'field' => array(
    'handler' => 'views_handler_field_date',
  ),
  'sort' => array(
    'handler' => 'views_handler_sort_date',
  ),
  'filter' => array(
    'handler' => 'views_handler_filter_date',
  ),
  'argument' => array(
    'handler' => 'views_handler_argument_date',
  ),
);
}
/**
 * Implements hook_date_views_fields().
 */
function YOURMODULE_date_views_fields($field) {
  $values = array(
    // The type of date: DATE_UNIX, DATE_ISO, DATE_DATETIME.
    'sql_type' => DATE_UNIX,
    // Timezone handling options: 'none', 'site', 'date', 'utc' .
    'tz_handling' => 'site',
    // Needed only for dates that use 'date' tz_handling.
    'timezone_field' => '',
    // Needed only for dates that use 'date' tz_handling.
    'offset_field' => '',
    // Array of "table.field" values for related fields that should be
    // loaded automatically in the Views SQL.
    'related_fields' => array(),
    // Granularity of this date field's db data.
    'granularity' => array('year', 'month', 'day', 'hour', 'minute', 'second'),
  );
  switch ($field) {
    case 'ENTITYNAME.date_property':
      return $values;
  }
}

Где ENTITYNAME - имя Вашей сущности.

Использованные материалы:

Drupal 7
comments powered by Disqus