Добавляем сущности произвольное свойство

Есть у Entity API в Drupal 7 такой любопытный хук — hook_entity_property_info_alter(). Он позволяет очень быстро добавить к любой сущности (например, к ноде) новое свойство, вычисляемое функцией, указанной в этом же хуке.

Допустим, у нас есть тип содержимого «фотоальбом» (album), а к нему через entity reference прикреплены материалы-фотографии. И нам нужно получить количество прикрепленных фотографий (ниже напишу, зачем). Определим такой хук:

function mymodule_entity_property_info_alter(&$info) {
  // photos count in album
  if (isset($info['node']['bundles']['album'])) {
    $info['node']['bundles']['album']['properties']['photos_count'] = array(
      'label' => t('Photos count'),
      'description' => t('Count of photos in the album'),
      'type' => 'integer',
      'getter callback' => 'mymodule_get_album_photos_count',
      'data' => array(),
    );
  }
}

Здесь мы добавляем свойство photos_count к материалам album и говорим, что свойство вычисляется в функции mymodule_get_album_photos_count():

function mymodule_get_album_photos_count($entity) {
  if (isset($entity->album_photos[LANGUAGE_NONE])) {
    return count($entity->album_photos[LANGUAGE_NONE]);
  } else {
    return 0;
  }
}

В функции мы просто считаем количество референсов в поле album_photos и возвращаем его. Это настолько тривиально, что можно делать на лету и никакие новые свойства не определять. Но дело в том, что определенные таким образом свойства автоматически становятся доступны во Views и, что еще важнее, в Search API.

То есть, этим способом можно, например, легко добавить в индексы Solr то, чего там нет — счетчики флагов, юзеров в группе, или экземпляров множественного поля.

Также нужно отметить, что новые свойства добавляются в метаданные сущности. То есть если мы вызовем обычный node_load(), в полученном объекте этих свойств не будет. А вот если обратиться к сущности через EntityMetadataWrapper — новые свойства сразу появятся.

Комментарии