Security update for Core, with self-updated composer
[yaffs-website] / web / core / modules / content_moderation / src / Entity / Routing / EntityModerationRouteProvider.php
diff --git a/web/core/modules/content_moderation/src/Entity/Routing/EntityModerationRouteProvider.php b/web/core/modules/content_moderation/src/Entity/Routing/EntityModerationRouteProvider.php
new file mode 100644 (file)
index 0000000..f72a47e
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+
+namespace Drupal\content_moderation\Entity\Routing;
+
+use Drupal\Core\Entity\EntityFieldManagerInterface;
+use Drupal\Core\Entity\EntityHandlerInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Entity\FieldableEntityInterface;
+use Drupal\Core\Entity\Routing\EntityRouteProviderInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * Dynamic route provider for the Content moderation module.
+ *
+ * Provides the following routes:
+ * - The latest version tab, showing the latest revision of an entity, not the
+ *   default one.
+ *
+ * @internal
+ */
+class EntityModerationRouteProvider implements EntityRouteProviderInterface, EntityHandlerInterface {
+
+  /**
+   * The entity manager.
+   *
+   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
+   */
+  protected $entityFieldManager;
+
+  /**
+   * Constructs a new DefaultHtmlRouteProvider.
+   *
+   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_manager
+   *   The entity manager.
+   */
+  public function __construct(EntityFieldManagerInterface $entity_manager) {
+    $this->entityFieldManager = $entity_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
+    return new static(
+      $container->get('entity_field.manager')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRoutes(EntityTypeInterface $entity_type) {
+    $collection = new RouteCollection();
+
+    if ($moderation_route = $this->getLatestVersionRoute($entity_type)) {
+      $entity_type_id = $entity_type->id();
+      $collection->add("entity.{$entity_type_id}.latest_version", $moderation_route);
+    }
+
+    return $collection;
+  }
+
+  /**
+   * Gets the moderation-form route.
+   *
+   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+   *   The entity type.
+   *
+   * @return \Symfony\Component\Routing\Route|null
+   *   The generated route, if available.
+   */
+  protected function getLatestVersionRoute(EntityTypeInterface $entity_type) {
+    if ($entity_type->hasLinkTemplate('latest-version') && $entity_type->hasViewBuilderClass()) {
+      $entity_type_id = $entity_type->id();
+      $route = new Route($entity_type->getLinkTemplate('latest-version'));
+      $route
+        ->addDefaults([
+          '_entity_view' => "{$entity_type_id}.full",
+          '_title_callback' => '\Drupal\Core\Entity\Controller\EntityController::title',
+        ])
+        // If the entity type is a node, unpublished content will be visible
+        // if the user has the "view all unpublished content" permission.
+        ->setRequirement('_entity_access', "{$entity_type_id}.view")
+        ->setRequirement('_content_moderation_latest_version', 'TRUE')
+        ->setOption('_content_moderation_entity_type', $entity_type_id)
+        ->setOption('parameters', [
+          $entity_type_id => [
+            'type' => 'entity:' . $entity_type_id,
+            'load_pending_revision' => 1,
+          ],
+        ]);
+
+      // Entity types with serial IDs can specify this in their route
+      // requirements, improving the matching process.
+      if ($this->getEntityTypeIdKeyType($entity_type) === 'integer') {
+        $route->setRequirement($entity_type_id, '\d+');
+      }
+      return $route;
+    }
+  }
+
+  /**
+   * Gets the type of the ID key for a given entity type.
+   *
+   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+   *   An entity type.
+   *
+   * @return string|null
+   *   The type of the ID key for a given entity type, or NULL if the entity
+   *   type does not support fields.
+   */
+  protected function getEntityTypeIdKeyType(EntityTypeInterface $entity_type) {
+    if (!$entity_type->entityClassImplements(FieldableEntityInterface::class)) {
+      return NULL;
+    }
+
+    $field_storage_definitions = $this->entityFieldManager->getFieldStorageDefinitions($entity_type->id());
+    return $field_storage_definitions[$entity_type->getKey('id')]->getType();
+  }
+
+}