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 }
|