function field_tokens_tokens in Field tokens 8
Same name and namespace in other branches
- 7 field_tokens.tokens.inc \field_tokens_tokens()
Implements hook_tokens().
File
- ./
field_tokens.tokens.inc, line 166 - Token functions for Field tokens module.
Code
function field_tokens_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
/** @var \Drupal\token\Token $token_service */
$token_service = \Drupal::token();
/** @var \Drupal\Core\Field\FormatterPluginManager $formatter_manager */
$formatter_manager = \Drupal::service('plugin.manager.field.formatter');
$url_options = [
'absolute' => TRUE,
];
$langcode = NULL;
if (isset($options['langcode'])) {
$url_options['language'] = \Drupal::languageManager()
->getLanguage($options['langcode']);
$langcode = $options['langcode'];
}
$replacements = [];
$token_types = [
'formatted' => [
'token_type' => 'formatted_field',
'field_type' => TRUE,
],
'property' => [
'token_type' => 'field_property',
'field_type' => FALSE,
],
];
// Entity tokens.
if ($type == 'entity' && !empty($data['entity'])) {
/** @var \Drupal\Core\Entity\ContentEntityBase $entity */
$entity = $data['entity'];
$fields = $entity
->getFieldDefinitions();
/** @var \Drupal\field\Entity\FieldConfig $field */
foreach ($fields as $field_name => $field) {
if ($field instanceof FieldConfig) {
foreach ($token_types as $token_type => $token_type_info) {
$field_tokens = $token_service
->findWithPrefix($tokens, "{$field_name}-{$token_type}");
if ($field_tokens) {
$token_data_type = $token_type_info['field_type'] ? "{$token_type_info['token_type']}-{$field->getType()}" : $token_type_info['token_type'];
foreach ($field_tokens as $name => $original) {
/** @var \Drupal\Core\Field\FieldItemList $items */
$items = $entity->{$field_name};
if (!$items
->isEmpty()) {
$parts = explode(':', $name);
$deltas = explode(',', array_shift($parts));
$diff = array_diff(array_values($deltas), array_keys($items
->getValue()));
if (empty($diff)) {
$token_items = [];
foreach ($deltas as $delta) {
$token_items[] = $items[$delta];
}
/** @var \Drupal\Core\Field\FieldItemBase $item */
foreach ($token_items as $item) {
if ($item
->isEmpty()) {
continue 2;
}
}
// Pass through to chained field tokens.
$chained_data = array_merge($data, [
$token_data_type => $token_items,
'field' => $field,
]);
$replacements += $token_service
->generate($token_data_type, [
implode(':', $parts) => $original,
], $chained_data, $options, $bubbleable_metadata);
}
}
}
}
}
}
}
}
elseif (strpos($type, 'formatted_field') === 0 && isset($data[$type]) && isset($data['entity_type']) && isset($data['entity'])) {
/** @var \Drupal\Core\Entity\ContentEntityBase $entity */
$entity = $data['entity'];
/** @var \Drupal\field\Entity\FieldConfig $field */
$field = $data['field'];
$field_type = \Drupal::service('plugin.manager.field.field_type')
->getDefinition($field
->getType());
/** @var \Drupal\Core\Entity\Entity\EntityViewDisplay $display */
$view_mode = \Drupal::entityTypeManager()
->getStorage('entity_view_display')
->load($entity
->getEntityTypeId() . '.' . $entity
->getType() . '.default');
$display = $view_mode
->getComponent($field
->get('field_name'));
$display['field_definition'] = $field;
$display['view_mode'] = 'default';
$items = $data[$type];
$formatters = $formatter_manager
->getDefinitions();
foreach ($tokens as $args => $original) {
$args = explode(':', $args);
$formatter_name = $field_type['default_formatter'];
$formatter_settings = [];
if (!empty($args[0])) {
$formatter_name = array_shift($args);
foreach ($args as $formatter_setting) {
list($name, $value) = explode('-', $formatter_setting, 2);
$formatter_settings[$name] = $value;
}
}
if (!is_null($formatter_name) && isset($formatters[$formatter_name]) && in_array($field_type['id'], $formatters[$formatter_name]['field_types'])) {
$default_settings = $formatter_manager
->getDefaultSettings($formatter_name);
if (!empty($default_settings)) {
$formatter_settings += $default_settings;
}
// Inject formatter and formatter settings into $display.
$display['type'] = $formatter_name;
$display['settings'] = isset($formatter_settings) ? $formatter_settings : $default_settings;
// Clone entity.
$cloned_entity = clone $entity;
foreach ($items as &$item) {
$item = $item
->getValue();
}
$cloned_entity->{$field
->get('field_name')}
->setValue($items);
$output = '';
$element = $cloned_entity->{$field
->get('field_name')}
->view($display);
if ($element) {
foreach (Element::children($element) as $delta) {
$output .= \Drupal::service('renderer')
->renderPlain($element[$delta]);
}
}
if (!empty($output)) {
$replacements[$original] = Markup::create($output);
}
}
}
}
elseif ($type == 'field_property') {
/** @var FieldConfig $field */
$field = $data['field'];
foreach ($tokens as $args => $original) {
$output = [];
$args = explode(':', $args);
$property = array_shift($args);
/** @var Drupal\Core\Field\FieldItemBase $item */
foreach ($data['field_property'] as $item) {
$properties = $field
->getFieldStorageDefinition()
->getPropertyDefinitions();
if (isset($properties[$property]) && $properties[$property] instanceof DataReferenceDefinition && !empty($args)) {
$reference = $item
->get($property)
->getValue();
if ($reference instanceof EntityInterface) {
/** @var \Drupal\token\TokenEntityMapper $token_entity_mapper */
$token_entity_mapper = \Drupal::service('token.entity_mapper');
$token_type = $token_entity_mapper
->getTokenTypeForEntityType($reference
->getEntityTypeId());
$chained_data = [
$token_type => $reference,
];
$output[] = $token_service
->generate($token_type, [
implode(':', $args) => $original,
], $chained_data, $options, $bubbleable_metadata)[$original];
}
}
else {
$value = $item
->get($property)
->getValue();
if (is_string($value)) {
$output[] = $value;
}
}
}
if (!empty($output)) {
$replacements[$original] = Markup::create(implode(', ', $output));
}
}
}
return $replacements;
}