node.tokens.inc 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <?php
  2. /**
  3. * @file
  4. * Builds placeholder replacement tokens for node-related data.
  5. */
  6. use Drupal\Core\Datetime\Entity\DateFormat;
  7. use Drupal\Core\Language\LanguageInterface;
  8. use Drupal\Core\Render\BubbleableMetadata;
  9. use Drupal\user\Entity\User;
  10. /**
  11. * Implements hook_token_info().
  12. */
  13. function node_token_info() {
  14. $type = [
  15. 'name' => t('Nodes'),
  16. 'description' => t('Tokens related to individual content items, or "nodes".'),
  17. 'needs-data' => 'node',
  18. ];
  19. // Core tokens for nodes.
  20. $node['nid'] = [
  21. 'name' => t("Content ID"),
  22. 'description' => t('The unique ID of the content item, or "node".'),
  23. ];
  24. $node['vid'] = [
  25. 'name' => t("Revision ID"),
  26. 'description' => t("The unique ID of the node's latest revision."),
  27. ];
  28. $node['type'] = [
  29. 'name' => t("Content type"),
  30. ];
  31. $node['type-name'] = [
  32. 'name' => t("Content type name"),
  33. 'description' => t("The human-readable name of the node type."),
  34. ];
  35. $node['title'] = [
  36. 'name' => t("Title"),
  37. ];
  38. $node['body'] = [
  39. 'name' => t("Body"),
  40. 'description' => t("The main body text of the node."),
  41. ];
  42. $node['summary'] = [
  43. 'name' => t("Summary"),
  44. 'description' => t("The summary of the node's main body text."),
  45. ];
  46. $node['langcode'] = [
  47. 'name' => t('Language code'),
  48. 'description' => t('The language code of the language the node is written in.'),
  49. ];
  50. $node['url'] = [
  51. 'name' => t("URL"),
  52. 'description' => t("The URL of the node."),
  53. ];
  54. $node['edit-url'] = [
  55. 'name' => t("Edit URL"),
  56. 'description' => t("The URL of the node's edit page."),
  57. ];
  58. // Chained tokens for nodes.
  59. $node['created'] = [
  60. 'name' => t("Date created"),
  61. 'type' => 'date',
  62. ];
  63. $node['changed'] = [
  64. 'name' => t("Date changed"),
  65. 'description' => t("The date the node was most recently updated."),
  66. 'type' => 'date',
  67. ];
  68. $node['author'] = [
  69. 'name' => t("Author"),
  70. 'type' => 'user',
  71. ];
  72. return [
  73. 'types' => ['node' => $type],
  74. 'tokens' => ['node' => $node],
  75. ];
  76. }
  77. /**
  78. * Implements hook_tokens().
  79. */
  80. function node_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
  81. $token_service = \Drupal::token();
  82. $url_options = ['absolute' => TRUE];
  83. if (isset($options['langcode'])) {
  84. $url_options['language'] = \Drupal::languageManager()->getLanguage($options['langcode']);
  85. $langcode = $options['langcode'];
  86. }
  87. else {
  88. $langcode = LanguageInterface::LANGCODE_DEFAULT;
  89. }
  90. $replacements = [];
  91. if ($type == 'node' && !empty($data['node'])) {
  92. /** @var \Drupal\node\NodeInterface $node */
  93. $node = $data['node'];
  94. foreach ($tokens as $name => $original) {
  95. switch ($name) {
  96. // Simple key values on the node.
  97. case 'nid':
  98. $replacements[$original] = $node->id();
  99. break;
  100. case 'vid':
  101. $replacements[$original] = $node->getRevisionId();
  102. break;
  103. case 'type':
  104. $replacements[$original] = $node->getType();
  105. break;
  106. case 'type-name':
  107. $type_name = node_get_type_label($node);
  108. $replacements[$original] = $type_name;
  109. break;
  110. case 'title':
  111. $replacements[$original] = $node->getTitle();
  112. break;
  113. case 'body':
  114. case 'summary':
  115. $translation = \Drupal::entityManager()->getTranslationFromContext($node, $langcode, ['operation' => 'node_tokens']);
  116. if ($translation->hasField('body') && ($items = $translation->get('body')) && !$items->isEmpty()) {
  117. $item = $items[0];
  118. // If the summary was requested and is not empty, use it.
  119. if ($name == 'summary' && !empty($item->summary)) {
  120. $output = $item->summary_processed;
  121. }
  122. // Attempt to provide a suitable version of the 'body' field.
  123. else {
  124. $output = $item->processed;
  125. // A summary was requested.
  126. if ($name == 'summary') {
  127. // Generate an optionally trimmed summary of the body field.
  128. // Get the 'trim_length' size used for the 'teaser' mode, if
  129. // present, or use the default trim_length size.
  130. $display_options = entity_get_display('node', $node->getType(), 'teaser')->getComponent('body');
  131. if (isset($display_options['settings']['trim_length'])) {
  132. $length = $display_options['settings']['trim_length'];
  133. }
  134. else {
  135. $settings = \Drupal::service('plugin.manager.field.formatter')->getDefaultSettings('text_summary_or_trimmed');
  136. $length = $settings['trim_length'];
  137. }
  138. $output = text_summary($output, $item->format, $length);
  139. }
  140. }
  141. // "processed" returns a \Drupal\Component\Render\MarkupInterface
  142. // via check_markup().
  143. $replacements[$original] = $output;
  144. }
  145. break;
  146. case 'langcode':
  147. $replacements[$original] = $node->language()->getId();
  148. break;
  149. case 'url':
  150. $replacements[$original] = $node->url('canonical', $url_options);
  151. break;
  152. case 'edit-url':
  153. $replacements[$original] = $node->url('edit-form', $url_options);
  154. break;
  155. // Default values for the chained tokens handled below.
  156. case 'author':
  157. $account = $node->getOwner() ? $node->getOwner() : User::load(0);
  158. $bubbleable_metadata->addCacheableDependency($account);
  159. $replacements[$original] = $account->label();
  160. break;
  161. case 'created':
  162. $date_format = DateFormat::load('medium');
  163. $bubbleable_metadata->addCacheableDependency($date_format);
  164. $replacements[$original] = format_date($node->getCreatedTime(), 'medium', '', NULL, $langcode);
  165. break;
  166. case 'changed':
  167. $date_format = DateFormat::load('medium');
  168. $bubbleable_metadata->addCacheableDependency($date_format);
  169. $replacements[$original] = format_date($node->getChangedTime(), 'medium', '', NULL, $langcode);
  170. break;
  171. }
  172. }
  173. if ($author_tokens = $token_service->findWithPrefix($tokens, 'author')) {
  174. $replacements += $token_service->generate('user', $author_tokens, ['user' => $node->getOwner()], $options, $bubbleable_metadata);
  175. }
  176. if ($created_tokens = $token_service->findWithPrefix($tokens, 'created')) {
  177. $replacements += $token_service->generate('date', $created_tokens, ['date' => $node->getCreatedTime()], $options, $bubbleable_metadata);
  178. }
  179. if ($changed_tokens = $token_service->findWithPrefix($tokens, 'changed')) {
  180. $replacements += $token_service->generate('date', $changed_tokens, ['date' => $node->getChangedTime()], $options, $bubbleable_metadata);
  181. }
  182. }
  183. return $replacements;
  184. }