Есть у 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
— новые свойства сразу появятся.