Создание кастомной entity

Создание кастомной entity

С созданием кастомной энтити, наверное, рано или поздно сталкиваются практически все. Entity обладает широкими возможностями: может быть fieldable (расширяема филдами), иметь систему кэширования и т.д. К тому же по умолчанию она будет видна вьюсам и многим другим контрибным модулям, которые работают с entities. Ноды к примеру, довольно гибки и расширяемы, но они не всегда подходят для решения определенных задач. Некоторые возможные причины отказа от использования нод:

  • необходимо использовать специфичную систему пермишенов.
  • необходимо использовать специфичное воркфлоу для обработки и публикации объектов.
  • требуется сущность для быстрого поиска и индекса поисковым движком (например, Solr). Сущность, которая будет хранить все необходимые данные в свой таблице.
  • использование сущности для создания многоуровневых зависимостей.
  • для решения задачи функционал нод избыточен (комментарии, дополнительные поля, атрибуты, ревизионность и пр.)

В статье рассмотрим создание самой простой кастомной энтити (без ревизий, филдов и UI). Энтити будем создавать с помощью широко известного контрибного модуля Entity API[1].

Содержание

Описание hook_entity_info()

Сущность будем создавать в рамках кастомного модуля. Для начала описание файла MYMODULE.info

1
2
3
4
5
6
name = MYMODULE
description = This an example of custom entity.
package = Others
core = 7.x
 
dependencies[] = entity

Для определения энтити используется hook_entity_info()[2]. Инициализация достаточно простая.
в MYMODULE.module

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
 * Implements hook_entity_info().
 */
function MYMODULE_entity_info() {
  $info['MYMODULE_entity'] = array(
    'label' => t('MYMODULE entity'),
    'entity class' => 'Entity',
    'controller class' => 'EntityAPIController',
    'module' => 'MYMODULE',
    'base table' => 'MYMODULE_entity',
    'load hook' => 'MYMODULE_load_entity',
    'entity keys' => array(
      'id' => 'eid',
    ),
  );
 
  return $info;
}

Значения ключей в этом хуке подробно описаны в официальной документации[2], ссылка на которую приведена в конце статьи. Исключения составляет ключ entity class, используемый модулем Entity API. В данном случае используется значение по умолчанию, базовый класс Entity. При необходимости от него можно наследоваться и расширить сущность как угодно.

Описание структуры таблицы

Так как в данной сущности нет ревизий, обойдемся одной таблицей.
в MYMODULE.install

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/**
 * Implements hook_schema().
 */
function MYMODULE_schema() {
  $schema['MYMODULE_entity'] = array(
    'description' => 'The base table for custom entity.',
    'fields' => array(
      'eid' => array(
        'description' => 'The primary identifier for custom entity.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'type' => array(
        'description' => 'The type of custom entity.',
        'type' => 'varchar',
        'length' => 32,
        'not null' => TRUE,
        'default' => '',
      ),
      'title' => array(
        'description' => 'The title of custom entity.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'uid' => array(
        'description' => 'The user ID that created this custom entity.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'created' => array(
        'description' => 'The Unix timestamp when the custom entity was created.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'changed' => array(
        'description' => 'The Unix timestamp when the custom entity was recently saved.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'indexes' => array(
      'uid' => array('uid'),
    ),
    'primary key' => array('eid'),
  );
 
  return $schema;
}

Количество столбцов может быть абсолютно произвольным, в зависимости от того, что сущность должна хранить.

CRUD операции

Собственно, пока entity довольно бесполезна, поэтому пора создать CRUD (create/read/update/delete) функции для работы с ней.
Функция создания entity.

1
2
3
4
5
6
/**
 * Creates an enitty.
 */
function MYMODULE_create_entity($values = array()) {
  return entity_create('MYMODULE_entity', $values);
}

Мультизагрузка нескольких сущностей.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
 * Loads entities multiple.
 *
 * @param array $ids
 *   Array of entities IDs.
 * @param array $conditions
 *   Array of additional conditions.
 * @param bool $reset
 *   Flag determines is needed to reset cache for entities or not.
 *
 * @return mixed
 *   Array of loaded entities or FALSE.
 */
function MYMODULE_load_entity_mulitple($ids, $conditions = array(), $reset = FALSE) {
  return entity_load('MYMODULE_entity', $ids, $conditions, $reset);
}

Загрузка одиночной сущности.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 * Loads a single entity.
 *
 * @param int $id
 *   Entity ID.
 * @param array $conditions
 *   Array of additional conditions.
 * @param bool $reset
 *   Flag determines is needed to reset cache for entity or not.
 *
 * @return mixed
 *   Object of loaded entity or FALSE.
 */
function MYMODULE_load_entity($id, $conditions = array(), $reset = FALSE) {
  $entities = MYMODULE_load_entity_mulitple(array($id), $conditions, $reset);
  return isset($entities[$id]) ? $entities[$id] : FALSE;
}

Операция сохранения/обновления.

1
2
3
4
5
6
/**
 * Saves an entity.
 */
function MYMODULE_save_entity($entity) {
  return entity_save('MYMODULE_entity', $entity);
}

Операция удаления.

1
2
3
4
5
6
/**
 * Deletes an entity.
 */
function MYMODULE_delete_entity($entity) {
  entity_delete('MYMODULE_entity', $entity->eid);
}

Дополнительная информация по статье

  1. https://www.drupal.org/project/entity - страница проекта Entity API.
  2. https://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook_entity_info/7 - описание hook_entity_info().
  3. Версии модулей, используемых в статье: Entity API version = "7.x-1.6"