function field_token_info_alter in Token 8
Same name and namespace in other branches
- 7 token.tokens.inc \field_token_info_alter()
Implements hook_token_info_alter() on behalf of field.module.
We use hook_token_info_alter() rather than hook_token_info() as other modules may already have defined some field tokens.
File
- ./
token.tokens.inc, line 1499 - Token callbacks for the token module.
Code
function field_token_info_alter(&$info) {
$type_info = \Drupal::service('plugin.manager.field.field_type')
->getDefinitions();
// Attach field tokens to their respecitve entity tokens.
foreach (\Drupal::entityTypeManager()
->getDefinitions() as $entity_type_id => $entity_type) {
if (!$entity_type
->entityClassImplements(ContentEntityInterface::class)) {
continue;
}
// Make sure a token type exists for this entity.
$token_type = \Drupal::service('token.entity_mapper')
->getTokenTypeForEntityType($entity_type_id);
if (empty($token_type) || !isset($info['types'][$token_type])) {
continue;
}
$fields = \Drupal::service('entity_field.manager')
->getFieldStorageDefinitions($entity_type_id);
foreach ($fields as $field_name => $field) {
/** @var \Drupal\field\FieldStorageConfigInterface $field */
// Ensure the token implements FieldStorageConfigInterface or is defined
// in token module.
$provider = '';
if (isset($info['types'][$token_type]['module'])) {
$provider = $info['types'][$token_type]['module'];
}
if (!$field instanceof FieldStorageConfigInterface && $provider != 'token') {
continue;
}
// If a token already exists for this field, then don't add it.
if (isset($info['tokens'][$token_type][$field_name])) {
continue;
}
if ($token_type == 'comment' && $field_name == 'comment_body') {
// Core provides the comment field as [comment:body].
continue;
}
// Do not define the token type if the field has no properties.
if (!$field
->getPropertyDefinitions()) {
continue;
}
// Generate a description for the token.
$labels = _token_field_label($entity_type_id, $field_name);
$label = array_shift($labels);
$params['@type'] = $type_info[$field
->getType()]['label'];
if (!empty($labels)) {
$params['%labels'] = implode(', ', $labels);
$description = t('@type field. Also known as %labels.', $params);
}
else {
$description = t('@type field.', $params);
}
$cardinality = $field
->getCardinality();
$cardinality = $cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED || $cardinality > 3 ? 3 : $cardinality;
$field_token_name = $token_type . '-' . $field_name;
$info['tokens'][$token_type][$field_name] = [
'name' => Html::escape($label),
'description' => $description,
'module' => 'token',
// For multivalue fields the field token is a list type.
'type' => $cardinality > 1 ? "list<{$field_token_name}>" : $field_token_name,
];
// Field token type.
$info['types'][$field_token_name] = [
'name' => Html::escape($label),
'description' => t('@label tokens.', [
'@label' => Html::escape($label),
]),
'needs-data' => $field_token_name,
'nested' => TRUE,
];
// Field list token type.
if ($cardinality > 1) {
$info['types']["list<{$field_token_name}>"] = [
'name' => t('List of @type values', [
'@type' => Html::escape($label),
]),
'description' => t('Tokens for lists of @type values.', [
'@type' => Html::escape($label),
]),
'needs-data' => "list<{$field_token_name}>",
'nested' => TRUE,
];
}
// Show a different token for each field delta.
if ($cardinality > 1) {
for ($delta = 0; $delta < $cardinality; $delta++) {
$info['tokens']["list<{$field_token_name}>"][$delta] = [
'name' => t('@type type with delta @delta', [
'@type' => Html::escape($label),
'@delta' => $delta,
]),
'module' => 'token',
'type' => $field_token_name,
];
}
}
// Property tokens.
foreach ($field
->getPropertyDefinitions() as $property => $property_definition) {
if (is_subclass_of($property_definition
->getClass(), 'Drupal\\Core\\TypedData\\PrimitiveInterface')) {
$info['tokens'][$field_token_name][$property] = [
'name' => $property_definition
->getLabel(),
'description' => $property_definition
->getDescription(),
'module' => 'token',
];
}
elseif ($property_definition instanceof DataReferenceDefinitionInterface && $property_definition
->getTargetDefinition() instanceof EntityDataDefinitionInterface) {
$referenced_entity_type = $property_definition
->getTargetDefinition()
->getEntityTypeId();
$referenced_token_type = \Drupal::service('token.entity_mapper')
->getTokenTypeForEntityType($referenced_entity_type);
$info['tokens'][$field_token_name][$property] = [
'name' => $property_definition
->getLabel(),
'description' => $property_definition
->getDescription(),
'module' => 'token',
'type' => $referenced_token_type,
];
}
}
// Provide image_with_image_style tokens for image fields.
if ($field
->getType() == 'image') {
$image_styles = image_style_options(FALSE);
foreach ($image_styles as $style => $description) {
$info['tokens'][$field_token_name][$style] = [
'name' => $description,
'description' => t('Represents the image in the given image style.'),
'type' => 'image_with_image_style',
];
}
}
// Provide format token for datetime fields.
$date_fields = [
'datetime',
'timestamp',
'created',
'changed',
];
if (in_array($field
->getType(), $date_fields, TRUE)) {
$info['tokens'][$field_token_name]['date'] = $info['tokens'][$field_token_name]['value'];
$info['tokens'][$field_token_name]['date']['name'] .= ' ' . t('format');
$info['tokens'][$field_token_name]['date']['type'] = 'date';
}
if ($field
->getType() == 'daterange' || $field
->getType() == 'date_recur') {
$info['tokens'][$field_token_name]['start_date'] = $info['tokens'][$field_token_name]['value'];
$info['tokens'][$field_token_name]['start_date']['name'] .= ' ' . t('format');
$info['tokens'][$field_token_name]['start_date']['type'] = 'date';
$info['tokens'][$field_token_name]['end_date'] = $info['tokens'][$field_token_name]['end_value'];
$info['tokens'][$field_token_name]['end_date']['name'] .= ' ' . t('format');
$info['tokens'][$field_token_name]['end_date']['type'] = 'date';
}
}
}
}