/**
  * #post_render_cache callback; attaches "X new comments" link metadata.
  *
  * @param array $element
  *   A render array with the following keys:
  *   - #markup
  *   - #attached
  * @param array $context
  *   An array with the following keys:
  *   - entity_type: an entity type
  *   - entity_id: an entity ID
  *   - field_name: a comment field name
  *
  * @return array
  *   The updated $element.
  */
 public function attachNewCommentsLinkMetadata(array $element, array $context)
 {
     $entity = $this->entityManager->getStorage($context['entity_type'])->load($context['entity_id']);
     // Build "X new comments" link metadata.
     $new = $this->commentManager->getCountNewComments($entity);
     // Early-return if there are zero new comments for the current user.
     if ($new === 0) {
         return $element;
     }
     $field_name = $context['field_name'];
     $page_number = $this->entityManager->getStorage('comment')->getNewCommentPageNumber($entity->{$field_name}->comment_count, $new, $entity);
     $query = $page_number ? array('page' => $page_number) : NULL;
     // Attach metadata.
     $element['#attached']['js'][] = array('type' => 'setting', 'data' => array('comment' => array('newCommentsLinks' => array($context['entity_type'] => array($context['field_name'] => array($context['entity_id'] => array('new_comment_count' => (int) $new, 'first_new_comment_link' => $entity->url('canonical', ['query' => $query, 'fragment' => 'new']))))))));
     return $element;
 }
예제 #2
0
 /**
  * Returns a set of nodes' last read timestamps.
  *
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The request of the page.
  *
  * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
  * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
  * @return \Symfony\Component\HttpFoundation\JsonResponse
  *   The JSON response.
  */
 public function renderNewCommentsNodeLinks(Request $request)
 {
     if ($this->currentUser()->isAnonymous()) {
         throw new AccessDeniedHttpException();
     }
     $nids = $request->request->get('node_ids');
     $field_name = $request->request->get('field_name');
     if (!isset($nids)) {
         throw new NotFoundHttpException();
     }
     // Only handle up to 100 nodes.
     $nids = array_slice($nids, 0, 100);
     $links = array();
     foreach ($nids as $nid) {
         $node = $this->entityManager->getStorage('node')->load($nid);
         $new = $this->commentManager->getCountNewComments($node);
         $page_number = $this->entityManager()->getStorage('comment')->getNewCommentPageNumber($node->{$field_name}->comment_count, $new, $node);
         $query = $page_number ? array('page' => $page_number) : NULL;
         $links[$nid] = array('new_comment_count' => (int) $new, 'first_new_comment_link' => $this->getUrlGenerator()->generateFromRoute('entity.node.canonical', array('node' => $node->id()), array('query' => $query, 'fragment' => 'new')));
     }
     return new JsonResponse($links);
 }
예제 #3
0
 /**
  * {@inheritdoc}
  */
 public function buildCommentedEntityLinks(FieldableEntityInterface $entity, array &$context)
 {
     $entity_links = array();
     $view_mode = $context['view_mode'];
     if ($view_mode == 'search_index' || $view_mode == 'search_result' || $view_mode == 'print' || $view_mode == 'rss') {
         // Do not add any links if the entity is displayed for:
         // - search indexing.
         // - constructing a search result excerpt.
         // - print.
         // - rss.
         return array();
     }
     $fields = $this->commentManager->getFields($entity->getEntityTypeId());
     foreach ($fields as $field_name => $detail) {
         // Skip fields that the entity does not have.
         if (!$entity->hasField($field_name)) {
             continue;
         }
         $links = array();
         $commenting_status = $entity->get($field_name)->status;
         if ($commenting_status != CommentItemInterface::HIDDEN) {
             // Entity has commenting status open or closed.
             $field_definition = $entity->getFieldDefinition($field_name);
             if ($view_mode == 'teaser') {
                 // Teaser view: display the number of comments that have been posted,
                 // or a link to add new comments if the user has permission, the
                 // entity is open to new comments, and there currently are none.
                 if ($this->currentUser->hasPermission('access comments')) {
                     if (!empty($entity->get($field_name)->comment_count)) {
                         $links['comment-comments'] = array('title' => $this->formatPlural($entity->get($field_name)->comment_count, '1 comment', '@count comments'), 'attributes' => array('title' => $this->t('Jump to the first comment.')), 'fragment' => 'comments', 'url' => $entity->urlInfo());
                         if ($this->moduleHandler->moduleExists('history')) {
                             $links['comment-new-comments'] = array('title' => '', 'url' => Url::fromRoute('<current>'), 'attributes' => array('class' => 'hidden', 'title' => $this->t('Jump to the first new comment.'), 'data-history-node-last-comment-timestamp' => $entity->get($field_name)->last_comment_timestamp, 'data-history-node-field-name' => $field_name));
                         }
                     }
                 }
                 // Provide a link to new comment form.
                 if ($commenting_status == CommentItemInterface::OPEN) {
                     $comment_form_location = $field_definition->getSetting('form_location');
                     if ($this->currentUser->hasPermission('post comments')) {
                         $links['comment-add'] = array('title' => $this->t('Add new comments'), 'language' => $entity->language(), 'attributes' => array('title' => $this->t('Share your thoughts and opinions.')), 'fragment' => 'comment-form');
                         if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE) {
                             $links['comment-add']['url'] = Url::fromRoute('comment.reply', ['entity_type' => $entity->getEntityTypeId(), 'entity' => $entity->id(), 'field_name' => $field_name]);
                         } else {
                             $links['comment-add'] += ['url' => $entity->urlInfo()];
                         }
                     } elseif ($this->currentUser->isAnonymous()) {
                         $links['comment-forbidden'] = array('title' => $this->commentManager->forbiddenMessage($entity, $field_name));
                     }
                 }
             } else {
                 // Entity in other view modes: add a "post comment" link if the user
                 // is allowed to post comments and if this entity is allowing new
                 // comments.
                 if ($commenting_status == CommentItemInterface::OPEN) {
                     $comment_form_location = $field_definition->getSetting('form_location');
                     if ($this->currentUser->hasPermission('post comments')) {
                         // Show the "post comment" link if the form is on another page, or
                         // if there are existing comments that the link will skip past.
                         if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE || !empty($entity->get($field_name)->comment_count) && $this->currentUser->hasPermission('access comments')) {
                             $links['comment-add'] = array('title' => $this->t('Add new comment'), 'attributes' => array('title' => $this->t('Share your thoughts and opinions.')), 'fragment' => 'comment-form');
                             if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE) {
                                 $links['comment-add']['url'] = Url::fromRoute('comment.reply', ['entity_type' => $entity->getEntityTypeId(), 'entity' => $entity->id(), 'field_name' => $field_name]);
                             } else {
                                 $links['comment-add']['url'] = $entity->urlInfo();
                             }
                         }
                     } elseif ($this->currentUser->isAnonymous()) {
                         $links['comment-forbidden'] = array('title' => $this->commentManager->forbiddenMessage($entity, $field_name));
                     }
                 }
             }
         }
         if (!empty($links)) {
             $entity_links['comment__' . $field_name] = array('#theme' => 'links__entity__comment__' . $field_name, '#links' => $links, '#attributes' => array('class' => array('links', 'inline')));
             if ($view_mode == 'teaser' && $this->moduleHandler->moduleExists('history') && $this->currentUser->isAuthenticated()) {
                 $entity_links['comment__' . $field_name]['#cache']['contexts'][] = 'user';
                 $entity_links['comment__' . $field_name]['#attached']['library'][] = 'comment/drupal.node-new-comments-link';
                 // Embed the metadata for the "X new comments" link (if any) on this
                 // entity.
                 $entity_links['comment__' . $field_name]['#attached']['drupalSettings']['history']['lastReadTimestamps'][$entity->id()] = (int) history_read($entity->id());
                 $new_comments = $this->commentManager->getCountNewComments($entity);
                 if ($new_comments > 0) {
                     $page_number = $this->entityManager->getStorage('comment')->getNewCommentPageNumber($entity->{$field_name}->comment_count, $new_comments, $entity, $field_name);
                     $query = $page_number ? ['page' => $page_number] : NULL;
                     $value = ['new_comment_count' => (int) $new_comments, 'first_new_comment_link' => $entity->url('canonical', ['query' => $query, 'fragment' => 'new'])];
                     $parents = ['comment', 'newCommentsLinks', $entity->getEntityTypeId(), $field_name, $entity->id()];
                     NestedArray::setValue($entity_links['comment__' . $field_name]['#attached']['drupalSettings'], $parents, $value);
                 }
             }
         }
     }
     return $entity_links;
 }
예제 #4
0
 /**
  * {@inheritdoc}
  */
 public function getTopics($tid, AccountInterface $account)
 {
     $config = $this->configFactory->get('forum.settings');
     $forum_per_page = $config->get('topics.page_limit');
     $sortby = $config->get('topics.order');
     $header = array(array('data' => $this->t('Topic'), 'field' => 'f.title'), array('data' => $this->t('Replies'), 'field' => 'f.comment_count'), array('data' => $this->t('Last reply'), 'field' => 'f.last_comment_timestamp'));
     $order = $this->getTopicOrder($sortby);
     for ($i = 0; $i < count($header); $i++) {
         if ($header[$i]['field'] == $order['field']) {
             $header[$i]['sort'] = $order['sort'];
         }
     }
     $query = $this->connection->select('forum_index', 'f')->extend('Drupal\\Core\\Database\\Query\\PagerSelectExtender')->extend('Drupal\\Core\\Database\\Query\\TableSortExtender');
     $query->fields('f');
     $query->condition('f.tid', $tid)->addTag('node_access')->addMetaData('base_table', 'forum_index')->orderBy('f.sticky', 'DESC')->orderByHeader($header)->limit($forum_per_page);
     $count_query = $this->connection->select('forum_index', 'f');
     $count_query->condition('f.tid', $tid);
     $count_query->addExpression('COUNT(*)');
     $count_query->addTag('node_access');
     $count_query->addMetaData('base_table', 'forum_index');
     $query->setCountQuery($count_query);
     $result = $query->execute();
     $nids = array();
     foreach ($result as $record) {
         $nids[] = $record->nid;
     }
     if ($nids) {
         $nodes = $this->entityManager->getStorage('node')->loadMultiple($nids);
         $query = $this->connection->select('node_field_data', 'n')->extend('Drupal\\Core\\Database\\Query\\TableSortExtender');
         $query->fields('n', array('nid'));
         $query->join('comment_entity_statistics', 'ces', "n.nid = ces.entity_id AND ces.field_name = 'comment_forum' AND ces.entity_type = 'node'");
         $query->fields('ces', array('cid', 'last_comment_uid', 'last_comment_timestamp', 'comment_count'));
         $query->join('forum_index', 'f', 'f.nid = n.nid');
         $query->addField('f', 'tid', 'forum_tid');
         $query->join('users_field_data', 'u', 'n.uid = u.uid AND u.default_langcode = 1');
         $query->addField('u', 'name');
         $query->join('users_field_data', 'u2', 'ces.last_comment_uid = u2.uid AND u.default_langcode = 1');
         $query->addExpression('CASE ces.last_comment_uid WHEN 0 THEN ces.last_comment_name ELSE u2.name END', 'last_comment_name');
         $query->orderBy('f.sticky', 'DESC')->orderByHeader($header)->condition('n.nid', $nids, 'IN')->condition('n.default_langcode', 1);
         $result = array();
         foreach ($query->execute() as $row) {
             $topic = $nodes[$row->nid];
             $topic->comment_mode = $topic->comment_forum->status;
             foreach ($row as $key => $value) {
                 $topic->{$key} = $value;
             }
             $result[] = $topic;
         }
     } else {
         $result = array();
     }
     $topics = array();
     $first_new_found = FALSE;
     foreach ($result as $topic) {
         if ($account->isAuthenticated()) {
             // A forum is new if the topic is new, or if there are new comments since
             // the user's last visit.
             if ($topic->forum_tid != $tid) {
                 $topic->new = 0;
             } else {
                 $history = $this->lastVisit($topic->id(), $account);
                 $topic->new_replies = $this->commentManager->getCountNewComments($topic, 'comment_forum', $history);
                 $topic->new = $topic->new_replies || $topic->last_comment_timestamp > $history;
             }
         } else {
             // Do not track "new replies" status for topics if the user is anonymous.
             $topic->new_replies = 0;
             $topic->new = 0;
         }
         // Make sure only one topic is indicated as the first new topic.
         $topic->first_new = FALSE;
         if ($topic->new != 0 && !$first_new_found) {
             $topic->first_new = TRUE;
             $first_new_found = TRUE;
         }
         if ($topic->comment_count > 0) {
             $last_reply = new \stdClass();
             $last_reply->created = $topic->last_comment_timestamp;
             $last_reply->name = $topic->last_comment_name;
             $last_reply->uid = $topic->last_comment_uid;
             $topic->last_reply = $last_reply;
         }
         $topics[$topic->id()] = $topic;
     }
     return array('topics' => $topics, 'header' => $header);
 }