View source
<?php
namespace Drupal\wbm2cm;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleInstallerInterface;
use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
use Drupal\workflows\Entity\Workflow;
use Psr\Log\LoggerInterface;
class MigrateManager {
protected $configFactory;
protected $entityTypeManager;
protected $moduleInstaller;
protected $wbm2cmStore;
protected $stateMapStore;
protected $logger;
public function __construct(ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager, ModuleInstallerInterface $module_installer, KeyValueFactoryInterface $key_value_factory, LoggerInterface $logger) {
$this->configFactory = $config_factory;
$this->entityTypeManager = $entity_type_manager;
$this->moduleInstaller = $module_installer;
$this->migrateStore = $key_value_factory
->get('wbm2cm_migrate');
$this->stateMapStore = $key_value_factory
->get('wbm2cm_migrate_state_map');
$this->logger = $logger;
}
public function getValidationMessages() {
$messages = [];
return $messages;
}
public function isValid() {
return empty($this
->getValidationMessages());
}
public function setFinished() {
$this->migrateStore
->set('finished', TRUE);
}
public function setUnfinished() {
$this->migrateStore
->set('finished', FALSE);
}
public function isFinished() {
return TRUE == $this->migrateStore
->get('finished');
}
public function isComplete() {
if ($this
->isFinished()) {
$states = $this->stateMapStore
->getAll();
if (empty($states)) {
$this->logger
->debug('isComplete was called, it isFinished, and there are NO states remaining in storage.');
return TRUE;
}
else {
$this->logger
->debug('isComplete was called, it isFinished, but there are %count states remaining in storage.', [
'%count' => count($states),
]);
return FALSE;
}
}
$this->logger
->debug('isComplete was called and returned FALSE.');
return FALSE;
}
public function saveWorkbenchModerationStatesAndTransitions() {
$states = [];
foreach ($this->configFactory
->listAll('workbench_moderation.moderation_state.') as $state_ids) {
$state = $this->configFactory
->getEditable($state_ids);
$states[] = $state
->get();
}
$this->logger
->info('Found Workbench Moderation states: %state_ids', [
'%state_ids' => print_r($states, 1),
]);
$this->migrateStore
->set('states', $states);
$transitions = [];
foreach ($this->configFactory
->listAll('workbench_moderation.moderation_state_transition.') as $transition_ids) {
$transition = $this->configFactory
->getEditable($transition_ids);
$transitions[] = $transition
->get();
}
$this->logger
->info('Found Workbench Moderation transitions: %transition_ids', [
'%transition_ids' => print_r($transitions, 1),
]);
$this->migrateStore
->set('transitions', $transitions);
}
public function saveWorkbenchModerationSateMap() {
$this->entityTypeManager
->clearCachedDefinitions();
$enabled_bundles = [];
foreach ($this->configFactory
->listAll() as $bundle_config_id) {
$bundle_config = $this->configFactory
->getEditable($bundle_config_id);
if (!($third_party_settings = $bundle_config
->get('third_party_settings'))) {
$this->logger
->debug('Skipping entity bundle that is not moderated: %bundle_id', [
'%bundle_id' => $bundle_config_id,
]);
continue;
}
$third_party_settings_updated = array_diff_key($third_party_settings, array_flip([
'workbench_moderation',
]));
if (count($third_party_settings) !== count($third_party_settings_updated)) {
$this->logger
->debug('Found Workbench Moderation bundle that is moderated: %bundle_id', [
'%bundle_id' => $bundle_config_id,
]);
list($entity_provider, $bundle_config_prefix, $bundle_id) = explode('.', $bundle_config_id);
$entity_type_id = FALSE;
foreach ($this->entityTypeManager
->getDefinitions() as $entity_definition) {
if ($entity_definition
->getProvider() === $entity_provider && $entity_definition
->get('config_prefix') === $bundle_config_prefix) {
$entity_type_id = $entity_definition
->getBundleOf();
break;
}
}
if (!$entity_type_id) {
throw new \Exception('Something went wrong.');
}
$enabled_bundles[$entity_type_id][] = $bundle_id;
}
else {
$this->logger
->debug('Skipping Workbench Moderation bundle that is moderated, but is incorrect format? %bundle_id', [
'%bundle_id' => $bundle_config_id,
]);
}
}
$this->migrateStore
->set('enabled_bundles', $enabled_bundles);
foreach ($enabled_bundles as $entity_type_id => $bundles) {
$entity_storage = $this->entityTypeManager
->getStorage($entity_type_id);
foreach ($bundles as $bundle_id) {
$this->logger
->debug('Querying for all %bundle_id revisions...', [
'%bundle_id' => $bundle_id,
]);
$entity_revisions = \Drupal::entityQuery($entity_type_id)
->condition('type', $bundle_id)
->allRevisions()
->execute();
foreach ($entity_revisions as $revision_id => $id) {
$entity = $entity_storage
->loadRevision($revision_id);
$state_map_key = "state_map.{$entity_type_id}.{$bundle_id}.{$revision_id}";
$this->stateMapStore
->set($state_map_key, $entity->moderation_state->target_id);
$this->logger
->debug('Setting Workbench Moderation state field on id:%id, revision:%revision_id from %state to NULL', [
'%id' => $id,
'%revision_id' => $revision_id,
'%state' => $entity->moderation_state->target_id,
]);
$entity->moderation_state = NULL;
$entity
->save();
$languages = $entity
->getTranslationLanguages(FALSE);
$language_ids = [];
foreach ($languages as $language) {
$language_ids[] = $language
->getId();
}
$this->logger
->debug('Found the following translations on id:%id, revision:%revision_id: %languages', [
'%id' => $id,
'%revision_id' => $revision_id,
'%languages' => implode(', ', $language_ids),
]);
foreach ($language_ids as $language_id) {
$translated_entity = $entity
->getTranslation($language_id);
$state_map_key = "state_map.{$entity_type_id}.{$bundle_id}.{$revision_id}.{$language_id}";
$this->stateMapStore
->set($state_map_key, $translated_entity->moderation_state->target_id);
$this->logger
->debug('Setting Workbench Moderation state field on id:%id, revision:%revision_id, lang:%lang from %state to NULL', [
'%id' => $id,
'%revision_id' => $revision_id,
'%lang' => $language_id,
'%state' => $entity->moderation_state->target_id,
]);
$translated_entity->moderation_state = NULL;
$translated_entity
->save();
}
}
}
}
$this->logger
->notice('Workbench Moderation states have been removed from all entities and temporarily stored in key value storage.');
}
public function uninstallWorkbenchModeration() {
$this->moduleInstaller
->uninstall([
'workbench_moderation',
], FALSE);
$this->logger
->notice('Workbench Moderation module is uninstalled.');
}
public function installWorkflows() {
$this->moduleInstaller
->install([
'workflows',
]);
$this->logger
->notice('Workflows module is installed.');
}
public function installContentModeration() {
$this->moduleInstaller
->install([
'content_moderation',
]);
$this->logger
->notice('Content Moderation module is installed.');
}
public function recreateWorkbenchModerationWorkflow() {
$states = $this->migrateStore
->get('states');
$transitions = $this->migrateStore
->get('transitions');
$enabled_bundles = $this->migrateStore
->get('enabled_bundles');
$workflow_config = [
'id' => 'content_moderation_workflow',
'label' => 'Content Moderation Workflow',
'type' => 'content_moderation',
'type_settings' => [
'states' => [],
'transitions' => [],
],
];
foreach ($states as $state) {
$workflow_config['type_settings']['states'][$state['id']] = [
'label' => $state['label'],
'published' => $state['published'],
'default_revision' => $state['default_revision'],
];
}
foreach ($transitions as $transition) {
$workflow_config['type_settings']['transitions'][$transition['id']] = [
'label' => $transition['label'],
'to' => $transition['stateTo'],
'from' => explode(',', $transition['stateFrom']),
];
}
$this->logger
->info('Create workflow from config: %config', [
'%config' => print_r($workflow_config, 1),
]);
$workflow = new Workflow($workflow_config, 'workflow');
$workflow_type_plugin = $workflow
->getTypePlugin();
foreach ($enabled_bundles as $entity_type_id => $bundles) {
foreach ($bundles as $bundle_id) {
$workflow_type_plugin
->addEntityTypeAndBundle($entity_type_id, $bundle_id);
$this->logger
->notice('Setting Content Moderation to be enabled on %bundle_id', [
'%bundle_id' => $bundle_id,
]);
}
}
$workflow
->save();
$this->logger
->notice('Content Moderation Workflow created.');
}
public function recreateModerationStatesOnEntities() {
$enabled_bundles = $this->migrateStore
->get('enabled_bundles');
foreach ($enabled_bundles as $entity_type_id => $bundles) {
$entity_storage = $this->entityTypeManager
->getStorage($entity_type_id);
foreach ($bundles as $bundle_id) {
$this->logger
->debug('Querying for all %bundle_id revisions...', [
'%bundle_id' => $bundle_id,
]);
$entity_revisions = \Drupal::entityQuery($entity_type_id)
->condition('type', $bundle_id)
->allRevisions()
->execute();
$this->logger
->debug('Setting Content Moderation states on %bundle_id entities', [
'%bundle_id' => $bundle_id,
]);
foreach ($entity_revisions as $revision_id => $id) {
$state_map_key = "state_map.{$entity_type_id}.{$bundle_id}.{$revision_id}";
$state_id = $this->stateMapStore
->get($state_map_key);
if (!$state_id) {
$this->logger
->debug('Skipping updating state on id:%id, revision:%revision_id because no state exists', [
'%id' => $entity
->id(),
'%revision_id' => $revision_id,
'%state' => $state_id,
]);
continue;
}
$entity = $entity_storage
->loadRevision($revision_id);
$entity->moderation_state = $state_id;
$entity
->save();
$this->logger
->debug('Setting Workbench Moderation state field on id:%id, revision:%revision_id to %state', [
'%id' => $entity
->id(),
'%revision_id' => $revision_id,
'%state' => $state_id,
]);
$this->stateMapStore
->delete($state_map_key);
$languages = $entity
->getTranslationLanguages(FALSE);
$language_ids = [];
foreach ($languages as $language) {
$language_ids[] = $language
->getId();
}
foreach ($language_ids as $language_id) {
$translated_entity = $entity
->getTranslation($language_id);
$state_map_key = "state_map.{$entity_type_id}.{$bundle_id}.{$revision_id}.{$language_id}";
$state_id = $this->stateMapStore
->get($state_map_key);
if (!$state_id) {
$this->logger
->debug('Skipping updating state on id:%id, revision:%revision_id, lang:%lang because no state exists', [
'%id' => $translated_entity
->id(),
'%revision_id' => $revision_id,
'%lang' => $language_id,
'%state' => $state_id,
]);
continue;
}
$translated_entity->moderation_state = $state_id;
$translated_entity
->save();
$this->logger
->debug('Setting Workbench Moderation state field on id:%id, revision:%revision_id to %state', [
'%id' => $translated_entity
->id(),
'%revision_id' => $revision_id,
'%state' => $state_id,
]);
$this->stateMapStore
->delete($state_map_key);
}
}
}
}
}
public function cleanupKeyValue() {
$this->migrateStore
->deleteMultiple([
'states',
'transitions',
'enabled_bundles',
]);
}
public function purgeAllKeyValueStores() {
$this->migrateStore
->deleteAll();
$this->stateMapStore
->deleteAll();
}
}