View source
<?php
declare (strict_types=1);
namespace Drupal\scheduled_transitions;
use Drupal\content_moderation\ModerationInformationInterface;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\RevisionLogInterface;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\Core\Utility\Token;
use Drupal\scheduled_transitions\Entity\ScheduledTransitionInterface;
use Drupal\scheduled_transitions\Exception\ScheduledTransitionMissingEntity;
use Drupal\scheduled_transitions\Form\ScheduledTransitionsSettingsForm as SettingsForm;
class ScheduledTransitionsUtility implements ScheduledTransitionsUtilityInterface {
protected $configFactory;
protected $cache;
protected $entityTypeManager;
protected $bundleInfo;
protected $moderationInformation;
protected $token;
protected $stringTranslation;
protected const CID_SCHEDULED_TRANSITIONS_BUNDLES = 'scheduled_transitions_enabled_bundles';
public const QUERY_TAG_TARGET_REVISIONS = 'scheduled_transitions_target_revisions';
public function __construct(ConfigFactoryInterface $configFactory, CacheBackendInterface $cache, EntityTypeManagerInterface $entityTypeManager, EntityTypeBundleInfoInterface $bundleInfo, ModerationInformationInterface $moderationInformation, Token $token, TranslationInterface $stringTranslation) {
$this->configFactory = $configFactory;
$this->cache = $cache;
$this->entityTypeManager = $entityTypeManager;
$this->bundleInfo = $bundleInfo;
$this->moderationInformation = $moderationInformation;
$this->token = $token;
$this->stringTranslation = $stringTranslation;
}
public function getTransitions(EntityInterface $entity) : array {
$transitionStorage = $this->entityTypeManager
->getStorage('scheduled_transition');
$ids = $transitionStorage
->getQuery()
->condition('entity__target_type', $entity
->getEntityTypeId())
->condition('entity__target_id', $entity
->id())
->execute();
return $transitionStorage
->loadMultiple($ids);
}
public function getApplicableBundles() : array {
$bundles = [];
$bundleInfo = $this->bundleInfo
->getAllBundleInfo();
foreach ($bundleInfo as $entityTypeId => $entityTypeBundles) {
$entityType = $this->entityTypeManager
->getDefinition($entityTypeId);
$entityTypeBundles = array_filter($entityTypeBundles, function ($bundleId) use ($entityType) : bool {
return $this->moderationInformation
->shouldModerateEntitiesOfBundle($entityType, $bundleId);
}, \ARRAY_FILTER_USE_KEY);
$bundles[$entityTypeId] = array_keys($entityTypeBundles);
}
return array_filter($bundles);
}
public function getBundles() : array {
$enabledBundlesCache = $this->cache
->get(static::CID_SCHEDULED_TRANSITIONS_BUNDLES);
if ($enabledBundlesCache !== FALSE) {
return $enabledBundlesCache->data ?? [];
}
$enabledBundles = $this->configFactory
->get('scheduled_transitions.settings')
->get('bundles');
$enabledBundles = array_map(function (array $bundleConfig) {
return sprintf('%s:%s', $bundleConfig['entity_type'], $bundleConfig['bundle']);
}, is_array($enabledBundles) ? $enabledBundles : []);
$applicableBundles = $this
->getApplicableBundles();
foreach ($applicableBundles as $entityTypeId => &$bundles) {
$bundles = array_filter($bundles, function (string $bundle) use ($entityTypeId, $enabledBundles) {
return in_array($entityTypeId . ':' . $bundle, $enabledBundles);
});
}
$applicableBundles = array_filter($applicableBundles);
$this->cache
->set(static::CID_SCHEDULED_TRANSITIONS_BUNDLES, $applicableBundles, Cache::PERMANENT, [
SettingsForm::SETTINGS_TAG,
]);
return $applicableBundles;
}
public function getTargetRevisionIds(EntityInterface $entity, string $language) : array {
$entityStorage = $this->entityTypeManager
->getStorage($entity
->getEntityTypeId());
$entityDefinition = $entityStorage
->getEntityType();
$ids = $entityStorage
->getQuery()
->allRevisions()
->condition($entityDefinition
->getKey('id'), $entity
->id())
->condition($entityDefinition
->getKey('langcode'), $language)
->sort($entityDefinition
->getKey('revision'), 'DESC')
->addTag(static::QUERY_TAG_TARGET_REVISIONS)
->execute();
return array_keys($ids);
}
public function generateRevisionLog(ScheduledTransitionInterface $scheduledTransition, RevisionLogInterface $newRevision) : string {
$entityStorage = $this->entityTypeManager
->getStorage($newRevision
->getEntityTypeId());
$latestRevisionId = $entityStorage
->getLatestRevisionId($newRevision
->id());
if ($latestRevisionId) {
$latest = $entityStorage
->loadRevision($latestRevisionId);
}
if (!isset($latest)) {
throw new ScheduledTransitionMissingEntity(sprintf('Could not determine latest revision.'));
}
$options = $scheduledTransition
->getOptions();
if (($options['revision_log_override'] ?? NULL) === TRUE) {
$template = $options['revision_log'] ?? '';
}
else {
$newIsLatest = $newRevision
->getRevisionId() === $latest
->getRevisionId();
$settings = $this->configFactory
->get('scheduled_transitions.settings');
$template = $newIsLatest ? $settings
->get('message_transition_latest') : $settings
->get('message_transition_historical');
}
$replacements = new ScheduledTransitionsTokenReplacements($scheduledTransition, $newRevision, $latest);
$replacements
->setStringTranslation($this->stringTranslation);
return $this
->tokenReplace($template, $replacements);
}
public static function createScheduledTransitionsCacheTag(EntityInterface $entity) : string {
return sprintf('scheduled_transitions_for:%s:%s', $entity
->getEntityTypeId(), $entity
->id());
}
protected function tokenReplace(string $text, ScheduledTransitionsTokenReplacements $replacements) : string {
$tokenData = [
'scheduled-transitions' => $replacements
->getReplacements(),
];
return $this->token
->replace($text, $tokenData);
}
}