diff --git a/tests/src/Kernel/FieldTest.php b/tests/src/Kernel/FieldTest.php index 90499b7..ae052cc 100644 --- a/tests/src/Kernel/FieldTest.php +++ b/tests/src/Kernel/FieldTest.php @@ -7,11 +7,11 @@ namespace Drupal\Tests\token\Kernel; +use Drupal\Component\Utility\Html; use Drupal\Component\Utility\Unicode; use Drupal\Core\Entity\Entity\EntityViewMode; -use Drupal\Core\Render\BubbleableMetadata; +use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Render\Markup; -use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; use Drupal\filter\Entity\FilterFormat; @@ -287,7 +287,10 @@ class FieldTest extends KernelTestBase { $term_reference_field_value = $this->randomString(); $term_reference = $this->createTerm($this->vocabulary, [ 'name' => 'Term to reference', - 'term_field' => $term_reference_field_value, + 'term_field' => [ + 'value' => $term_reference_field_value, + 'format' => $this->testFormat->id(), + ], ]); $entity = Node::create([ 'title' => 'Test entity reference', @@ -300,7 +303,46 @@ class FieldTest extends KernelTestBase { $this->assertTokens('node', ['node' => $entity], [ 'test_reference:title' => Markup::create('Test node to reference'), 'test_reference:test_field' => Markup::create('foo'), - 'test_term_reference:term_field' => Markup::create($term_reference_field_value), + 'test_term_reference:term_field' => Html::escape($term_reference_field_value), + ]); + } + + /** + * Tests support for cardinality > 1 chaining. + */ + public function testMultivalueCardinality() { + /** @var \Drupal\field\FieldStorageConfigInterface $storage */ + $storage = FieldStorageConfig::load('node.test_term_reference'); + $storage->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); + $storage->save(); + + // Add a few terms. + $terms = []; + foreach (range(1, 3) as $i) { + $terms[$i] = $this->createTerm($this->vocabulary, [ + 'name' => $this->randomString(), + 'term_field' => [ + 'value' => $this->randomString(), + 'format' => $this->testFormat->id(), + ], + ]); + } + + $entity = Node::create([ + 'title' => 'Test multivalue chained tokens', + 'type' => 'article', + 'test_term_reference' => [ + ['target_id' => $terms[1]->id()], + ['target_id' => $terms[2]->id()], + ['target_id' => $terms[3]->id()], + ], + ]); + $entity->save(); + + $this->assertTokens('node', ['node' => $entity], [ + 'test_term_reference:0:term_field' => Html::escape($terms[1]->term_field->value), + 'test_term_reference:1:term_field' => Html::escape($terms[2]->term_field->value), + 'test_term_reference:2:term_field' => Html::escape($terms[3]->term_field->value), ]); } diff --git a/token.tokens.inc b/token.tokens.inc index e12c1ff..e900bea 100644 --- a/token.tokens.inc +++ b/token.tokens.inc @@ -1232,10 +1232,14 @@ function field_token_info_alter(&$info) { // For a single field timestamps and entity references can be chained. if ($field_cardinality == 1) { if (isset($field_property_definition['value']) && ($field_property_definition['value']->getDataType() == 'timestamp' )) { + // Date field. $info['tokens'][$token_type][$field_name]['type'] = 'date'; } elseif (isset($field_property_definition['entity'])) { + // Entity reference field. $entity_type = $field_property_definition['entity']->getTargetDefinition()->getEntityTypeId(); + // Convert to token type. + $entity_type = \Drupal::service('token.entity_mapper')->getTokenTypeForEntityType($entity_type); $info['tokens'][$token_type][$field_name]['type'] = $entity_type; } } @@ -1430,7 +1434,8 @@ function field_tokens($type, $tokens, array $data = array(), array $options = ar foreach ($chained_field_token_candidates as $chained_field_token_name => $chained_field_token_info) { if ($chained_field_tokens = $token_service->findWithPrefix($tokens, $chained_field_token_name)) { $chained_data = $chained_field_token_info['data']; - $chained_token_type = $chained_field_token_info['chained_token_type']; + // Convert to token type. + $chained_token_type = \Drupal::service('token.entity_mapper')->getTokenTypeForEntityType($chained_field_token_info['chained_token_type'], TRUE); $replacements += $token_service->generate($chained_token_type, $chained_field_tokens, $chained_data, $options, $bubbleable_metadata); } } @@ -1469,7 +1474,8 @@ function field_tokens($type, $tokens, array $data = array(), array $options = ar elseif($type != 'multiple_field_value') { $field_storage_definition = $field->getFieldDefinition()->getFieldStorageDefinition(); $field_property_definition = $field_storage_definition->getPropertyDefinitions(); - $chained_token_type = $field_property_definition['entity']->getTargetDefinition()->getEntityTypeId(); + // Convert entity type to token type. + $chained_token_type = \Drupal::service('token.entity_mapper')->getTokenTypeForEntityType($field_property_definition['entity']->getTargetDefinition()->getEntityTypeId()); $chained_entity = $field[$delta]->entity; if ($langcode && $chained_entity->hasTranslation($langcode)) { $chained_entity = $chained_entity->getTranslation($langcode);