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