annotate core/modules/comment/src/CommentLinkBuilder.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\comment;
Chris@0 4
Chris@0 5 use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
Chris@0 6 use Drupal\Component\Utility\NestedArray;
Chris@18 7 use Drupal\Core\DependencyInjection\DeprecatedServicePropertyTrait;
Chris@18 8 use Drupal\Core\Entity\EntityTypeManagerInterface;
Chris@0 9 use Drupal\Core\Entity\FieldableEntityInterface;
Chris@0 10 use Drupal\Core\Extension\ModuleHandlerInterface;
Chris@0 11 use Drupal\Core\Session\AccountInterface;
Chris@0 12 use Drupal\Core\StringTranslation\StringTranslationTrait;
Chris@0 13 use Drupal\Core\StringTranslation\TranslationInterface;
Chris@0 14 use Drupal\Core\Url;
Chris@0 15
Chris@0 16 /**
Chris@0 17 * Defines a class for building markup for comment links on a commented entity.
Chris@0 18 *
Chris@0 19 * Comment links include 'log in to post new comment', 'add new comment' etc.
Chris@0 20 */
Chris@0 21 class CommentLinkBuilder implements CommentLinkBuilderInterface {
Chris@0 22
Chris@0 23 use StringTranslationTrait;
Chris@18 24 use DeprecatedServicePropertyTrait;
Chris@18 25
Chris@18 26 /**
Chris@18 27 * {@inheritdoc}
Chris@18 28 */
Chris@18 29 protected $deprecatedProperties = ['entityManager' => 'entity.manager'];
Chris@0 30
Chris@0 31 /**
Chris@0 32 * Current user.
Chris@0 33 *
Chris@0 34 * @var \Drupal\Core\Session\AccountInterface
Chris@0 35 */
Chris@0 36 protected $currentUser;
Chris@0 37
Chris@0 38 /**
Chris@0 39 * Comment manager service.
Chris@0 40 *
Chris@0 41 * @var \Drupal\comment\CommentManagerInterface
Chris@0 42 */
Chris@0 43 protected $commentManager;
Chris@0 44
Chris@0 45 /**
Chris@0 46 * Module handler service.
Chris@0 47 *
Chris@0 48 * @var \Drupal\Core\Extension\ModuleHandlerInterface
Chris@0 49 */
Chris@0 50 protected $moduleHandler;
Chris@0 51
Chris@0 52 /**
Chris@18 53 * The entity type manager service.
Chris@0 54 *
Chris@18 55 * @var \Drupal\Core\Entity\EntityTypeManagerInterface
Chris@0 56 */
Chris@18 57 protected $entityTypeManager;
Chris@0 58
Chris@0 59 /**
Chris@0 60 * Constructs a new CommentLinkBuilder object.
Chris@0 61 *
Chris@0 62 * @param \Drupal\Core\Session\AccountInterface $current_user
Chris@0 63 * Current user.
Chris@0 64 * @param \Drupal\comment\CommentManagerInterface $comment_manager
Chris@0 65 * Comment manager service.
Chris@0 66 * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
Chris@0 67 * Module handler service.
Chris@0 68 * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
Chris@0 69 * String translation service.
Chris@18 70 * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
Chris@18 71 * The entity type manager.
Chris@0 72 */
Chris@18 73 public function __construct(AccountInterface $current_user, CommentManagerInterface $comment_manager, ModuleHandlerInterface $module_handler, TranslationInterface $string_translation, EntityTypeManagerInterface $entity_type_manager) {
Chris@0 74 $this->currentUser = $current_user;
Chris@0 75 $this->commentManager = $comment_manager;
Chris@0 76 $this->moduleHandler = $module_handler;
Chris@0 77 $this->stringTranslation = $string_translation;
Chris@18 78 $this->entityTypeManager = $entity_type_manager;
Chris@0 79 }
Chris@0 80
Chris@0 81 /**
Chris@0 82 * {@inheritdoc}
Chris@0 83 */
Chris@0 84 public function buildCommentedEntityLinks(FieldableEntityInterface $entity, array &$context) {
Chris@0 85 $entity_links = [];
Chris@0 86 $view_mode = $context['view_mode'];
Chris@0 87 if ($view_mode == 'search_index' || $view_mode == 'search_result' || $view_mode == 'print' || $view_mode == 'rss') {
Chris@0 88 // Do not add any links if the entity is displayed for:
Chris@0 89 // - search indexing.
Chris@0 90 // - constructing a search result excerpt.
Chris@0 91 // - print.
Chris@0 92 // - rss.
Chris@0 93 return [];
Chris@0 94 }
Chris@0 95
Chris@0 96 $fields = $this->commentManager->getFields($entity->getEntityTypeId());
Chris@0 97 foreach ($fields as $field_name => $detail) {
Chris@0 98 // Skip fields that the entity does not have.
Chris@0 99 if (!$entity->hasField($field_name)) {
Chris@0 100 continue;
Chris@0 101 }
Chris@0 102 $links = [];
Chris@0 103 $commenting_status = $entity->get($field_name)->status;
Chris@0 104 if ($commenting_status != CommentItemInterface::HIDDEN) {
Chris@0 105 // Entity has commenting status open or closed.
Chris@0 106 $field_definition = $entity->getFieldDefinition($field_name);
Chris@0 107 if ($view_mode == 'teaser') {
Chris@0 108 // Teaser view: display the number of comments that have been posted,
Chris@0 109 // or a link to add new comments if the user has permission, the
Chris@0 110 // entity is open to new comments, and there currently are none.
Chris@0 111 if ($this->currentUser->hasPermission('access comments')) {
Chris@0 112 if (!empty($entity->get($field_name)->comment_count)) {
Chris@0 113 $links['comment-comments'] = [
Chris@0 114 'title' => $this->formatPlural($entity->get($field_name)->comment_count, '1 comment', '@count comments'),
Chris@0 115 'attributes' => ['title' => $this->t('Jump to the first comment.')],
Chris@0 116 'fragment' => 'comments',
Chris@17 117 'url' => $entity->toUrl(),
Chris@0 118 ];
Chris@0 119 if ($this->moduleHandler->moduleExists('history')) {
Chris@0 120 $links['comment-new-comments'] = [
Chris@0 121 'title' => '',
Chris@0 122 'url' => Url::fromRoute('<current>'),
Chris@0 123 'attributes' => [
Chris@0 124 'class' => 'hidden',
Chris@0 125 'title' => $this->t('Jump to the first new comment.'),
Chris@0 126 'data-history-node-last-comment-timestamp' => $entity->get($field_name)->last_comment_timestamp,
Chris@0 127 'data-history-node-field-name' => $field_name,
Chris@0 128 ],
Chris@0 129 ];
Chris@0 130 }
Chris@0 131 }
Chris@0 132 }
Chris@0 133 // Provide a link to new comment form.
Chris@0 134 if ($commenting_status == CommentItemInterface::OPEN) {
Chris@0 135 $comment_form_location = $field_definition->getSetting('form_location');
Chris@0 136 if ($this->currentUser->hasPermission('post comments')) {
Chris@0 137 $links['comment-add'] = [
Chris@0 138 'title' => $this->t('Add new comment'),
Chris@0 139 'language' => $entity->language(),
Chris@0 140 'attributes' => ['title' => $this->t('Share your thoughts and opinions.')],
Chris@0 141 'fragment' => 'comment-form',
Chris@0 142 ];
Chris@0 143 if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE) {
Chris@0 144 $links['comment-add']['url'] = Url::fromRoute('comment.reply', [
Chris@0 145 'entity_type' => $entity->getEntityTypeId(),
Chris@0 146 'entity' => $entity->id(),
Chris@0 147 'field_name' => $field_name,
Chris@0 148 ]);
Chris@0 149 }
Chris@0 150 else {
Chris@17 151 $links['comment-add'] += ['url' => $entity->toUrl()];
Chris@0 152 }
Chris@0 153 }
Chris@0 154 elseif ($this->currentUser->isAnonymous()) {
Chris@0 155 $links['comment-forbidden'] = [
Chris@0 156 'title' => $this->commentManager->forbiddenMessage($entity, $field_name),
Chris@0 157 ];
Chris@0 158 }
Chris@0 159 }
Chris@0 160 }
Chris@0 161 else {
Chris@0 162 // Entity in other view modes: add a "post comment" link if the user
Chris@0 163 // is allowed to post comments and if this entity is allowing new
Chris@0 164 // comments.
Chris@0 165 if ($commenting_status == CommentItemInterface::OPEN) {
Chris@0 166 $comment_form_location = $field_definition->getSetting('form_location');
Chris@0 167 if ($this->currentUser->hasPermission('post comments')) {
Chris@0 168 // Show the "post comment" link if the form is on another page, or
Chris@0 169 // if there are existing comments that the link will skip past.
Chris@0 170 if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE || (!empty($entity->get($field_name)->comment_count) && $this->currentUser->hasPermission('access comments'))) {
Chris@0 171 $links['comment-add'] = [
Chris@0 172 'title' => $this->t('Add new comment'),
Chris@0 173 'attributes' => ['title' => $this->t('Share your thoughts and opinions.')],
Chris@0 174 'fragment' => 'comment-form',
Chris@0 175 ];
Chris@0 176 if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE) {
Chris@0 177 $links['comment-add']['url'] = Url::fromRoute('comment.reply', [
Chris@0 178 'entity_type' => $entity->getEntityTypeId(),
Chris@0 179 'entity' => $entity->id(),
Chris@0 180 'field_name' => $field_name,
Chris@0 181 ]);
Chris@0 182 }
Chris@0 183 else {
Chris@17 184 $links['comment-add']['url'] = $entity->toUrl();
Chris@0 185 }
Chris@0 186 }
Chris@0 187 }
Chris@0 188 elseif ($this->currentUser->isAnonymous()) {
Chris@0 189 $links['comment-forbidden'] = [
Chris@0 190 'title' => $this->commentManager->forbiddenMessage($entity, $field_name),
Chris@0 191 ];
Chris@0 192 }
Chris@0 193 }
Chris@0 194 }
Chris@0 195 }
Chris@0 196
Chris@0 197 if (!empty($links)) {
Chris@0 198 $entity_links['comment__' . $field_name] = [
Chris@0 199 '#theme' => 'links__entity__comment__' . $field_name,
Chris@0 200 '#links' => $links,
Chris@0 201 '#attributes' => ['class' => ['links', 'inline']],
Chris@0 202 ];
Chris@0 203 if ($view_mode == 'teaser' && $this->moduleHandler->moduleExists('history') && $this->currentUser->isAuthenticated()) {
Chris@0 204 $entity_links['comment__' . $field_name]['#cache']['contexts'][] = 'user';
Chris@0 205 $entity_links['comment__' . $field_name]['#attached']['library'][] = 'comment/drupal.node-new-comments-link';
Chris@0 206 // Embed the metadata for the "X new comments" link (if any) on this
Chris@0 207 // entity.
Chris@0 208 $entity_links['comment__' . $field_name]['#attached']['drupalSettings']['history']['lastReadTimestamps'][$entity->id()] = (int) history_read($entity->id());
Chris@0 209 $new_comments = $this->commentManager->getCountNewComments($entity);
Chris@0 210 if ($new_comments > 0) {
Chris@18 211 $page_number = $this->entityTypeManager
Chris@0 212 ->getStorage('comment')
Chris@0 213 ->getNewCommentPageNumber($entity->{$field_name}->comment_count, $new_comments, $entity, $field_name);
Chris@0 214 $query = $page_number ? ['page' => $page_number] : NULL;
Chris@0 215 $value = [
Chris@0 216 'new_comment_count' => (int) $new_comments,
Chris@18 217 'first_new_comment_link' => $entity->toUrl('canonical', [
Chris@0 218 'query' => $query,
Chris@0 219 'fragment' => 'new',
Chris@18 220 ])->toString(),
Chris@0 221 ];
Chris@0 222 $parents = ['comment', 'newCommentsLinks', $entity->getEntityTypeId(), $field_name, $entity->id()];
Chris@0 223 NestedArray::setValue($entity_links['comment__' . $field_name]['#attached']['drupalSettings'], $parents, $value);
Chris@0 224 }
Chris@0 225 }
Chris@0 226 }
Chris@0 227 }
Chris@0 228 return $entity_links;
Chris@0 229 }
Chris@0 230
Chris@0 231 }