Mercurial > hg > isophonics-drupal-site
comparison core/modules/node/src/Controller/NodeController.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 1fec387a4317 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\node\Controller; | |
4 | |
5 use Drupal\Component\Utility\Xss; | |
6 use Drupal\Core\Controller\ControllerBase; | |
7 use Drupal\Core\Datetime\DateFormatterInterface; | |
8 use Drupal\Core\DependencyInjection\ContainerInjectionInterface; | |
9 use Drupal\Core\Render\RendererInterface; | |
10 use Drupal\Core\Url; | |
11 use Drupal\node\NodeStorageInterface; | |
12 use Drupal\node\NodeTypeInterface; | |
13 use Drupal\node\NodeInterface; | |
14 use Symfony\Component\DependencyInjection\ContainerInterface; | |
15 | |
16 /** | |
17 * Returns responses for Node routes. | |
18 */ | |
19 class NodeController extends ControllerBase implements ContainerInjectionInterface { | |
20 | |
21 /** | |
22 * The date formatter service. | |
23 * | |
24 * @var \Drupal\Core\Datetime\DateFormatterInterface | |
25 */ | |
26 protected $dateFormatter; | |
27 | |
28 /** | |
29 * The renderer service. | |
30 * | |
31 * @var \Drupal\Core\Render\RendererInterface | |
32 */ | |
33 protected $renderer; | |
34 | |
35 /** | |
36 * Constructs a NodeController object. | |
37 * | |
38 * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter | |
39 * The date formatter service. | |
40 * @param \Drupal\Core\Render\RendererInterface $renderer | |
41 * The renderer service. | |
42 */ | |
43 public function __construct(DateFormatterInterface $date_formatter, RendererInterface $renderer) { | |
44 $this->dateFormatter = $date_formatter; | |
45 $this->renderer = $renderer; | |
46 } | |
47 | |
48 /** | |
49 * {@inheritdoc} | |
50 */ | |
51 public static function create(ContainerInterface $container) { | |
52 return new static( | |
53 $container->get('date.formatter'), | |
54 $container->get('renderer') | |
55 ); | |
56 } | |
57 | |
58 /** | |
59 * Displays add content links for available content types. | |
60 * | |
61 * Redirects to node/add/[type] if only one content type is available. | |
62 * | |
63 * @return array|\Symfony\Component\HttpFoundation\RedirectResponse | |
64 * A render array for a list of the node types that can be added; however, | |
65 * if there is only one node type defined for the site, the function | |
66 * will return a RedirectResponse to the node add page for that one node | |
67 * type. | |
68 */ | |
69 public function addPage() { | |
70 $build = [ | |
71 '#theme' => 'node_add_list', | |
72 '#cache' => [ | |
73 'tags' => $this->entityManager()->getDefinition('node_type')->getListCacheTags(), | |
74 ], | |
75 ]; | |
76 | |
77 $content = []; | |
78 | |
79 // Only use node types the user has access to. | |
80 foreach ($this->entityManager()->getStorage('node_type')->loadMultiple() as $type) { | |
81 $access = $this->entityManager()->getAccessControlHandler('node')->createAccess($type->id(), NULL, [], TRUE); | |
82 if ($access->isAllowed()) { | |
83 $content[$type->id()] = $type; | |
84 } | |
85 $this->renderer->addCacheableDependency($build, $access); | |
86 } | |
87 | |
88 // Bypass the node/add listing if only one content type is available. | |
89 if (count($content) == 1) { | |
90 $type = array_shift($content); | |
91 return $this->redirect('node.add', ['node_type' => $type->id()]); | |
92 } | |
93 | |
94 $build['#content'] = $content; | |
95 | |
96 return $build; | |
97 } | |
98 | |
99 /** | |
100 * Provides the node submission form. | |
101 * | |
102 * @param \Drupal\node\NodeTypeInterface $node_type | |
103 * The node type entity for the node. | |
104 * | |
105 * @return array | |
106 * A node submission form. | |
107 */ | |
108 public function add(NodeTypeInterface $node_type) { | |
109 $node = $this->entityManager()->getStorage('node')->create([ | |
110 'type' => $node_type->id(), | |
111 ]); | |
112 | |
113 $form = $this->entityFormBuilder()->getForm($node); | |
114 | |
115 return $form; | |
116 } | |
117 | |
118 /** | |
119 * Displays a node revision. | |
120 * | |
121 * @param int $node_revision | |
122 * The node revision ID. | |
123 * | |
124 * @return array | |
125 * An array suitable for drupal_render(). | |
126 */ | |
127 public function revisionShow($node_revision) { | |
128 $node = $this->entityManager()->getStorage('node')->loadRevision($node_revision); | |
129 $node = $this->entityManager()->getTranslationFromContext($node); | |
130 $node_view_controller = new NodeViewController($this->entityManager, $this->renderer, $this->currentUser()); | |
131 $page = $node_view_controller->view($node); | |
132 unset($page['nodes'][$node->id()]['#cache']); | |
133 return $page; | |
134 } | |
135 | |
136 /** | |
137 * Page title callback for a node revision. | |
138 * | |
139 * @param int $node_revision | |
140 * The node revision ID. | |
141 * | |
142 * @return string | |
143 * The page title. | |
144 */ | |
145 public function revisionPageTitle($node_revision) { | |
146 $node = $this->entityManager()->getStorage('node')->loadRevision($node_revision); | |
147 return $this->t('Revision of %title from %date', ['%title' => $node->label(), '%date' => format_date($node->getRevisionCreationTime())]); | |
148 } | |
149 | |
150 /** | |
151 * Generates an overview table of older revisions of a node. | |
152 * | |
153 * @param \Drupal\node\NodeInterface $node | |
154 * A node object. | |
155 * | |
156 * @return array | |
157 * An array as expected by drupal_render(). | |
158 */ | |
159 public function revisionOverview(NodeInterface $node) { | |
160 $account = $this->currentUser(); | |
161 $langcode = $node->language()->getId(); | |
162 $langname = $node->language()->getName(); | |
163 $languages = $node->getTranslationLanguages(); | |
164 $has_translations = (count($languages) > 1); | |
165 $node_storage = $this->entityManager()->getStorage('node'); | |
166 $type = $node->getType(); | |
167 | |
168 $build['#title'] = $has_translations ? $this->t('@langname revisions for %title', ['@langname' => $langname, '%title' => $node->label()]) : $this->t('Revisions for %title', ['%title' => $node->label()]); | |
169 $header = [$this->t('Revision'), $this->t('Operations')]; | |
170 | |
171 $revert_permission = (($account->hasPermission("revert $type revisions") || $account->hasPermission('revert all revisions') || $account->hasPermission('administer nodes')) && $node->access('update')); | |
172 $delete_permission = (($account->hasPermission("delete $type revisions") || $account->hasPermission('delete all revisions') || $account->hasPermission('administer nodes')) && $node->access('delete')); | |
173 | |
174 $rows = []; | |
175 $default_revision = $node->getRevisionId(); | |
176 | |
177 foreach ($this->getRevisionIds($node, $node_storage) as $vid) { | |
178 /** @var \Drupal\node\NodeInterface $revision */ | |
179 $revision = $node_storage->loadRevision($vid); | |
180 // Only show revisions that are affected by the language that is being | |
181 // displayed. | |
182 if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) { | |
183 $username = [ | |
184 '#theme' => 'username', | |
185 '#account' => $revision->getRevisionUser(), | |
186 ]; | |
187 | |
188 // Use revision link to link to revisions that are not active. | |
189 $date = $this->dateFormatter->format($revision->revision_timestamp->value, 'short'); | |
190 if ($vid != $node->getRevisionId()) { | |
191 $link = $this->l($date, new Url('entity.node.revision', ['node' => $node->id(), 'node_revision' => $vid])); | |
192 } | |
193 else { | |
194 $link = $node->link($date); | |
195 } | |
196 | |
197 $row = []; | |
198 $column = [ | |
199 'data' => [ | |
200 '#type' => 'inline_template', | |
201 '#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}', | |
202 '#context' => [ | |
203 'date' => $link, | |
204 'username' => $this->renderer->renderPlain($username), | |
205 'message' => ['#markup' => $revision->revision_log->value, '#allowed_tags' => Xss::getHtmlTagList()], | |
206 ], | |
207 ], | |
208 ]; | |
209 // @todo Simplify once https://www.drupal.org/node/2334319 lands. | |
210 $this->renderer->addCacheableDependency($column['data'], $username); | |
211 $row[] = $column; | |
212 | |
213 if ($vid == $default_revision) { | |
214 $row[] = [ | |
215 'data' => [ | |
216 '#prefix' => '<em>', | |
217 '#markup' => $this->t('Current revision'), | |
218 '#suffix' => '</em>', | |
219 ], | |
220 ]; | |
221 | |
222 $rows[] = [ | |
223 'data' => $row, | |
224 'class' => ['revision-current'], | |
225 ]; | |
226 } | |
227 else { | |
228 $links = []; | |
229 if ($revert_permission) { | |
230 $links['revert'] = [ | |
231 'title' => $vid < $node->getRevisionId() ? $this->t('Revert') : $this->t('Set as current revision'), | |
232 'url' => $has_translations ? | |
233 Url::fromRoute('node.revision_revert_translation_confirm', ['node' => $node->id(), 'node_revision' => $vid, 'langcode' => $langcode]) : | |
234 Url::fromRoute('node.revision_revert_confirm', ['node' => $node->id(), 'node_revision' => $vid]), | |
235 ]; | |
236 } | |
237 | |
238 if ($delete_permission) { | |
239 $links['delete'] = [ | |
240 'title' => $this->t('Delete'), | |
241 'url' => Url::fromRoute('node.revision_delete_confirm', ['node' => $node->id(), 'node_revision' => $vid]), | |
242 ]; | |
243 } | |
244 | |
245 $row[] = [ | |
246 'data' => [ | |
247 '#type' => 'operations', | |
248 '#links' => $links, | |
249 ], | |
250 ]; | |
251 | |
252 $rows[] = $row; | |
253 } | |
254 } | |
255 } | |
256 | |
257 $build['node_revisions_table'] = [ | |
258 '#theme' => 'table', | |
259 '#rows' => $rows, | |
260 '#header' => $header, | |
261 '#attached' => [ | |
262 'library' => ['node/drupal.node.admin'], | |
263 ], | |
264 '#attributes' => ['class' => 'node-revision-table'], | |
265 ]; | |
266 | |
267 $build['pager'] = ['#type' => 'pager']; | |
268 | |
269 return $build; | |
270 } | |
271 | |
272 /** | |
273 * The _title_callback for the node.add route. | |
274 * | |
275 * @param \Drupal\node\NodeTypeInterface $node_type | |
276 * The current node. | |
277 * | |
278 * @return string | |
279 * The page title. | |
280 */ | |
281 public function addPageTitle(NodeTypeInterface $node_type) { | |
282 return $this->t('Create @name', ['@name' => $node_type->label()]); | |
283 } | |
284 | |
285 /** | |
286 * Gets a list of node revision IDs for a specific node. | |
287 * | |
288 * @param \Drupal\node\NodeInterface $node | |
289 * The node entity. | |
290 * @param \Drupal\node\NodeStorageInterface $node_storage | |
291 * The node storage handler. | |
292 * | |
293 * @return int[] | |
294 * Node revision IDs (in descending order). | |
295 */ | |
296 protected function getRevisionIds(NodeInterface $node, NodeStorageInterface $node_storage) { | |
297 $result = $node_storage->getQuery() | |
298 ->allRevisions() | |
299 ->condition($node->getEntityType()->getKey('id'), $node->id()) | |
300 ->sort($node->getEntityType()->getKey('revision'), 'DESC') | |
301 ->pager(50) | |
302 ->execute(); | |
303 return array_keys($result); | |
304 } | |
305 | |
306 } |