comment.tokens.inc 9.48 KB
Newer Older
1 2 3 4 5 6 7
<?php

/**
 * @file
 * Builds placeholder replacement tokens for comment-related data.
 */

8
use Drupal\Component\Utility\UrlHelper;
9
use Drupal\Core\Datetime\Entity\DateFormat;
10 11
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
12
use Drupal\Core\Render\BubbleableMetadata;
13

14
/**
15
 * Implements hook_token_info().
16 17
 */
function comment_token_info() {
18
  $type = [
19 20 21
    'name' => t('Comments'),
    'description' => t('Tokens for comments posted on the site.'),
    'needs-data' => 'comment',
22
  ];
23

24 25 26
  $tokens = [];
  // Provide a integration for each entity type except comment.
  foreach (\Drupal::entityTypeManager()->getDefinitions() as $entity_type_id => $entity_type) {
27
    if ($entity_type_id == 'comment' || !$entity_type->entityClassImplements(ContentEntityInterface::class)) {
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
      continue;
    }

    if (\Drupal::service('comment.manager')->getFields($entity_type_id)) {
      // Get the correct token type.
      $token_type = ($entity_type_id == 'taxonomy_term') ? 'term' : $entity_type_id;

      // @todo Make this work per field. See https://www.drupal.org/node/2031903.
      $tokens[$token_type]['comment-count'] = [
        'name' => t("Comment count"),
        'description' => t("The number of comments posted on an entity."),
      ];
      $tokens[$token_type]['comment-count-new'] = [
        'name' => t("New comment count"),
        'description' => t("The number of comments posted on an entity since the reader last viewed it."),
      ];
    }
  }
46 47

  // Core comment tokens
48
  $comment['cid'] = [
49 50
    'name' => t("Comment ID"),
    'description' => t("The unique ID of the comment."),
51 52
  ];
  $comment['hostname'] = [
53 54
    'name' => t("IP Address"),
    'description' => t("The IP address of the computer the comment was posted from."),
55 56
  ];
  $comment['mail'] = [
57 58
    'name' => t("Email address"),
    'description' => t("The email address left by the comment author."),
59 60
  ];
  $comment['homepage'] = [
61 62
    'name' => t("Home page"),
    'description' => t("The home page URL left by the comment author."),
63 64
  ];
  $comment['title'] = [
65 66
    'name' => t("Title"),
    'description' => t("The title of the comment."),
67 68
  ];
  $comment['body'] = [
69 70
    'name' => t("Content"),
    'description' => t("The formatted content of the comment itself."),
71 72
  ];
  $comment['langcode'] = [
73 74
    'name' => t('Language code'),
    'description' => t('The language code of the language the comment is written in.'),
75 76
  ];
  $comment['url'] = [
77 78
    'name' => t("URL"),
    'description' => t("The URL of the comment."),
79 80
  ];
  $comment['edit-url'] = [
81 82
    'name' => t("Edit URL"),
    'description' => t("The URL of the comment's edit page."),
83
  ];
84 85

  // Chained tokens for comments
86
  $comment['created'] = [
87 88 89
    'name' => t("Date created"),
    'description' => t("The date the comment was posted."),
    'type' => 'date',
90 91
  ];
  $comment['changed'] = [
92 93 94
    'name' => t("Date changed"),
    'description' => t("The date the comment was most recently updated."),
    'type' => 'date',
95 96
  ];
  $comment['parent'] = [
97 98 99
    'name' => t("Parent"),
    'description' => t("The comment's parent, if comment threading is active."),
    'type' => 'comment',
100 101
  ];
  $comment['entity'] = [
102 103 104
    'name' => t("Entity"),
    'description' => t("The entity the comment was posted to."),
    'type' => 'entity',
105 106
  ];
  $comment['author'] = [
107
    'name' => t("Author"),
108
    'description' => t("The author name of the comment."),
109
    'type' => 'user',
110
  ];
111

112 113 114
  return [
    'types' => ['comment' => $type],
    'tokens' => [
115
      'comment' => $comment,
116 117
    ] + $tokens,
  ];
118 119 120
}

/**
121
 * Implements hook_tokens().
122
 */
123
function comment_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
124
  $token_service = \Drupal::token();
125

126
  $url_options = ['absolute' => TRUE];
127
  if (isset($options['langcode'])) {
128
    $url_options['language'] = \Drupal::languageManager()->getLanguage($options['langcode']);
129
    $langcode = $options['langcode'];
130 131
  }
  else {
132
    $langcode = NULL;
133
  }
134
  $replacements = [];
135 136

  if ($type == 'comment' && !empty($data['comment'])) {
137
    /** @var \Drupal\comment\CommentInterface $comment */
138 139 140 141 142 143
    $comment = $data['comment'];

    foreach ($tokens as $name => $original) {
      switch ($name) {
        // Simple key values on the comment.
        case 'cid':
144
          $replacements[$original] = $comment->id();
145 146
          break;

147
        // Poster identity information for comments.
148
        case 'hostname':
149
          $replacements[$original] = $comment->getHostname();
150 151 152
          break;

        case 'mail':
153
          $mail = $comment->getAuthorEmail();
154 155 156 157 158
          // Add the user cacheability metadata in case the author of the comment
          // is not the anonymous user.
          if ($comment->getOwnerId()) {
            $bubbleable_metadata->addCacheableDependency($comment->getOwner());
          }
159
          $replacements[$original] = $mail;
160 161 162
          break;

        case 'homepage':
163
          $replacements[$original] = UrlHelper::stripDangerousProtocols($comment->getHomepage());
164 165 166
          break;

        case 'title':
167
          $replacements[$original] = $comment->getSubject();
168 169 170
          break;

        case 'body':
171 172
          // "processed" returns a \Drupal\Component\Render\MarkupInterface via
          // check_markup().
173
          $replacements[$original] = $comment->comment_body->processed;
174 175
          break;

176
        case 'langcode':
177
          $replacements[$original] = $comment->language()->getId();
178 179
          break;

180 181
        // Comment related URLs.
        case 'url':
182
          $url_options['fragment'] = 'comment-' . $comment->id();
183
          $replacements[$original] = $comment->url('canonical', $url_options);
184 185 186
          break;

        case 'edit-url':
187
          $url_options['fragment'] = NULL;
188
          $replacements[$original] = $comment->url('edit-form', $url_options);
189 190 191
          break;

        case 'author':
192
          $name = $comment->getAuthorName();
193 194 195 196 197
          // Add the user cacheability metadata in case the author of the comment
          // is not the anonymous user.
          if ($comment->getOwnerId()) {
            $bubbleable_metadata->addCacheableDependency($comment->getOwner());
          }
198
          $replacements[$original] = $name;
199 200 201
          break;

        case 'parent':
202 203
          if ($comment->hasParentComment()) {
            $parent = $comment->getParentComment();
204
            $bubbleable_metadata->addCacheableDependency($parent);
205
            $replacements[$original] = $parent->getSubject();
206 207 208 209
          }
          break;

        case 'created':
210 211
          $date_format = DateFormat::load('medium');
          $bubbleable_metadata->addCacheableDependency($date_format);
212
          $replacements[$original] = format_date($comment->getCreatedTime(), 'medium', '', NULL, $langcode);
213 214 215
          break;

        case 'changed':
216 217
          $date_format = DateFormat::load('medium');
          $bubbleable_metadata->addCacheableDependency($date_format);
218
          $replacements[$original] = format_date($comment->getChangedTime(), 'medium', '', NULL, $langcode);
219 220
          break;

221
        case 'entity':
222
          $entity = $comment->getCommentedEntity();
223
          $bubbleable_metadata->addCacheableDependency($entity);
224
          $title = $entity->label();
225
          $replacements[$original] = $title;
226 227 228 229 230
          break;
      }
    }

    // Chained token relationships.
231
    if ($entity_tokens = $token_service->findwithPrefix($tokens, 'entity')) {
232
      $entity = $comment->getCommentedEntity();
233
      $replacements += $token_service->generate($comment->getCommentedEntityTypeId(), $entity_tokens, [$comment->getCommentedEntityTypeId() => $entity], $options, $bubbleable_metadata);
234 235
    }

236
    if ($date_tokens = $token_service->findwithPrefix($tokens, 'created')) {
237
      $replacements += $token_service->generate('date', $date_tokens, ['date' => $comment->getCreatedTime()], $options, $bubbleable_metadata);
238 239
    }

240
    if ($date_tokens = $token_service->findwithPrefix($tokens, 'changed')) {
241
      $replacements += $token_service->generate('date', $date_tokens, ['date' => $comment->getChangedTime()], $options, $bubbleable_metadata);
242 243
    }

244
    if (($parent_tokens = $token_service->findwithPrefix($tokens, 'parent')) && $parent = $comment->getParentComment()) {
245
      $replacements += $token_service->generate('comment', $parent_tokens, ['comment' => $parent], $options, $bubbleable_metadata);
246 247
    }

248
    if (($author_tokens = $token_service->findwithPrefix($tokens, 'author')) && $account = $comment->getOwner()) {
249
      $replacements += $token_service->generate('user', $author_tokens, ['user' => $account], $options, $bubbleable_metadata);
250 251
    }
  }
252 253
  // Replacement tokens for any content entities that have comment field.
  elseif (!empty($data[$type]) && $data[$type] instanceof FieldableEntityInterface) {
254
    /** @var $entity \Drupal\Core\Entity\FieldableEntityInterface */
255
    $entity = $data[$type];
256 257

    foreach ($tokens as $name => $original) {
258
      switch ($name) {
259
        case 'comment-count':
260
          $count = 0;
261
          $fields = array_keys(\Drupal::service('comment.manager')->getFields($entity->getEntityTypeId()));
262
          $definitions = array_keys($entity->getFieldDefinitions());
263 264 265 266 267
          $valid_fields = array_intersect($fields, $definitions);
          foreach ($valid_fields as $field_name) {
            $count += $entity->get($field_name)->comment_count;
          }
          $replacements[$original] = $count;
268 269 270
          break;

        case 'comment-count-new':
271
          $replacements[$original] = \Drupal::service('comment.manager')->getCountNewComments($entity);
272 273 274 275 276 277 278
          break;
      }
    }
  }

  return $replacements;
}