Chris@14: getTypePlugin(); Chris@14: foreach ($plugin->getEntityTypes() as $entity_type_id) { Chris@14: $sandbox['entity_type_ids'][$entity_type_id] = $entity_type_id; Chris@14: foreach ($plugin->getBundlesForEntityType($entity_type_id) as $bundle) { Chris@14: $sandbox['bundles'][$entity_type_id][$bundle] = $bundle; Chris@14: } Chris@14: } Chris@14: } Chris@14: $sandbox['offset'] = 0; Chris@14: $sandbox['limit'] = Settings::get('entity_update_batch_size', 50); Chris@14: $sandbox['total'] = count($sandbox['entity_type_ids']); Chris@14: $entity_type_id = array_shift($sandbox['entity_type_ids']); Chris@14: } Chris@14: Chris@14: // If there are no moderated bundles or we processed all of them, we are done. Chris@14: $entity_type_manager = \Drupal::entityTypeManager(); Chris@14: /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $content_moderation_state_storage */ Chris@14: $content_moderation_state_storage = $entity_type_manager->getStorage('content_moderation_state'); Chris@14: if (!$entity_type_id) { Chris@14: $content_moderation_state_storage->resetCache(); Chris@14: $sandbox['#finished'] = 1; Chris@14: return; Chris@14: } Chris@14: Chris@14: // Retrieve a batch of moderated entities to be processed. Chris@14: $storage = $entity_type_manager->getStorage($entity_type_id); Chris@14: $entity_type = $entity_type_manager->getDefinition($entity_type_id); Chris@14: $query = $storage->getQuery() Chris@14: ->accessCheck(FALSE) Chris@14: ->sort($entity_type->getKey('id')) Chris@14: ->range($sandbox['offset'], $sandbox['limit']); Chris@14: $bundle_key = $entity_type->getKey('bundle'); Chris@14: if ($bundle_key && !empty($sandbox['bundles'][$entity_type_id])) { Chris@14: $bundles = array_keys($sandbox['bundles'][$entity_type_id]); Chris@14: $query->condition($bundle_key, $bundles, 'IN'); Chris@14: } Chris@14: $entity_ids = $query->execute(); Chris@14: Chris@14: // Compute progress status and skip to the next entity type, if needed. Chris@14: $sandbox['#finished'] = ($sandbox['total'] - count($sandbox['entity_type_ids']) - 1) / $sandbox['total']; Chris@14: if (!$entity_ids) { Chris@14: $sandbox['offset'] = 0; Chris@14: $entity_type_id = array_shift($sandbox['entity_type_ids']) ?: FALSE; Chris@14: return; Chris@14: } Chris@14: Chris@14: // Load the "content_moderation_state" revisions corresponding to the Chris@14: // moderated entity default revisions. Chris@14: $result = $content_moderation_state_storage->getQuery() Chris@14: ->allRevisions() Chris@14: ->condition('content_entity_type_id', $entity_type_id) Chris@14: ->condition('content_entity_revision_id', array_keys($entity_ids), 'IN') Chris@14: ->execute(); Chris@14: /** @var \Drupal\Core\Entity\ContentEntityInterface[] $revisions */ Chris@14: $revisions = $content_moderation_state_storage->loadMultipleRevisions(array_keys($result)); Chris@14: Chris@14: // Update "content_moderation_state" data. Chris@14: foreach ($revisions as $revision) { Chris@14: if (!$revision->isDefaultRevision()) { Chris@14: $revision->setNewRevision(FALSE); Chris@14: $revision->isDefaultRevision(TRUE); Chris@14: $content_moderation_state_storage->save($revision); Chris@14: } Chris@14: } Chris@14: Chris@14: // Clear static cache to avoid memory issues. Chris@14: $storage->resetCache($entity_ids); Chris@14: Chris@14: $sandbox['offset'] += $sandbox['limit']; Chris@14: } Chris@18: Chris@18: /** Chris@18: * Set the default moderation state for new content to 'draft'. Chris@18: */ Chris@18: function content_moderation_post_update_set_default_moderation_state(&$sandbox) { Chris@18: \Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'workflow', function (Workflow $workflow) { Chris@18: if ($workflow->get('type') === 'content_moderation') { Chris@18: $configuration = $workflow->getTypePlugin()->getConfiguration(); Chris@18: $configuration['default_moderation_state'] = 'draft'; Chris@18: $workflow->getTypePlugin()->setConfiguration($configuration); Chris@18: return TRUE; Chris@18: } Chris@18: return FALSE; Chris@18: }); Chris@18: } Chris@18: Chris@18: /** Chris@18: * Set the filter on the moderation view to be the latest translation affected. Chris@18: */ Chris@18: function content_moderation_post_update_set_views_filter_latest_translation_affected_revision(&$sandbox) { Chris@18: $original_plugin_name = 'latest_revision'; Chris@18: $new_plugin_name = 'latest_translation_affected_revision'; Chris@18: Chris@18: // Check that views is installed and the moderated content view exists. Chris@18: if (\Drupal::moduleHandler()->moduleExists('views') && $view = View::load('moderated_content')) { Chris@18: $display = &$view->getDisplay('default'); Chris@18: if (!isset($display['display_options']['filters'][$original_plugin_name])) { Chris@18: return; Chris@18: } Chris@18: Chris@18: $translation_affected_filter = [ Chris@18: 'id' => $new_plugin_name, Chris@18: 'field' => $new_plugin_name, Chris@18: 'plugin_id' => $new_plugin_name, Chris@18: ] + $display['display_options']['filters'][$original_plugin_name]; Chris@18: Chris@18: $display['display_options']['filters'] = [$new_plugin_name => $translation_affected_filter] + $display['display_options']['filters']; Chris@18: unset($display['display_options']['filters'][$original_plugin_name]); Chris@18: Chris@18: $view->save(); Chris@18: } Chris@18: } Chris@18: Chris@18: /** Chris@18: * Update the dependencies of entity displays to include associated workflow. Chris@18: */ Chris@18: function content_moderation_post_update_entity_display_dependencies(&$sandbox) { Chris@18: /** @var \Drupal\content_moderation\ModerationInformationInterface $moderation_info */ Chris@18: $moderation_info = \Drupal::service('content_moderation.moderation_information'); Chris@18: /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */ Chris@18: $entity_type_manager = \Drupal::service('entity_type.manager'); Chris@18: Chris@18: \Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'entity_form_display', function (EntityFormDisplay $entity_form_display) use ($moderation_info, $entity_type_manager) { Chris@18: $associated_entity_type = $entity_type_manager->getDefinition($entity_form_display->getTargetEntityTypeId()); Chris@18: Chris@18: if ($moderation_info->isModeratedEntityType($associated_entity_type)) { Chris@18: $entity_form_display->calculateDependencies(); Chris@18: return TRUE; Chris@18: } Chris@18: elseif ($moderation_state_component = $entity_form_display->getComponent('moderation_state')) { Chris@18: // Remove the component from the entity form display, then manually delete Chris@18: // it from the hidden components list, completely purging it. Chris@18: $entity_form_display->removeComponent('moderation_state'); Chris@18: $hidden_components = $entity_form_display->get('hidden'); Chris@18: unset($hidden_components['moderation_state']); Chris@18: $entity_form_display->set('hidden', $hidden_components); Chris@18: $entity_form_display->calculateDependencies(); Chris@18: return TRUE; Chris@18: } Chris@18: Chris@18: return FALSE; Chris@18: }); Chris@18: }