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