comment.tokens.inc 9.25 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\Html;
9
use Drupal\Component\Utility\UrlHelper;
10
use Drupal\Component\Utility\Xss;
11 12
use Drupal\Core\Datetime\Entity\DateFormat;
use Drupal\Core\Render\BubbleableMetadata;
13

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

24
  // @todo Make this work per field. See https://www.drupal.org/node/2031903.
25
  $entity['comment-count'] = array(
26
    'name' => t("Comment count"),
27
    'description' => t("The number of comments posted on an entity."),
28
  );
29
  $entity['comment-count-new'] = array(
30
    'name' => t("New comment count"),
31
    'description' => t("The number of comments posted on an entity since the reader last viewed it."),
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
  );

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

  // Chained tokens for comments
  $comment['created'] = array(
    'name' => t("Date created"),
    'description' => t("The date the comment was posted."),
    'type' => 'date',
  );
78 79 80 81 82
  $comment['changed'] = array(
    'name' => t("Date changed"),
    'description' => t("The date the comment was most recently updated."),
    'type' => 'date',
  );
83 84 85 86 87
  $comment['parent'] = array(
    'name' => t("Parent"),
    'description' => t("The comment's parent, if comment threading is active."),
    'type' => 'comment',
  );
88 89 90 91 92
  $comment['entity'] = array(
    'name' => t("Entity"),
    'description' => t("The entity the comment was posted to."),
    'type' => 'entity',
  );
93 94
  $comment['author'] = array(
    'name' => t("Author"),
95
    'description' => t("The author name of the comment."),
96 97 98 99 100 101
    'type' => 'user',
  );

  return array(
    'types' => array('comment' => $type),
    'tokens' => array(
102
      'entity' => $entity,
103 104 105 106 107 108
      'comment' => $comment,
    ),
  );
}

/**
109
 * Implements hook_tokens().
110
 */
111
function comment_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
112
  $token_service = \Drupal::token();
113

114
  $url_options = array('absolute' => TRUE);
115
  if (isset($options['langcode'])) {
116
    $url_options['language'] = \Drupal::languageManager()->getLanguage($options['langcode']);
117
    $langcode = $options['langcode'];
118 119
  }
  else {
120
    $langcode = NULL;
121 122 123 124 125 126
  }
  $sanitize = !empty($options['sanitize']);

  $replacements = array();

  if ($type == 'comment' && !empty($data['comment'])) {
127
    /** @var \Drupal\comment\CommentInterface $comment */
128 129 130 131 132 133
    $comment = $data['comment'];

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

137
        // Poster identity information for comments.
138
        case 'hostname':
139
          $replacements[$original] = $sanitize ? Html::escape($comment->getHostname()) : $comment->getHostname();
140 141 142
          break;

        case 'mail':
143
          $mail = $comment->getAuthorEmail();
144 145 146 147 148
          // 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());
          }
149
          $replacements[$original] = $sanitize ? Html::escape($mail) : $mail;
150 151 152
          break;

        case 'homepage':
153
          $replacements[$original] = $sanitize ? UrlHelper::filterBadProtocol($comment->getHomepage()) : $comment->getHomepage();
154 155 156
          break;

        case 'title':
157
          $replacements[$original] = $sanitize ? Xss::filter($comment->getSubject()) : $comment->getSubject();
158 159 160
          break;

        case 'body':
161
          $replacements[$original] = $sanitize ? $comment->comment_body->processed : $comment->comment_body->value;
162 163
          break;

164
        case 'langcode':
165
          $replacements[$original] = $sanitize ? Html::escape($comment->language()->getId()) : $comment->language()->getId();
166 167
          break;

168 169
        // Comment related URLs.
        case 'url':
170
          $url_options['fragment']  = 'comment-' . $comment->id();
171
          $replacements[$original] = $comment->url('canonical', $url_options);
172 173 174
          break;

        case 'edit-url':
175
          $url_options['fragment'] = NULL;
176
          $replacements[$original] = $comment->url('edit-form', $url_options);
177 178 179
          break;

        case 'author':
180
          $name = $comment->getAuthorName();
181 182 183 184 185
          // 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());
          }
186
          $replacements[$original] = $sanitize ? Xss::filter($name) : $name;
187 188 189
          break;

        case 'parent':
190 191
          if ($comment->hasParentComment()) {
            $parent = $comment->getParentComment();
192
            $bubbleable_metadata->addCacheableDependency($parent);
193
            $replacements[$original] = $sanitize ? Xss::filter($parent->getSubject()) : $parent->getSubject();
194 195 196 197
          }
          break;

        case 'created':
198 199
          $date_format = DateFormat::load('medium');
          $bubbleable_metadata->addCacheableDependency($date_format);
200
          $replacements[$original] = format_date($comment->getCreatedTime(), 'medium', '', NULL, $langcode);
201 202 203
          break;

        case 'changed':
204 205
          $date_format = DateFormat::load('medium');
          $bubbleable_metadata->addCacheableDependency($date_format);
206
          $replacements[$original] = format_date($comment->getChangedTime(), 'medium', '', NULL, $langcode);
207 208
          break;

209
        case 'entity':
210
          $entity = $comment->getCommentedEntity();
211
          $bubbleable_metadata->addCacheableDependency($entity);
212
          $title = $entity->label();
213
          $replacements[$original] = $sanitize ? Xss::filter($title) : $title;
214 215 216 217 218
          break;
      }
    }

    // Chained token relationships.
219
    if ($entity_tokens = $token_service->findwithPrefix($tokens, 'entity')) {
220
      $entity = $comment->getCommentedEntity();
221
      $replacements += $token_service->generate($comment->getCommentedEntityTypeId(), $entity_tokens, array($comment->getCommentedEntityTypeId() => $entity), $options, $bubbleable_metadata);
222 223
    }

224
    if ($date_tokens = $token_service->findwithPrefix($tokens, 'created')) {
225
      $replacements += $token_service->generate('date', $date_tokens, array('date' => $comment->getCreatedTime()), $options, $bubbleable_metadata);
226 227
    }

228
    if ($date_tokens = $token_service->findwithPrefix($tokens, 'changed')) {
229
      $replacements += $token_service->generate('date', $date_tokens, array('date' => $comment->getChangedTime()), $options, $bubbleable_metadata);
230 231
    }

232
    if (($parent_tokens = $token_service->findwithPrefix($tokens, 'parent')) && $parent = $comment->getParentComment()) {
233
      $replacements += $token_service->generate('comment', $parent_tokens, array('comment' => $parent), $options, $bubbleable_metadata);
234 235
    }

236
    if (($author_tokens = $token_service->findwithPrefix($tokens, 'author')) && $account = $comment->getOwner()) {
237
      $replacements += $token_service->generate('user', $author_tokens, array('user' => $account), $options, $bubbleable_metadata);
238 239
    }
  }
240
  elseif ($type == 'entity' & !empty($data['entity'])) {
241
    /** @var $entity \Drupal\Core\Entity\FieldableEntityInterface */
242
    $entity = $data['entity'];
243 244

    foreach ($tokens as $name => $original) {
245
      switch ($name) {
246
        case 'comment-count':
247
          $count = 0;
248
          $fields = array_keys(\Drupal::service('comment.manager')->getFields($entity->getEntityTypeId()));
249
          $definitions = array_keys($entity->getFieldDefinitions());
250 251 252 253 254
          $valid_fields = array_intersect($fields, $definitions);
          foreach ($valid_fields as $field_name) {
            $count += $entity->get($field_name)->comment_count;
          }
          $replacements[$original] = $count;
255 256 257
          break;

        case 'comment-count-new':
258
          $replacements[$original] = \Drupal::service('comment.manager')->getCountNewComments($entity);
259 260 261 262 263 264 265
          break;
      }
    }
  }

  return $replacements;
}