Added Entity and Entity Reference Revisions which got dropped somewhere along the...
[yaffs-website] / web / modules / contrib / entity / src / Controller / RevisionControllerTrait.php
diff --git a/web/modules/contrib/entity/src/Controller/RevisionControllerTrait.php b/web/modules/contrib/entity/src/Controller/RevisionControllerTrait.php
new file mode 100644 (file)
index 0000000..6be025a
--- /dev/null
@@ -0,0 +1,192 @@
+<?php
+
+namespace Drupal\entity\Controller;
+
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Language\LanguageInterface;
+use Drupal\Core\Entity\EntityInterface;
+
+/**
+ * Defines a trait for common revision UI functionality.
+ */
+trait RevisionControllerTrait {
+
+  /**
+   * Returns the entity type manager.
+   *
+   * @return \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  abstract protected function entityTypeManager();
+
+  /**
+   * Returns the langauge manager.
+   *
+   * @return \Drupal\Core\Language\LanguageManagerInterface
+   */
+  abstract public function languageManager();
+
+  /**
+   * Determines if the user has permission to revert revisions.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The entity to check revert access for.
+   *
+   * @return bool
+   *   TRUE if the user has revert access.
+   */
+  abstract protected function hasRevertRevisionAccess(EntityInterface $entity);
+
+  /**
+   * Determines if the user has permission to delete revisions.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The entity to check delete revision access for.
+   *
+   * @return bool
+   *   TRUE if the user has delete revision access.
+   */
+  abstract protected function hasDeleteRevisionAccess(EntityInterface $entity);
+
+  /**
+   * Builds a link to revert an entity revision.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity_revision
+   *   The entity to build a revert revision link for.
+   *
+   * @return array
+   *   A link render array.
+   */
+  abstract protected function buildRevertRevisionLink(EntityInterface $entity_revision);
+
+  /**
+   * Builds a link to delete an entity revision.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity_revision
+   *   The entity to build a delete revision link for.
+   *
+   * @return array
+   *   A link render array.
+   */
+  abstract protected function buildDeleteRevisionLink(EntityInterface $entity_revision);
+
+  /**
+   * Returns a string providing details of the revision.
+   *
+   * E.g. Node describes its revisions using {date} by {username}. For the
+   *   non-current revision, it also provides a link to view that revision.
+   *
+   * @param \Drupal\Core\Entity\ContentEntityInterface $revision
+   *   The entity revision.
+   * @param bool $is_current
+   *   TRUE if the revision is the current revision.
+   *
+   * @return string
+   *   Returns a string to provide the details of the revision.
+   */
+  abstract protected function getRevisionDescription(ContentEntityInterface $revision, $is_current = FALSE);
+
+  /**
+   * Loads all revision IDs of an entity sorted by revision ID descending.
+   *
+   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
+   *   The entity.
+   *
+   * @return mixed[]
+   */
+  protected function revisionIds(ContentEntityInterface $entity) {
+    $entity_type = $entity->getEntityType();
+    $result = $this->entityTypeManager()->getStorage($entity_type->id())->getQuery()
+      ->allRevisions()
+      ->condition($entity_type->getKey('id'), $entity->id())
+      ->sort($entity_type->getKey('revision'), 'DESC')
+      ->execute();
+    return array_keys($result);
+  }
+
+  /**
+   * Generates an overview table of older revisions of an entity.
+   *
+   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
+   *   An entity object.
+   *
+   * @return array
+   *   A render array.
+   */
+  protected function revisionOverview(ContentEntityInterface $entity) {
+    $langcode = $this->languageManager()
+      ->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
+      ->getId();
+    /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $entity_storage */
+    $entity_storage = $this->entityTypeManager()->getStorage($entity->getEntityTypeId());
+    $revision_ids = $this->revisionIds($entity);
+    $entity_revisions = $entity_storage->loadMultipleRevisions($revision_ids);
+
+    $header = [$this->t('Revision'), $this->t('Operations')];
+    $rows = [];
+    foreach ($entity_revisions as $revision) {
+      $row = [];
+      /** @var \Drupal\Core\Entity\ContentEntityInterface $revision */
+      if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) {
+        $row[] = $this->getRevisionDescription($revision, $revision->isDefaultRevision());
+
+        if ($revision->isDefaultRevision()) {
+          $row[] = [
+            'data' => [
+              '#prefix' => '<em>',
+              '#markup' => $this->t('Current revision'),
+              '#suffix' => '</em>',
+            ],
+          ];
+          foreach ($row as &$current) {
+            $current['class'] = ['revision-current'];
+          }
+        }
+        else {
+          $links = $this->getOperationLinks($revision);
+          $row[] = [
+            'data' => [
+              '#type' => 'operations',
+              '#links' => $links,
+            ],
+          ];
+        }
+      }
+
+      $rows[] = $row;
+    }
+
+    $build[$entity->getEntityTypeId() . '_revisions_table'] = [
+      '#theme' => 'table',
+      '#rows' => $rows,
+      '#header' => $header,
+    ];
+
+    // We have no clue about caching yet.
+    $build['#cache']['max-age'] = 0;
+
+    return $build;
+  }
+
+  /**
+   * Get the links of the operations for an entity revision.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity_revision
+   *   The entity to build the revision links for.
+   *
+   * @return array
+   *   The operation links.
+   */
+  protected function getOperationLinks(EntityInterface $entity_revision) {
+    $links = [];
+    if ($this->hasRevertRevisionAccess($entity_revision)) {
+      $links['revert'] = $this->buildRevertRevisionLink($entity_revision);
+    }
+
+    if ($this->hasDeleteRevisionAccess($entity_revision)) {
+      $links['delete'] = $this->buildDeleteRevisionLink($entity_revision);
+    }
+
+    return array_filter($links);
+  }
+
+}