annotate core/modules/node/src/Controller/NodeViewController.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\node\Controller;
Chris@0 4
Chris@0 5 use Drupal\Core\Entity\EntityInterface;
Chris@0 6 use Drupal\Core\Entity\Controller\EntityViewController;
Chris@18 7 use Drupal\Core\Entity\EntityRepositoryInterface;
Chris@18 8 use Drupal\Core\Entity\EntityTypeManagerInterface;
Chris@0 9 use Drupal\Core\Render\RendererInterface;
Chris@0 10 use Drupal\Core\Session\AccountInterface;
Chris@0 11 use Symfony\Component\DependencyInjection\ContainerInterface;
Chris@0 12
Chris@0 13 /**
Chris@0 14 * Defines a controller to render a single node.
Chris@0 15 */
Chris@0 16 class NodeViewController extends EntityViewController {
Chris@0 17
Chris@0 18 /**
Chris@0 19 * The current user.
Chris@0 20 *
Chris@0 21 * @var \Drupal\Core\Session\AccountInterface
Chris@0 22 */
Chris@0 23 protected $currentUser;
Chris@0 24
Chris@0 25 /**
Chris@18 26 * The entity repository service.
Chris@18 27 *
Chris@18 28 * @var \Drupal\Core\Entity\EntityRepositoryInterface
Chris@18 29 */
Chris@18 30 protected $entityRepository;
Chris@18 31
Chris@18 32 /**
Chris@0 33 * Creates an NodeViewController object.
Chris@0 34 *
Chris@18 35 * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
Chris@18 36 * The entity type manager.
Chris@0 37 * @param \Drupal\Core\Render\RendererInterface $renderer
Chris@0 38 * The renderer service.
Chris@0 39 * @param \Drupal\Core\Session\AccountInterface $current_user
Chris@0 40 * The current user. For backwards compatibility this is optional, however
Chris@0 41 * this will be removed before Drupal 9.0.0.
Chris@18 42 * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
Chris@18 43 * The entity repository.
Chris@0 44 */
Chris@18 45 public function __construct(EntityTypeManagerInterface $entity_type_manager, RendererInterface $renderer, AccountInterface $current_user = NULL, EntityRepositoryInterface $entity_repository = NULL) {
Chris@18 46 parent::__construct($entity_type_manager, $renderer);
Chris@0 47 $this->currentUser = $current_user ?: \Drupal::currentUser();
Chris@18 48 if (!$entity_repository) {
Chris@18 49 @trigger_error('The entity.repository service must be passed to NodeViewController::__construct(), it is required before Drupal 9.0.0. See https://www.drupal.org/node/2549139.', E_USER_DEPRECATED);
Chris@18 50 $entity_repository = \Drupal::service('entity.repository');
Chris@18 51 }
Chris@18 52 $this->entityRepository = $entity_repository;
Chris@0 53 }
Chris@0 54
Chris@0 55 /**
Chris@0 56 * {@inheritdoc}
Chris@0 57 */
Chris@0 58 public static function create(ContainerInterface $container) {
Chris@0 59 return new static(
Chris@18 60 $container->get('entity_type.manager'),
Chris@0 61 $container->get('renderer'),
Chris@18 62 $container->get('current_user'),
Chris@18 63 $container->get('entity.repository')
Chris@0 64 );
Chris@0 65 }
Chris@0 66
Chris@0 67 /**
Chris@0 68 * {@inheritdoc}
Chris@0 69 */
Chris@0 70 public function view(EntityInterface $node, $view_mode = 'full', $langcode = NULL) {
Chris@0 71 $build = parent::view($node, $view_mode, $langcode);
Chris@0 72
Chris@0 73 foreach ($node->uriRelationships() as $rel) {
Chris@18 74 $url = $node->toUrl($rel)->setAbsolute(TRUE);
Chris@0 75 // Add link relationships if the user is authenticated or if the anonymous
Chris@0 76 // user has access. Access checking must be done for anonymous users to
Chris@0 77 // avoid traffic to inaccessible pages from web crawlers. For
Chris@0 78 // authenticated users, showing the links in HTML head does not impact
Chris@0 79 // user experience or security, since the routes are access checked when
Chris@0 80 // visited and only visible via view source. This prevents doing
Chris@0 81 // potentially expensive and hard to cache access checks on every request.
Chris@0 82 // This means that the page will vary by user.permissions. We also rely on
Chris@0 83 // the access checking fallback to ensure the correct cacheability
Chris@0 84 // metadata if we have to check access.
Chris@0 85 if ($this->currentUser->isAuthenticated() || $url->access($this->currentUser)) {
Chris@0 86 // Set the node path as the canonical URL to prevent duplicate content.
Chris@0 87 $build['#attached']['html_head_link'][] = [
Chris@0 88 [
Chris@0 89 'rel' => $rel,
Chris@0 90 'href' => $url->toString(),
Chris@0 91 ],
Chris@0 92 TRUE,
Chris@0 93 ];
Chris@0 94 }
Chris@0 95
Chris@0 96 if ($rel == 'canonical') {
Chris@0 97 // Set the non-aliased canonical path as a default shortlink.
Chris@0 98 $build['#attached']['html_head_link'][] = [
Chris@0 99 [
Chris@0 100 'rel' => 'shortlink',
Chris@0 101 'href' => $url->setOption('alias', TRUE)->toString(),
Chris@0 102 ],
Chris@0 103 TRUE,
Chris@0 104 ];
Chris@0 105 }
Chris@0 106 }
Chris@0 107
Chris@18 108 // Since this generates absolute URLs, it can only be cached "per site".
Chris@18 109 $build['#cache']['contexts'][] = 'url.site';
Chris@18 110
Chris@0 111 // Given this varies by $this->currentUser->isAuthenticated(), add a cache
Chris@0 112 // context based on the anonymous role.
Chris@0 113 $build['#cache']['contexts'][] = 'user.roles:anonymous';
Chris@0 114
Chris@0 115 return $build;
Chris@0 116 }
Chris@0 117
Chris@0 118 /**
Chris@0 119 * The _title_callback for the page that renders a single node.
Chris@0 120 *
Chris@0 121 * @param \Drupal\Core\Entity\EntityInterface $node
Chris@0 122 * The current node.
Chris@0 123 *
Chris@0 124 * @return string
Chris@0 125 * The page title.
Chris@0 126 */
Chris@0 127 public function title(EntityInterface $node) {
Chris@18 128 return $this->entityRepository->getTranslationFromContext($node)->label();
Chris@0 129 }
Chris@0 130
Chris@0 131 }