Version 1
[yaffs-website] / web / core / modules / node / src / Controller / NodeController.php
diff --git a/web/core/modules/node/src/Controller/NodeController.php b/web/core/modules/node/src/Controller/NodeController.php
new file mode 100644 (file)
index 0000000..4840147
--- /dev/null
@@ -0,0 +1,306 @@
+<?php
+
+namespace Drupal\node\Controller;
+
+use Drupal\Component\Utility\Xss;
+use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\Datetime\DateFormatterInterface;
+use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
+use Drupal\Core\Render\RendererInterface;
+use Drupal\Core\Url;
+use Drupal\node\NodeStorageInterface;
+use Drupal\node\NodeTypeInterface;
+use Drupal\node\NodeInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Returns responses for Node routes.
+ */
+class NodeController extends ControllerBase implements ContainerInjectionInterface {
+
+  /**
+   * The date formatter service.
+   *
+   * @var \Drupal\Core\Datetime\DateFormatterInterface
+   */
+  protected $dateFormatter;
+
+  /**
+   * The renderer service.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
+  /**
+   * Constructs a NodeController object.
+   *
+   * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
+   *   The date formatter service.
+   * @param \Drupal\Core\Render\RendererInterface $renderer
+   *   The renderer service.
+   */
+  public function __construct(DateFormatterInterface $date_formatter, RendererInterface $renderer) {
+    $this->dateFormatter = $date_formatter;
+    $this->renderer = $renderer;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('date.formatter'),
+      $container->get('renderer')
+    );
+  }
+
+  /**
+   * Displays add content links for available content types.
+   *
+   * Redirects to node/add/[type] if only one content type is available.
+   *
+   * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
+   *   A render array for a list of the node types that can be added; however,
+   *   if there is only one node type defined for the site, the function
+   *   will return a RedirectResponse to the node add page for that one node
+   *   type.
+   */
+  public function addPage() {
+    $build = [
+      '#theme' => 'node_add_list',
+      '#cache' => [
+        'tags' => $this->entityManager()->getDefinition('node_type')->getListCacheTags(),
+      ],
+    ];
+
+    $content = [];
+
+    // Only use node types the user has access to.
+    foreach ($this->entityManager()->getStorage('node_type')->loadMultiple() as $type) {
+      $access = $this->entityManager()->getAccessControlHandler('node')->createAccess($type->id(), NULL, [], TRUE);
+      if ($access->isAllowed()) {
+        $content[$type->id()] = $type;
+      }
+      $this->renderer->addCacheableDependency($build, $access);
+    }
+
+    // Bypass the node/add listing if only one content type is available.
+    if (count($content) == 1) {
+      $type = array_shift($content);
+      return $this->redirect('node.add', ['node_type' => $type->id()]);
+    }
+
+    $build['#content'] = $content;
+
+    return $build;
+  }
+
+  /**
+   * Provides the node submission form.
+   *
+   * @param \Drupal\node\NodeTypeInterface $node_type
+   *   The node type entity for the node.
+   *
+   * @return array
+   *   A node submission form.
+   */
+  public function add(NodeTypeInterface $node_type) {
+    $node = $this->entityManager()->getStorage('node')->create([
+      'type' => $node_type->id(),
+    ]);
+
+    $form = $this->entityFormBuilder()->getForm($node);
+
+    return $form;
+  }
+
+  /**
+   * Displays a node revision.
+   *
+   * @param int $node_revision
+   *   The node revision ID.
+   *
+   * @return array
+   *   An array suitable for drupal_render().
+   */
+  public function revisionShow($node_revision) {
+    $node = $this->entityManager()->getStorage('node')->loadRevision($node_revision);
+    $node = $this->entityManager()->getTranslationFromContext($node);
+    $node_view_controller = new NodeViewController($this->entityManager, $this->renderer, $this->currentUser());
+    $page = $node_view_controller->view($node);
+    unset($page['nodes'][$node->id()]['#cache']);
+    return $page;
+  }
+
+  /**
+   * Page title callback for a node revision.
+   *
+   * @param int $node_revision
+   *   The node revision ID.
+   *
+   * @return string
+   *   The page title.
+   */
+  public function revisionPageTitle($node_revision) {
+    $node = $this->entityManager()->getStorage('node')->loadRevision($node_revision);
+    return $this->t('Revision of %title from %date', ['%title' => $node->label(), '%date' => format_date($node->getRevisionCreationTime())]);
+  }
+
+  /**
+   * Generates an overview table of older revisions of a node.
+   *
+   * @param \Drupal\node\NodeInterface $node
+   *   A node object.
+   *
+   * @return array
+   *   An array as expected by drupal_render().
+   */
+  public function revisionOverview(NodeInterface $node) {
+    $account = $this->currentUser();
+    $langcode = $node->language()->getId();
+    $langname = $node->language()->getName();
+    $languages = $node->getTranslationLanguages();
+    $has_translations = (count($languages) > 1);
+    $node_storage = $this->entityManager()->getStorage('node');
+    $type = $node->getType();
+
+    $build['#title'] = $has_translations ? $this->t('@langname revisions for %title', ['@langname' => $langname, '%title' => $node->label()]) : $this->t('Revisions for %title', ['%title' => $node->label()]);
+    $header = [$this->t('Revision'), $this->t('Operations')];
+
+    $revert_permission = (($account->hasPermission("revert $type revisions") || $account->hasPermission('revert all revisions') || $account->hasPermission('administer nodes')) && $node->access('update'));
+    $delete_permission = (($account->hasPermission("delete $type revisions") || $account->hasPermission('delete all revisions') || $account->hasPermission('administer nodes')) && $node->access('delete'));
+
+    $rows = [];
+    $default_revision = $node->getRevisionId();
+
+    foreach ($this->getRevisionIds($node, $node_storage) as $vid) {
+      /** @var \Drupal\node\NodeInterface $revision */
+      $revision = $node_storage->loadRevision($vid);
+      // Only show revisions that are affected by the language that is being
+      // displayed.
+      if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) {
+        $username = [
+          '#theme' => 'username',
+          '#account' => $revision->getRevisionUser(),
+        ];
+
+        // Use revision link to link to revisions that are not active.
+        $date = $this->dateFormatter->format($revision->revision_timestamp->value, 'short');
+        if ($vid != $node->getRevisionId()) {
+          $link = $this->l($date, new Url('entity.node.revision', ['node' => $node->id(), 'node_revision' => $vid]));
+        }
+        else {
+          $link = $node->link($date);
+        }
+
+        $row = [];
+        $column = [
+          'data' => [
+            '#type' => 'inline_template',
+            '#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}',
+            '#context' => [
+              'date' => $link,
+              'username' => $this->renderer->renderPlain($username),
+              'message' => ['#markup' => $revision->revision_log->value, '#allowed_tags' => Xss::getHtmlTagList()],
+            ],
+          ],
+        ];
+        // @todo Simplify once https://www.drupal.org/node/2334319 lands.
+        $this->renderer->addCacheableDependency($column['data'], $username);
+        $row[] = $column;
+
+        if ($vid == $default_revision) {
+          $row[] = [
+            'data' => [
+              '#prefix' => '<em>',
+              '#markup' => $this->t('Current revision'),
+              '#suffix' => '</em>',
+            ],
+          ];
+
+          $rows[] = [
+            'data' => $row,
+            'class' => ['revision-current'],
+          ];
+        }
+        else {
+          $links = [];
+          if ($revert_permission) {
+            $links['revert'] = [
+              'title' => $vid < $node->getRevisionId() ? $this->t('Revert') : $this->t('Set as current revision'),
+              'url' => $has_translations ?
+                Url::fromRoute('node.revision_revert_translation_confirm', ['node' => $node->id(), 'node_revision' => $vid, 'langcode' => $langcode]) :
+                Url::fromRoute('node.revision_revert_confirm', ['node' => $node->id(), 'node_revision' => $vid]),
+            ];
+          }
+
+          if ($delete_permission) {
+            $links['delete'] = [
+              'title' => $this->t('Delete'),
+              'url' => Url::fromRoute('node.revision_delete_confirm', ['node' => $node->id(), 'node_revision' => $vid]),
+            ];
+          }
+
+          $row[] = [
+            'data' => [
+              '#type' => 'operations',
+              '#links' => $links,
+            ],
+          ];
+
+          $rows[] = $row;
+        }
+      }
+    }
+
+    $build['node_revisions_table'] = [
+      '#theme' => 'table',
+      '#rows' => $rows,
+      '#header' => $header,
+      '#attached' => [
+        'library' => ['node/drupal.node.admin'],
+      ],
+      '#attributes' => ['class' => 'node-revision-table'],
+    ];
+
+    $build['pager'] = ['#type' => 'pager'];
+
+    return $build;
+  }
+
+  /**
+   * The _title_callback for the node.add route.
+   *
+   * @param \Drupal\node\NodeTypeInterface $node_type
+   *   The current node.
+   *
+   * @return string
+   *   The page title.
+   */
+  public function addPageTitle(NodeTypeInterface $node_type) {
+    return $this->t('Create @name', ['@name' => $node_type->label()]);
+  }
+
+  /**
+   * Gets a list of node revision IDs for a specific node.
+   *
+   * @param \Drupal\node\NodeInterface $node
+   *   The node entity.
+   * @param \Drupal\node\NodeStorageInterface $node_storage
+   *   The node storage handler.
+   *
+   * @return int[]
+   *   Node revision IDs (in descending order).
+   */
+  protected function getRevisionIds(NodeInterface $node, NodeStorageInterface $node_storage) {
+    $result = $node_storage->getQuery()
+      ->allRevisions()
+      ->condition($node->getEntityType()->getKey('id'), $node->id())
+      ->sort($node->getEntityType()->getKey('revision'), 'DESC')
+      ->pager(50)
+      ->execute();
+    return array_keys($result);
+  }
+
+}