X-Git-Url: http://www.aleph1.co.uk/gitweb/?a=blobdiff_plain;f=web%2Fcore%2Fmodules%2Fcomment%2Fsrc%2FCommentViewBuilder.php;fp=web%2Fcore%2Fmodules%2Fcomment%2Fsrc%2FCommentViewBuilder.php;h=ec6d49a5b07275b7eeaa32a162ed15f8dbf75b9c;hb=a2bd1bf0c2c1f1a17d188f4dc0726a45494cefae;hp=0000000000000000000000000000000000000000;hpb=57c063afa3f66b07c4bbddc2d6129a96d90f0aad;p=yaffs-website diff --git a/web/core/modules/comment/src/CommentViewBuilder.php b/web/core/modules/comment/src/CommentViewBuilder.php new file mode 100644 index 000000000..ec6d49a5b --- /dev/null +++ b/web/core/modules/comment/src/CommentViewBuilder.php @@ -0,0 +1,183 @@ +currentUser = $current_user; + } + + /** + * {@inheritdoc} + */ + public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) { + return new static( + $entity_type, + $container->get('entity.manager'), + $container->get('language_manager'), + $container->get('current_user') + ); + } + + /** + * {@inheritdoc} + */ + protected function getBuildDefaults(EntityInterface $entity, $view_mode) { + $build = parent::getBuildDefaults($entity, $view_mode); + + /** @var \Drupal\comment\CommentInterface $entity */ + // Store a threading field setting to use later in self::buildComponents(). + $build['#comment_threaded'] = $entity->getCommentedEntity() + ->getFieldDefinition($entity->getFieldName()) + ->getSetting('default_mode') === CommentManagerInterface::COMMENT_MODE_THREADED; + // If threading is enabled, don't render cache individual comments, but do + // keep the cacheability metadata, so it can bubble up. + if ($build['#comment_threaded']) { + unset($build['#cache']['keys']); + } + + return $build; + } + + /** + * {@inheritdoc} + * + * In addition to modifying the content key on entities, this implementation + * will also set the comment entity key which all comments carry. + * + * @throws \InvalidArgumentException + * Thrown when a comment is attached to an entity that no longer exists. + */ + public function buildComponents(array &$build, array $entities, array $displays, $view_mode) { + /** @var \Drupal\comment\CommentInterface[] $entities */ + if (empty($entities)) { + return; + } + + // Pre-load associated users into cache to leverage multiple loading. + $uids = []; + foreach ($entities as $entity) { + $uids[] = $entity->getOwnerId(); + } + $this->entityManager->getStorage('user')->loadMultiple(array_unique($uids)); + + parent::buildComponents($build, $entities, $displays, $view_mode); + + // A counter to track the indentation level. + $current_indent = 0; + + foreach ($entities as $id => $entity) { + if ($build[$id]['#comment_threaded']) { + $comment_indent = count(explode('.', $entity->getThread())) - 1; + if ($comment_indent > $current_indent) { + // Set 1 to indent this comment from the previous one (its parent). + // Set only one extra level of indenting even if the difference in + // depth is higher. + $build[$id]['#comment_indent'] = 1; + $current_indent++; + } + else { + // Set zero if this comment is on the same level as the previous one + // or negative value to point an amount indents to close. + $build[$id]['#comment_indent'] = $comment_indent - $current_indent; + $current_indent = $comment_indent; + } + } + + // Commented entities already loaded after self::getBuildDefaults(). + $commented_entity = $entity->getCommentedEntity(); + + $build[$id]['#entity'] = $entity; + $build[$id]['#theme'] = 'comment__' . $entity->getFieldName() . '__' . $commented_entity->bundle(); + + $display = $displays[$entity->bundle()]; + if ($display->getComponent('links')) { + $build[$id]['links'] = [ + '#lazy_builder' => ['comment.lazy_builders:renderLinks', [ + $entity->id(), + $view_mode, + $entity->language()->getId(), + !empty($entity->in_preview), + ]], + '#create_placeholder' => TRUE, + ]; + } + + if (!isset($build[$id]['#attached'])) { + $build[$id]['#attached'] = []; + } + $build[$id]['#attached']['library'][] = 'comment/drupal.comment-by-viewer'; + if ($this->moduleHandler->moduleExists('history') && $this->currentUser->isAuthenticated()) { + $build[$id]['#attached']['library'][] = 'comment/drupal.comment-new-indicator'; + + // Embed the metadata for the comment "new" indicators on this node. + $build[$id]['history'] = [ + '#lazy_builder' => ['history_attach_timestamp', [$commented_entity->id()]], + '#create_placeholder' => TRUE, + ]; + } + } + if ($build[$id]['#comment_threaded']) { + // The final comment must close up some hanging divs. + $build[$id]['#comment_indent_final'] = $current_indent; + } + } + + /** + * {@inheritdoc} + */ + protected function alterBuild(array &$build, EntityInterface $comment, EntityViewDisplayInterface $display, $view_mode) { + parent::alterBuild($build, $comment, $display, $view_mode); + if (empty($comment->in_preview)) { + $prefix = ''; + + // Add indentation div or close open divs as needed. + if ($build['#comment_threaded']) { + $prefix .= $build['#comment_indent'] <= 0 ? str_repeat('', abs($build['#comment_indent'])) : "\n" . '
'; + } + + // Add anchor for each comment. + $prefix .= "id()}\">\n"; + $build['#prefix'] = $prefix; + + // Close all open divs. + if (!empty($build['#comment_indent_final'])) { + $build['#suffix'] = str_repeat('
', $build['#comment_indent_final']); + } + } + } + +}