t('Field collection host entity'), 'description' => t('Tokens related to field collection host entities.'), 'needs-data' => 'field_collection_item', ); // Simple tokens. $host['type'] = array( 'name' => t('Host entity type'), 'description' => t('The entity type of the host. Common types are node and user.'), ); $host['bundle'] = array( 'name' => t('Host entity bundle'), 'description' => t('For node entity types this is the content type, otherwise available as [node:content-type:machine-name].'), ); $host['id'] = array( 'name' => t('Host entity ID'), 'description' => t('The entity ID of the host. For nodes this is nid, for users uid.'), ); // Chained tokens. foreach (field_collection_host_entity_types() as $entity_type => $entity_info) { $host[$entity_type] = array( 'name' => t('Entity: @entity_type', array('@entity_type' => $entity_info['label'])), 'description' => t('Host entity tokens when it is of type %entity_type', array('%entity_type' => $entity_info['label'])), 'type' => $entity_type, ); } return array( 'types' => array('host' => $type), 'tokens' => array('host' => $host), ); } /** * Implements hook_token_info_alter(). * * Inject an additional 'host' token to the 'field_collection_item' token type. */ function field_collection_token_info_alter(&$data) { $data['types']['field_collection_item'] = array( 'name' => t('Field collection'), 'description' => t('Tokens related to field collection.'), 'needs-data' => 'field_collection_item', ); $data['tokens']['field_collection_item']['host'] = array( 'name' => t('Host entity'), 'description' => t('The host entity of this field collection item.'), 'type' => 'host', ); } /** * Implements hook_tokens(). */ function field_collection_tokens($type, $tokens, array $data = array(), array $options = array()) { $replacements = array(); // Provide a complete set of tokens for type == 'host', and a supplementary // token 'host' for type == 'field_collection_item'. if (($type == 'field_collection_item' or $type == 'host') and !empty($data['field_collection_item'])) { $collection = $data['field_collection_item']; // When saving revisions, only $collection->original has valid state about // its host entity. if (!empty($collection->original)) { $collection = $collection->original; } if ($type == 'field_collection_item') { if (!empty($tokens['host'])) { $replacements[$tokens['host']] = $collection->hostEntityId(); } if ($host_tokens = token_find_with_prefix($tokens, 'host')) { $replacements += token_generate('host', $host_tokens, $data, $options); } } // $type == 'host' else { // Mapping between token and the FieldCollectionItemEntity method used to // retrieve the token with. $token_method_map = array( 'type' => 'hostEntityType', 'bundle' => 'hostEntityBundle', 'id' => 'hostEntityId', ); $entity_types = field_collection_host_entity_types(); foreach ($tokens as $name => $orig) { if (isset($token_method_map[$name])) { $replacements[$orig] = $collection->{$token_method_map[$name]}(); } // This replaces e.g. [host:node] and [host:user] with their respective // nid and uid. if (!empty($entity_types[$name])) { $replacements[$orig] = $collection->hostEntityId(); } } foreach ($entity_types as $entity_type => $entity_info) { if ($entity_tokens = token_find_with_prefix($tokens, $entity_type)) { $host = $collection->hostEntity(); $replacements += token_generate($entity_type, $entity_tokens, array($entity_type => $host), $options); } } } } return $replacements; } /** * Entity types that serve as host for field collections. * * @return array * The list of entities as provided by entity_get_info(), filtered by field * collection usage. */ function field_collection_host_entity_types() { $host_entity_types = &drupal_static(__FUNCTION__, FALSE); if ($host_entity_types === FALSE) { $host_entity_types = array(); $entity_types = entity_get_info(); // Look for all field instances, filter them by type == 'field_collection' // and map the entity type it's connected to to the returned list. foreach (field_info_field_map() as $field_instance) { if ($field_instance['type'] == 'field_collection') { foreach (array_keys($field_instance['bundles']) as $entity_type) { if (!isset($host_entity_types[$entity_type])) { // No need to test for existence in $entity_types. If it's not there // your site is broken. $host_entity_types[$entity_type] = $entity_types[$entity_type]; } } } } } return $host_entity_types; }