class ScheduledTransitionsRunner in Scheduled Transitions 2.x
Same name and namespace in other branches
- 8 src/ScheduledTransitionsRunner.php \Drupal\scheduled_transitions\ScheduledTransitionsRunner
Executes transitions.
Hierarchy
- class \Drupal\scheduled_transitions\ScheduledTransitionsRunner implements ScheduledTransitionsRunnerInterface uses StringTranslationTrait
Expanded class hierarchy of ScheduledTransitionsRunner
1 string reference to 'ScheduledTransitionsRunner'
1 service uses ScheduledTransitionsRunner
File
- src/
ScheduledTransitionsRunner.php, line 29
Namespace
Drupal\scheduled_transitionsView source
class ScheduledTransitionsRunner implements ScheduledTransitionsRunnerInterface {
use StringTranslationTrait;
protected const LOCK_DURATION = 1800;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* System time.
*
* @var \Drupal\Component\Datetime\TimeInterface
*/
protected $time;
/**
* A logger instance.
*
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* General service for moderation-related questions about Entity API.
*
* @var \Drupal\content_moderation\ModerationInformationInterface
*/
protected $moderationInformation;
/**
* The token replacement system.
*
* @var \Drupal\Core\Utility\Token
*/
protected $token;
/**
* The configuration factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* The event dispatcher.
*
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
*/
protected $eventDispatcher;
/**
* Utilities for Scheduled Transitions module.
*
* @var \Drupal\scheduled_transitions\ScheduledTransitionsUtilityInterface
*/
protected $scheduledTransitionsUtility;
/**
* Constructs a new ScheduledTransitionsRunner.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The configuration factory.
* @param \Drupal\Component\Datetime\TimeInterface $time
* System time.
* @param \Psr\Log\LoggerInterface $logger
* A logger instance.
* @param \Drupal\content_moderation\ModerationInformationInterface $moderationInformation
* General service for moderation-related questions about Entity API.
* @param \Drupal\Core\Utility\Token $token
* The token replacement system.
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher
* The event dispatcher.
* @param \Drupal\scheduled_transitions\ScheduledTransitionsUtilityInterface $scheduledTransitionsUtility
* Utilities for Scheduled Transitions module.
*/
public function __construct(EntityTypeManagerInterface $entityTypeManager, ConfigFactoryInterface $configFactory, TimeInterface $time, LoggerInterface $logger, ModerationInformationInterface $moderationInformation, Token $token, EventDispatcherInterface $eventDispatcher, ScheduledTransitionsUtilityInterface $scheduledTransitionsUtility) {
$this->entityTypeManager = $entityTypeManager;
$this->configFactory = $configFactory;
$this->time = $time;
$this->logger = $logger;
$this->moderationInformation = $moderationInformation;
$this->token = $token;
$this->eventDispatcher = $eventDispatcher;
$this->scheduledTransitionsUtility = $scheduledTransitionsUtility;
}
/**
* {@inheritdoc}
*/
public function runTransition(ScheduledTransitionInterface $scheduledTransition) : void {
$scheduledTransitionId = $scheduledTransition
->id();
$targs = [
'@id' => $scheduledTransitionId,
];
$entity = $scheduledTransition
->getEntity();
if (!$entity) {
$this->logger
->info('Entity does not exist for scheduled transition #@id', $targs);
throw new ScheduledTransitionMissingEntity(sprintf('Entity does not exist for scheduled transition #%s', $scheduledTransitionId));
}
$event = new ScheduledTransitionsNewRevisionEvent($scheduledTransition);
$this->eventDispatcher
->dispatch(ScheduledTransitionsEvents::NEW_REVISION, $event);
$newRevision = $event
->getNewRevision();
if (!$newRevision) {
throw new ScheduledTransitionMissingEntity(sprintf('No revision could be determined to transition to for scheduled transition #%s', $scheduledTransitionId));
}
/** @var \Drupal\Core\Entity\EntityStorageInterface|\Drupal\Core\Entity\RevisionableStorageInterface $entityStorage */
$entityStorage = $this->entityTypeManager
->getStorage($entity
->getEntityTypeId());
$latestRevisionId = $entityStorage
->getLatestRevisionId($entity
->id());
if ($latestRevisionId) {
/** @var \Drupal\Core\Entity\EntityInterface|\Drupal\Core\Entity\RevisionableInterface $latest */
$latest = $entityStorage
->loadRevision($latestRevisionId);
}
if (!isset($latest)) {
$this->logger
->info('Latest revision does not exist for scheduled transition #@id', $targs);
throw new ScheduledTransitionMissingEntity(sprintf('Latest revision does not exist for scheduled transition #%s', $scheduledTransitionId));
}
$this
->transitionEntity($scheduledTransition, $newRevision, $latest);
$this->logger
->info('Deleted scheduled transition #@id', $targs);
$scheduledTransition
->delete();
}
/**
* Transition a revision.
*
* This method is responsible for saving new revision, and any intermediate
* revisions if applicable.
*
* @param \Drupal\scheduled_transitions\Entity\ScheduledTransitionInterface $scheduledTransition
* A scheduled transition entity.
* @param \Drupal\Core\Entity\EntityInterface $newRevision
* A new default revision.
* @param \Drupal\Core\Entity\EntityInterface $latest
* The latest current revision.
*/
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();
}
}
}
}
/**
* Logs a message and adds context.
*
* @param mixed $level
* Log level.
* @param string $message
* A log message.
* @param \Drupal\scheduled_transitions\ScheduledTransitionsTokenReplacements $replacements
* A replacements object.
*/
protected function log($level, string $message, ScheduledTransitionsTokenReplacements $replacements) : void {
$variables = $replacements
->getReplacements();
$targs = [
'@new_state' => $variables['to-state'],
'@original_state' => $variables['from-state'],
'@revision_id' => $variables['from-revision-id'],
'@original_latest_state' => $variables['latest-state'],
'@original_revision_id' => $variables['latest-revision-id'],
];
$this->logger
->log($level, $message, $targs);
}
/**
* Replaces all tokens in a given string with appropriate values.
*
* @param string $text
* A string containing replaceable tokens.
* @param \Drupal\scheduled_transitions\ScheduledTransitionsTokenReplacements $replacements
* A replacements object.
*
* @return string
* The string with the tokens replaced.
*/
protected function tokenReplace(string $text, ScheduledTransitionsTokenReplacements $replacements) : string {
$tokenData = [
'scheduled-transitions' => $replacements
->getReplacements(),
];
return $this->token
->replace($text, $tokenData);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
ScheduledTransitionsRunner:: |
protected | property | The configuration factory. | |
ScheduledTransitionsRunner:: |
protected | property | The entity type manager. | |
ScheduledTransitionsRunner:: |
protected | property | The event dispatcher. | |
ScheduledTransitionsRunner:: |
protected | property | A logger instance. | |
ScheduledTransitionsRunner:: |
protected | property | General service for moderation-related questions about Entity API. | |
ScheduledTransitionsRunner:: |
protected | property | Utilities for Scheduled Transitions module. | |
ScheduledTransitionsRunner:: |
protected | property | System time. | |
ScheduledTransitionsRunner:: |
protected | property | The token replacement system. | |
ScheduledTransitionsRunner:: |
protected | constant | ||
ScheduledTransitionsRunner:: |
protected | function | Logs a message and adds context. | |
ScheduledTransitionsRunner:: |
public | function |
Executes a transition. Overrides ScheduledTransitionsRunnerInterface:: |
|
ScheduledTransitionsRunner:: |
protected | function | Replaces all tokens in a given string with appropriate values. | |
ScheduledTransitionsRunner:: |
protected | function | Transition a revision. | |
ScheduledTransitionsRunner:: |
public | function | Constructs a new ScheduledTransitionsRunner. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 4 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |