/**
  * Gets the moderation state entity linked to a content entity revision.
  *
  * @return \Drupal\content_moderation\ModerationStateInterface|null
  *   The moderation state configuration entity linked to a content entity
  *   revision.
  */
 protected function getModerationState()
 {
     $entity = $this->getEntity();
     if (!\Drupal::service('content_moderation.moderation_information')->shouldModerateEntitiesOfBundle($entity->getEntityType(), $entity->bundle())) {
         return NULL;
     }
     if ($entity->id() && $entity->getRevisionId()) {
         $revisions = \Drupal::service('entity.query')->get('content_moderation_state')->condition('content_entity_type_id', $entity->getEntityTypeId())->condition('content_entity_id', $entity->id())->condition('content_entity_revision_id', $entity->getRevisionId())->allRevisions()->sort('revision_id', 'DESC')->execute();
         if ($revision_to_load = key($revisions)) {
             /** @var \Drupal\content_moderation\ContentModerationStateInterface $content_moderation_state */
             $content_moderation_state = \Drupal::entityTypeManager()->getStorage('content_moderation_state')->loadRevision($revision_to_load);
             // Return the correct translation.
             $langcode = $entity->language()->getId();
             if (!$content_moderation_state->hasTranslation($langcode)) {
                 $content_moderation_state->addTranslation($langcode);
             }
             if ($content_moderation_state->language()->getId() !== $langcode) {
                 $content_moderation_state = $content_moderation_state->getTranslation($langcode);
             }
             return $content_moderation_state->get('moderation_state')->entity;
         }
     }
     // It is possible that the bundle does not exist at this point. For example,
     // the node type form creates a fake Node entity to get default values.
     // @see \Drupal\node\NodeTypeForm::form()
     $bundle_entity = \Drupal::entityTypeManager()->getStorage($entity->getEntityType()->getBundleEntityType())->load($entity->bundle());
     if ($bundle_entity && ($default = $bundle_entity->getThirdPartySetting('content_moderation', 'default_moderation_state'))) {
         return ModerationState::load($default);
     }
 }
 /**
  * Verify moderation state methods based on entity properties.
  *
  * @covers ::isPublishedState
  * @covers ::isDefaultRevisionState
  *
  * @dataProvider moderationStateProvider
  */
 public function testModerationStateProperties($published, $default_revision, $is_published, $is_default)
 {
     $moderation_state_id = $this->randomMachineName();
     $moderation_state = ModerationState::create(['id' => $moderation_state_id, 'label' => $this->randomString(), 'published' => $published, 'default_revision' => $default_revision]);
     $moderation_state->save();
     $moderation_state = ModerationState::load($moderation_state_id);
     $this->assertEquals($is_published, $moderation_state->isPublishedState());
     $this->assertEquals($is_default, $moderation_state->isDefaultRevisionState());
 }
 /**
  * {@inheritdoc}
  */
 public function calculateDependencies()
 {
     parent::calculateDependencies();
     if ($this->stateFrom) {
         $this->addDependency('config', ModerationState::load($this->stateFrom)->getConfigDependencyName());
     }
     if ($this->stateTo) {
         $this->addDependency('config', ModerationState::load($this->stateTo)->getConfigDependencyName());
     }
     return $this;
 }
 /**
  * Tests basic monolingual content moderation through the API.
  */
 public function testBasicModeration()
 {
     $node_type = NodeType::create(['type' => 'example']);
     $node_type->setThirdPartySetting('content_moderation', 'enabled', TRUE);
     $node_type->setThirdPartySetting('content_moderation', 'allowed_moderation_states', ['draft', 'published']);
     $node_type->setThirdPartySetting('content_moderation', 'default_moderation_state', 'draft');
     $node_type->save();
     $node = Node::create(['type' => 'example', 'title' => 'Test title']);
     $node->save();
     $node = $this->reloadNode($node);
     $this->assertEquals('draft', $node->moderation_state->entity->id());
     $published = ModerationState::load('published');
     $node->moderation_state->entity = $published;
     $node->save();
     $node = $this->reloadNode($node);
     $this->assertEquals('published', $node->moderation_state->entity->id());
     // Change the state without saving the node.
     $content_moderation_state = ContentModerationState::load(1);
     $content_moderation_state->set('moderation_state', 'draft');
     $content_moderation_state->setNewRevision(TRUE);
     $content_moderation_state->save();
     $node = $this->reloadNode($node, 3);
     $this->assertEquals('draft', $node->moderation_state->entity->id());
     $this->assertFalse($node->isPublished());
     // Get the default revision.
     $node = $this->reloadNode($node);
     $this->assertTrue($node->isPublished());
     $this->assertEquals(2, $node->getRevisionId());
     $node->moderation_state->target_id = 'published';
     $node->save();
     $node = $this->reloadNode($node, 4);
     $this->assertEquals('published', $node->moderation_state->entity->id());
     // Get the default revision.
     $node = $this->reloadNode($node);
     $this->assertTrue($node->isPublished());
     $this->assertEquals(4, $node->getRevisionId());
 }
 /**
  * {@inheritdoc}
  */
 public function validate($value, Constraint $constraint)
 {
     /** @var \Drupal\Core\Entity\EntityInterface $entity */
     $entity = $value->getEntity();
     // Ignore entities that are not subject to moderation anyway.
     if (!$this->moderationInformation->isModeratedEntity($entity)) {
         return;
     }
     // Ignore entities that are being created for the first time.
     if ($entity->isNew()) {
         return;
     }
     // 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)) {
         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());
     }
     if ($entity->moderation_state->target_id) {
         $new_state_id = $entity->moderation_state->target_id;
     } else {
         $new_state_id = $default = $this->moderationInformation->loadBundleEntity($entity->getEntityType()->getBundleEntityType(), $entity->bundle())->getThirdPartySetting('content_moderation', 'default_moderation_state');
     }
     if ($new_state_id) {
         $new_state = ModerationStateEntity::load($new_state_id);
     }
     // @todo - what if $new_state_id references something that does not exist or
     //   is null.
     if (!$this->validation->isTransitionAllowed($original_entity->moderation_state->entity, $new_state)) {
         $this->context->addViolation($constraint->message, ['%from' => $original_entity->moderation_state->entity->label(), '%to' => $new_state->label()]);
     }
 }