comment.tokens.inc 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <?php
  2. /**
  3. * @file
  4. * Builds placeholder replacement tokens for comment-related data.
  5. */
  6. use Drupal\Component\Utility\UrlHelper;
  7. use Drupal\Core\Datetime\Entity\DateFormat;
  8. use Drupal\Core\Entity\ContentEntityInterface;
  9. use Drupal\Core\Entity\FieldableEntityInterface;
  10. use Drupal\Core\Render\BubbleableMetadata;
  11. /**
  12. * Implements hook_token_info().
  13. */
  14. function comment_token_info() {
  15. $type = [
  16. 'name' => t('Comments'),
  17. 'description' => t('Tokens for comments posted on the site.'),
  18. 'needs-data' => 'comment',
  19. ];
  20. $tokens = [];
  21. // Provide a integration for each entity type except comment.
  22. foreach (\Drupal::entityTypeManager()->getDefinitions() as $entity_type_id => $entity_type) {
  23. if ($entity_type_id == 'comment' || !$entity_type->entityClassImplements(ContentEntityInterface::class)) {
  24. continue;
  25. }
  26. if (\Drupal::service('comment.manager')->getFields($entity_type_id)) {
  27. // Get the correct token type.
  28. $token_type = ($entity_type_id == 'taxonomy_term') ? 'term' : $entity_type_id;
  29. // @todo Make this work per field. See https://www.drupal.org/node/2031903.
  30. $tokens[$token_type]['comment-count'] = [
  31. 'name' => t("Comment count"),
  32. 'description' => t("The number of comments posted on an entity."),
  33. ];
  34. $tokens[$token_type]['comment-count-new'] = [
  35. 'name' => t("New comment count"),
  36. 'description' => t("The number of comments posted on an entity since the reader last viewed it."),
  37. ];
  38. }
  39. }
  40. // Core comment tokens
  41. $comment['cid'] = [
  42. 'name' => t("Comment ID"),
  43. 'description' => t("The unique ID of the comment."),
  44. ];
  45. $comment['hostname'] = [
  46. 'name' => t("IP Address"),
  47. 'description' => t("The IP address of the computer the comment was posted from."),
  48. ];
  49. $comment['mail'] = [
  50. 'name' => t("Email address"),
  51. 'description' => t("The email address left by the comment author."),
  52. ];
  53. $comment['homepage'] = [
  54. 'name' => t("Home page"),
  55. 'description' => t("The home page URL left by the comment author."),
  56. ];
  57. $comment['title'] = [
  58. 'name' => t("Title"),
  59. 'description' => t("The title of the comment."),
  60. ];
  61. $comment['body'] = [
  62. 'name' => t("Content"),
  63. 'description' => t("The formatted content of the comment itself."),
  64. ];
  65. $comment['langcode'] = [
  66. 'name' => t('Language code'),
  67. 'description' => t('The language code of the language the comment is written in.'),
  68. ];
  69. $comment['url'] = [
  70. 'name' => t("URL"),
  71. 'description' => t("The URL of the comment."),
  72. ];
  73. $comment['edit-url'] = [
  74. 'name' => t("Edit URL"),
  75. 'description' => t("The URL of the comment's edit page."),
  76. ];
  77. // Chained tokens for comments
  78. $comment['created'] = [
  79. 'name' => t("Date created"),
  80. 'description' => t("The date the comment was posted."),
  81. 'type' => 'date',
  82. ];
  83. $comment['changed'] = [
  84. 'name' => t("Date changed"),
  85. 'description' => t("The date the comment was most recently updated."),
  86. 'type' => 'date',
  87. ];
  88. $comment['parent'] = [
  89. 'name' => t("Parent"),
  90. 'description' => t("The comment's parent, if comment threading is active."),
  91. 'type' => 'comment',
  92. ];
  93. $comment['entity'] = [
  94. 'name' => t("Entity"),
  95. 'description' => t("The entity the comment was posted to."),
  96. 'type' => 'entity',
  97. ];
  98. $comment['author'] = [
  99. 'name' => t("Author"),
  100. 'description' => t("The author name of the comment."),
  101. 'type' => 'user',
  102. ];
  103. return [
  104. 'types' => ['comment' => $type],
  105. 'tokens' => [
  106. 'comment' => $comment,
  107. ] + $tokens,
  108. ];
  109. }
  110. /**
  111. * Implements hook_tokens().
  112. */
  113. function comment_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
  114. $token_service = \Drupal::token();
  115. $url_options = ['absolute' => TRUE];
  116. if (isset($options['langcode'])) {
  117. $url_options['language'] = \Drupal::languageManager()->getLanguage($options['langcode']);
  118. $langcode = $options['langcode'];
  119. }
  120. else {
  121. $langcode = NULL;
  122. }
  123. $replacements = [];
  124. if ($type == 'comment' && !empty($data['comment'])) {
  125. /** @var \Drupal\comment\CommentInterface $comment */
  126. $comment = $data['comment'];
  127. foreach ($tokens as $name => $original) {
  128. switch ($name) {
  129. // Simple key values on the comment.
  130. case 'cid':
  131. $replacements[$original] = $comment->id();
  132. break;
  133. // Poster identity information for comments.
  134. case 'hostname':
  135. $replacements[$original] = $comment->getHostname();
  136. break;
  137. case 'mail':
  138. $mail = $comment->getAuthorEmail();
  139. // Add the user cacheability metadata in case the author of the comment
  140. // is not the anonymous user.
  141. if ($comment->getOwnerId()) {
  142. $bubbleable_metadata->addCacheableDependency($comment->getOwner());
  143. }
  144. $replacements[$original] = $mail;
  145. break;
  146. case 'homepage':
  147. $replacements[$original] = UrlHelper::stripDangerousProtocols($comment->getHomepage());
  148. break;
  149. case 'title':
  150. $replacements[$original] = $comment->getSubject();
  151. break;
  152. case 'body':
  153. // "processed" returns a \Drupal\Component\Render\MarkupInterface via
  154. // check_markup().
  155. $replacements[$original] = $comment->comment_body->processed;
  156. break;
  157. case 'langcode':
  158. $replacements[$original] = $comment->language()->getId();
  159. break;
  160. // Comment related URLs.
  161. case 'url':
  162. $url_options['fragment'] = 'comment-' . $comment->id();
  163. $replacements[$original] = $comment->toUrl('canonical', $url_options)->toString();
  164. break;
  165. case 'edit-url':
  166. $url_options['fragment'] = NULL;
  167. $replacements[$original] = $comment->toUrl('edit-form', $url_options)->toString();
  168. break;
  169. case 'author':
  170. $name = $comment->getAuthorName();
  171. // Add the user cacheability metadata in case the author of the comment
  172. // is not the anonymous user.
  173. if ($comment->getOwnerId()) {
  174. $bubbleable_metadata->addCacheableDependency($comment->getOwner());
  175. }
  176. $replacements[$original] = $name;
  177. break;
  178. case 'parent':
  179. if ($comment->hasParentComment()) {
  180. $parent = $comment->getParentComment();
  181. $bubbleable_metadata->addCacheableDependency($parent);
  182. $replacements[$original] = $parent->getSubject();
  183. }
  184. break;
  185. case 'created':
  186. $date_format = DateFormat::load('medium');
  187. $bubbleable_metadata->addCacheableDependency($date_format);
  188. $replacements[$original] = \Drupal::service('date.formatter')->format($comment->getCreatedTime(), 'medium', '', NULL, $langcode);
  189. break;
  190. case 'changed':
  191. $date_format = DateFormat::load('medium');
  192. $bubbleable_metadata->addCacheableDependency($date_format);
  193. $replacements[$original] = \Drupal::service('date.formatter')->format($comment->getChangedTime(), 'medium', '', NULL, $langcode);
  194. break;
  195. case 'entity':
  196. $entity = $comment->getCommentedEntity();
  197. $bubbleable_metadata->addCacheableDependency($entity);
  198. $title = $entity->label();
  199. $replacements[$original] = $title;
  200. break;
  201. }
  202. }
  203. // Chained token relationships.
  204. if ($entity_tokens = $token_service->findwithPrefix($tokens, 'entity')) {
  205. $entity = $comment->getCommentedEntity();
  206. $replacements += $token_service->generate($comment->getCommentedEntityTypeId(), $entity_tokens, [$comment->getCommentedEntityTypeId() => $entity], $options, $bubbleable_metadata);
  207. }
  208. if ($date_tokens = $token_service->findwithPrefix($tokens, 'created')) {
  209. $replacements += $token_service->generate('date', $date_tokens, ['date' => $comment->getCreatedTime()], $options, $bubbleable_metadata);
  210. }
  211. if ($date_tokens = $token_service->findwithPrefix($tokens, 'changed')) {
  212. $replacements += $token_service->generate('date', $date_tokens, ['date' => $comment->getChangedTime()], $options, $bubbleable_metadata);
  213. }
  214. if (($parent_tokens = $token_service->findwithPrefix($tokens, 'parent')) && $parent = $comment->getParentComment()) {
  215. $replacements += $token_service->generate('comment', $parent_tokens, ['comment' => $parent], $options, $bubbleable_metadata);
  216. }
  217. if (($author_tokens = $token_service->findwithPrefix($tokens, 'author')) && $account = $comment->getOwner()) {
  218. $replacements += $token_service->generate('user', $author_tokens, ['user' => $account], $options, $bubbleable_metadata);
  219. }
  220. }
  221. // Replacement tokens for any content entities that have comment field.
  222. elseif (!empty($data[$type]) && $data[$type] instanceof FieldableEntityInterface) {
  223. /** @var $entity \Drupal\Core\Entity\FieldableEntityInterface */
  224. $entity = $data[$type];
  225. foreach ($tokens as $name => $original) {
  226. switch ($name) {
  227. case 'comment-count':
  228. $count = 0;
  229. $fields = array_keys(\Drupal::service('comment.manager')->getFields($entity->getEntityTypeId()));
  230. $definitions = array_keys($entity->getFieldDefinitions());
  231. $valid_fields = array_intersect($fields, $definitions);
  232. foreach ($valid_fields as $field_name) {
  233. $count += $entity->get($field_name)->comment_count;
  234. }
  235. $replacements[$original] = $count;
  236. break;
  237. case 'comment-count-new':
  238. $replacements[$original] = \Drupal::service('comment.manager')->getCountNewComments($entity);
  239. break;
  240. }
  241. }
  242. }
  243. return $replacements;
  244. }