You are here

protected function ScheduledTransitionsRunner::transitionEntity in Scheduled Transitions 8

Same name and namespace in other branches
  1. 2.x 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 165

Class

ScheduledTransitionsRunner
Executes transitions.

Namespace

Drupal\scheduled_transitions

Code

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

  /** @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.
  $isLatestRevisionPublished = $this->moderationInformation
    ->isLiveRevision($latest);

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

  /** @var \Drupal\Core\Entity\EntityInterface|\Drupal\Core\Entity\RevisionableInterface $latest */
  $entityRevisionId = $newRevision
    ->getRevisionId();
  $workflow = $this->moderationInformation
    ->getWorkflowForEntity($latest);
  $workflowPlugin = $workflow
    ->getTypePlugin();
  $states = $workflowPlugin
    ->getStates();
  $originalNewRevisionState = $states[$newRevision->moderation_state->value ?? ''] ?? NULL;
  $originalLatestState = $states[$latest->moderation_state->value ?? ''] ?? NULL;
  $newState = $states[$scheduledTransition
    ->getState()] ?? NULL;
  $targs = [
    '@revision_id' => $entityRevisionId,
    '@original_state' => $originalNewRevisionState ? $originalNewRevisionState
      ->label() : $this
      ->t('- Unknown state -'),
    '@new_state' => $newState
      ->label(),
    '@original_revision_id' => $latest
      ->getRevisionId(),
    '@original_latest_state' => $originalLatestState ? $originalLatestState
      ->label() : $this
      ->t('- Unknown state -'),
  ];
  $tokenData = [
    'scheduled-transitions' => [
      'to-state' => $targs['@new_state'],
      'from-state' => $targs['@original_state'],
      'from-revision-id' => $targs['@revision_id'],
      'latest-state' => $targs['@original_latest_state'],
      'latest-revision-id' => $targs['@original_revision_id'],
    ],
  ];

  // Start the transition process.
  // Determine if latest before calling setNewRevision on $newRevision.
  $newIsLatest = $newRevision
    ->getRevisionId() === $latest
    ->getRevisionId();

  // 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->logger
      ->info('Transitioning latest revision from @original_state to @new_state', $targs);
    if ($newRevision instanceof RevisionLogInterface) {
      $template = $settings
        ->get('message_transition_latest');
      $log = $this->token
        ->replace($template, $tokenData);
      $newRevision
        ->setRevisionLogMessage($log);
      $newRevision
        ->setRevisionCreationTime($this->time
        ->getRequestTime());
    }
    $newRevision
      ->save();
  }
  else {
    $this->logger
      ->info('Copied revision #@revision_id and changed from @original_state to @new_state', $targs);
    if ($newRevision instanceof RevisionLogInterface) {
      $template = $settings
        ->get('message_transition_historical');
      $log = $this->token
        ->replace($template, $tokenData);
      $newRevision
        ->setRevisionLogMessage($log);
      $newRevision
        ->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->logger
          ->info('Reverted @original_latest_state revision #@original_revision_id back to top', $targs);
        if ($latest instanceof RevisionLogInterface) {
          $template = $settings
            ->get('message_transition_copy_latest_draft');
          $log = $this->token
            ->replace($template, $tokenData);
          $latest
            ->setRevisionLogMessage($log);
          $latest
            ->setRevisionCreationTime($this->time
            ->getRequestTime());
        }
        $latest
          ->save();
      }
    }
  }
}