Security update for Core, with self-updated composer
[yaffs-website] / web / core / modules / content_moderation / src / Plugin / Validation / Constraint / ModerationStateConstraintValidator.php
index b664c65d2590123bec367fa7ed2404abb3c740fc..4b879737dae519ed5fb2bb89cea0da772d2824bf 100644 (file)
@@ -6,7 +6,6 @@ use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\content_moderation\ModerationInformationInterface;
-use Drupal\content_moderation\StateTransitionValidation;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\Validator\Constraint;
 use Symfony\Component\Validator\ConstraintValidator;
@@ -16,13 +15,6 @@ use Symfony\Component\Validator\ConstraintValidator;
  */
 class ModerationStateConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface {
 
-  /**
-   * The state transition validation.
-   *
-   * @var \Drupal\content_moderation\StateTransitionValidation
-   */
-  protected $validation;
-
   /**
    * The entity type manager.
    *
@@ -42,13 +34,10 @@ class ModerationStateConstraintValidator extends ConstraintValidator implements
    *
    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
    *   The entity type manager.
-   * @param \Drupal\content_moderation\StateTransitionValidation $validation
-   *   The state transition validation.
    * @param \Drupal\content_moderation\ModerationInformationInterface $moderation_information
    *   The moderation information.
    */
-  public function __construct(EntityTypeManagerInterface $entity_type_manager, StateTransitionValidation $validation, ModerationInformationInterface $moderation_information) {
-    $this->validation = $validation;
+  public function __construct(EntityTypeManagerInterface $entity_type_manager, ModerationInformationInterface $moderation_information) {
     $this->entityTypeManager = $entity_type_manager;
     $this->moderationInformation = $moderation_information;
   }
@@ -59,7 +48,6 @@ class ModerationStateConstraintValidator extends ConstraintValidator implements
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('entity_type.manager'),
-      $container->get('content_moderation.state_transition_validation'),
       $container->get('content_moderation.moderation_information')
     );
   }
@@ -68,7 +56,7 @@ class ModerationStateConstraintValidator extends ConstraintValidator implements
    * {@inheritdoc}
    */
   public function validate($value, Constraint $constraint) {
-    /** @var \Drupal\Core\Entity\EntityInterface $entity */
+    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
     $entity = $value->getEntity();
 
     // Ignore entities that are not subject to moderation anyway.
@@ -76,29 +64,43 @@ class ModerationStateConstraintValidator extends ConstraintValidator implements
       return;
     }
 
-    // Ignore entities that are being created for the first time.
-    if ($entity->isNew()) {
-      return;
-    }
+    $workflow = $this->moderationInformation->getWorkflowForEntity($entity);
 
-    // Ignore entities that are being moderated for the first time, such as
-    // when they existed before moderation was enabled for this entity type.
-    if ($this->isFirstTimeModeration($entity)) {
+    if (!$workflow->getTypePlugin()->hasState($entity->moderation_state->value)) {
+      // If the state we are transitioning to doesn't exist, we can't validate
+      // the transitions for this entity further.
+      $this->context->addViolation($constraint->invalidStateMessage, [
+        '%state' => $entity->moderation_state->value,
+        '%workflow' => $workflow->label(),
+      ]);
       return;
     }
 
-    $original_entity = $this->moderationInformation->getLatestRevision($entity->getEntityTypeId(), $entity->id());
-    if (!$entity->isDefaultTranslation() && $original_entity->hasTranslation($entity->language()->getId())) {
-      $original_entity = $original_entity->getTranslation($entity->language()->getId());
-    }
-
-    $workflow = $this->moderationInformation->getWorkflowForEntity($entity);
-    $new_state = $workflow->getState($entity->moderation_state->value) ?: $workflow->getInitialState();
-    $original_state = $workflow->getState($original_entity->moderation_state->value);
-    // @todo - what if $new_state references something that does not exist or
-    //   is null.
-    if (!$original_state->canTransitionTo($new_state->id())) {
-      $this->context->addViolation($constraint->message, ['%from' => $original_state->label(), '%to' => $new_state->label()]);
+    // If a new state is being set and there is an existing state, validate
+    // there is a valid transition between them.
+    if (!$entity->isNew() && !$this->isFirstTimeModeration($entity)) {
+      $original_entity = $this->entityTypeManager->getStorage($entity->getEntityTypeId())->loadRevision($entity->getLoadedRevisionId());
+      if (!$entity->isDefaultTranslation() && $original_entity->hasTranslation($entity->language()->getId())) {
+        $original_entity = $original_entity->getTranslation($entity->language()->getId());
+      }
+
+      // If the state of the original entity doesn't exist on the workflow,
+      // we cannot do any further validation of transitions, because none will
+      // be setup for a state that doesn't exist. Instead allow any state to
+      // take its place.
+      if (!$workflow->getTypePlugin()->hasState($original_entity->moderation_state->value)) {
+        return;
+      }
+
+      $new_state = $workflow->getTypePlugin()->getState($entity->moderation_state->value);
+      $original_state = $workflow->getTypePlugin()->getState($original_entity->moderation_state->value);
+
+      if (!$original_state->canTransitionTo($new_state->id())) {
+        $this->context->addViolation($constraint->message, [
+          '%from' => $original_state->label(),
+          '%to' => $new_state->label()
+        ]);
+      }
     }
   }