You are here

protected function ScheduledTransitionsRunner::transitionEntity in Scheduled Transitions 2.x

Same name and namespace in other branches
  1. 8 src/ScheduledTransitionsRunner.php \Drupal\scheduled_transitions\ScheduledTransitionsRunner::transitionEntity()

Transition a revision.

This method is responsible for saving new revision, and any intermediate revisions if applicable.

Parameters

\Drupal\scheduled_transitions\Entity\ScheduledTransitionInterface $scheduledTransition: A scheduled transition entity.

\Drupal\Core\Entity\EntityInterface $newRevision: A new default revision.

\Drupal\Core\Entity\EntityInterface $latest: The latest current revision.

1 call to ScheduledTransitionsRunner::transitionEntity()
ScheduledTransitionsRunner::runTransition in src/ScheduledTransitionsRunner.php
Executes a transition.

File

src/ScheduledTransitionsRunner.php, line 177

Class

ScheduledTransitionsRunner
Executes transitions.

Namespace

Drupal\scheduled_transitions

Code

protected function transitionEntity(ScheduledTransitionInterface $scheduledTransition, EntityInterface $newRevision, EntityInterface $latest) : void {

  /** @var \Drupal\Core\Entity\EntityInterface|\Drupal\Core\Entity\RevisionableInterface $newRevision */

  /** @var \Drupal\Core\Entity\EntityInterface|\Drupal\Core\Entity\RevisionableInterface $latest */

  /** @var \Drupal\Core\Entity\RevisionableStorageInterface $entityStorage */
  $entityStorage = $this->entityTypeManager
    ->getStorage($newRevision
    ->getEntityTypeId());
  $settings = $this->configFactory
    ->get('scheduled_transitions.settings');

  // Check this now before any new saves.
  // Remove if Scheduled Transitions supports non CM workflows in the future.
  $isLatestRevisionPublished = NULL;
  $originalLatestState = NULL;
  $newState = NULL;
  if ($latest instanceof ContentEntityInterface) {
    $isLatestRevisionPublished = $this->moderationInformation
      ->isLiveRevision($latest);
    $workflow = $this->moderationInformation
      ->getWorkflowForEntity($latest);
    $workflowPlugin = $workflow
      ->getTypePlugin();
    $states = $workflowPlugin
      ->getStates();
    $originalLatestState = $states[$latest->moderation_state->value ?? ''] ?? NULL;
    $newState = $states[$scheduledTransition
      ->getState()] ?? NULL;
  }
  $replacements = new ScheduledTransitionsTokenReplacements($scheduledTransition, $newRevision, $latest);

  // Start the transition process.
  // Determine if latest before calling setNewRevision on $newRevision.
  $newIsLatest = $newRevision
    ->getRevisionId() === $latest
    ->getRevisionId();
  $revisionLog = $newRevision instanceof RevisionLogInterface ? $this->scheduledTransitionsUtility
    ->generateRevisionLog($scheduledTransition, $newRevision) : NULL;

  // Creating revisions via createRevision to invoke
  // setRevisionTranslationAffected and whatever other logic doesn't happen
  // automatically by simply setting setNewRevision on its own.
  // 'default' param: will be changed by content moderation anyway, and
  // ->setNewRevision() is called.
  $newRevision = $entityStorage
    ->createRevision($newRevision, FALSE);
  $newRevision->moderation_state = $newState
    ->id();
  if ($newRevision instanceof EntityChangedInterface) {
    $newRevision
      ->setChangedTime($this->time
      ->getRequestTime());
  }

  // If publishing the latest revision, then only set moderation state.
  if ($newIsLatest) {
    $this
      ->log(LogLevel::INFO, 'Transitioning latest revision from @original_state to @new_state', $replacements);
    if ($newRevision instanceof RevisionLogInterface && $revisionLog) {
      $newRevision
        ->setRevisionLogMessage($revisionLog)
        ->setRevisionCreationTime($this->time
        ->getRequestTime());
    }
    $newRevision
      ->save();
  }
  else {
    $this
      ->log(LogLevel::INFO, 'Copied revision #@revision_id and changed from @original_state to @new_state', $replacements);
    if ($newRevision instanceof RevisionLogInterface && $revisionLog) {
      $newRevision
        ->setRevisionLogMessage($revisionLog)
        ->setRevisionCreationTime($this->time
        ->getRequestTime());
    }
    $newRevision
      ->save();
    $options = $scheduledTransition
      ->getOptions();

    // If the new revision is now a default, and the old latest was not a
    // default (e.g Draft), then pull it back on top.
    if (!empty($options[ScheduledTransition::OPTION_RECREATE_NON_DEFAULT_HEAD])) {

      // To republish, this revision cannot be published, and the state for
      // this revision must still exist.
      if (!$isLatestRevisionPublished && $originalLatestState) {
        $latest = $entityStorage
          ->createRevision($latest, FALSE);
        $this
          ->log(LogLevel::INFO, 'Reverted @original_latest_state revision #@original_revision_id back to top', $replacements);
        if ($latest instanceof RevisionLogInterface) {
          $template = $settings
            ->get('message_transition_copy_latest_draft');
          $latest
            ->setRevisionLogMessage($this
            ->tokenReplace($template, $replacements))
            ->setRevisionCreationTime($this->time
            ->getRequestTime());
        }
        $latest
          ->save();
      }
    }
  }
}