annotate core/modules/content_moderation/content_moderation.post_update.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@14 1 <?php
Chris@14 2
Chris@14 3 /**
Chris@14 4 * @file
Chris@14 5 * Post update functions for the Content Moderation module.
Chris@14 6 */
Chris@14 7
Chris@18 8 use Drupal\Core\Config\Entity\ConfigEntityUpdater;
Chris@18 9 use Drupal\Core\Entity\Entity\EntityFormDisplay;
Chris@14 10 use Drupal\Core\Site\Settings;
Chris@18 11 use Drupal\views\Entity\View;
Chris@14 12 use Drupal\workflows\Entity\Workflow;
Chris@14 13
Chris@14 14 /**
Chris@14 15 * Synchronize moderation state default revisions with their host entities.
Chris@14 16 */
Chris@14 17 function content_moderation_post_update_update_cms_default_revisions(&$sandbox) {
Chris@14 18 // For every moderated entity, identify the default revision ID, track the
Chris@14 19 // corresponding "content_moderation_state" revision and save it as the new
Chris@14 20 // default revision, if needed.
Chris@14 21
Chris@14 22 // Initialize sandbox info.
Chris@14 23 $entity_type_id = &$sandbox['entity_type_id'];
Chris@14 24 if (!isset($entity_type_id)) {
Chris@14 25 $sandbox['bundles'] = [];
Chris@16 26 $sandbox['entity_type_ids'] = [];
Chris@14 27 /** @var \Drupal\workflows\WorkflowInterface $workflow */
Chris@14 28 foreach (Workflow::loadMultipleByType('content_moderation') as $workflow) {
Chris@14 29 /** @var \Drupal\content_moderation\Plugin\WorkflowType\ContentModeration $plugin */
Chris@14 30 $plugin = $workflow->getTypePlugin();
Chris@14 31 foreach ($plugin->getEntityTypes() as $entity_type_id) {
Chris@14 32 $sandbox['entity_type_ids'][$entity_type_id] = $entity_type_id;
Chris@14 33 foreach ($plugin->getBundlesForEntityType($entity_type_id) as $bundle) {
Chris@14 34 $sandbox['bundles'][$entity_type_id][$bundle] = $bundle;
Chris@14 35 }
Chris@14 36 }
Chris@14 37 }
Chris@14 38 $sandbox['offset'] = 0;
Chris@14 39 $sandbox['limit'] = Settings::get('entity_update_batch_size', 50);
Chris@14 40 $sandbox['total'] = count($sandbox['entity_type_ids']);
Chris@14 41 $entity_type_id = array_shift($sandbox['entity_type_ids']);
Chris@14 42 }
Chris@14 43
Chris@14 44 // If there are no moderated bundles or we processed all of them, we are done.
Chris@14 45 $entity_type_manager = \Drupal::entityTypeManager();
Chris@14 46 /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $content_moderation_state_storage */
Chris@14 47 $content_moderation_state_storage = $entity_type_manager->getStorage('content_moderation_state');
Chris@14 48 if (!$entity_type_id) {
Chris@14 49 $content_moderation_state_storage->resetCache();
Chris@14 50 $sandbox['#finished'] = 1;
Chris@14 51 return;
Chris@14 52 }
Chris@14 53
Chris@14 54 // Retrieve a batch of moderated entities to be processed.
Chris@14 55 $storage = $entity_type_manager->getStorage($entity_type_id);
Chris@14 56 $entity_type = $entity_type_manager->getDefinition($entity_type_id);
Chris@14 57 $query = $storage->getQuery()
Chris@14 58 ->accessCheck(FALSE)
Chris@14 59 ->sort($entity_type->getKey('id'))
Chris@14 60 ->range($sandbox['offset'], $sandbox['limit']);
Chris@14 61 $bundle_key = $entity_type->getKey('bundle');
Chris@14 62 if ($bundle_key && !empty($sandbox['bundles'][$entity_type_id])) {
Chris@14 63 $bundles = array_keys($sandbox['bundles'][$entity_type_id]);
Chris@14 64 $query->condition($bundle_key, $bundles, 'IN');
Chris@14 65 }
Chris@14 66 $entity_ids = $query->execute();
Chris@14 67
Chris@14 68 // Compute progress status and skip to the next entity type, if needed.
Chris@14 69 $sandbox['#finished'] = ($sandbox['total'] - count($sandbox['entity_type_ids']) - 1) / $sandbox['total'];
Chris@14 70 if (!$entity_ids) {
Chris@14 71 $sandbox['offset'] = 0;
Chris@14 72 $entity_type_id = array_shift($sandbox['entity_type_ids']) ?: FALSE;
Chris@14 73 return;
Chris@14 74 }
Chris@14 75
Chris@14 76 // Load the "content_moderation_state" revisions corresponding to the
Chris@14 77 // moderated entity default revisions.
Chris@14 78 $result = $content_moderation_state_storage->getQuery()
Chris@14 79 ->allRevisions()
Chris@14 80 ->condition('content_entity_type_id', $entity_type_id)
Chris@14 81 ->condition('content_entity_revision_id', array_keys($entity_ids), 'IN')
Chris@14 82 ->execute();
Chris@14 83 /** @var \Drupal\Core\Entity\ContentEntityInterface[] $revisions */
Chris@14 84 $revisions = $content_moderation_state_storage->loadMultipleRevisions(array_keys($result));
Chris@14 85
Chris@14 86 // Update "content_moderation_state" data.
Chris@14 87 foreach ($revisions as $revision) {
Chris@14 88 if (!$revision->isDefaultRevision()) {
Chris@14 89 $revision->setNewRevision(FALSE);
Chris@14 90 $revision->isDefaultRevision(TRUE);
Chris@14 91 $content_moderation_state_storage->save($revision);
Chris@14 92 }
Chris@14 93 }
Chris@14 94
Chris@14 95 // Clear static cache to avoid memory issues.
Chris@14 96 $storage->resetCache($entity_ids);
Chris@14 97
Chris@14 98 $sandbox['offset'] += $sandbox['limit'];
Chris@14 99 }
Chris@18 100
Chris@18 101 /**
Chris@18 102 * Set the default moderation state for new content to 'draft'.
Chris@18 103 */
Chris@18 104 function content_moderation_post_update_set_default_moderation_state(&$sandbox) {
Chris@18 105 \Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'workflow', function (Workflow $workflow) {
Chris@18 106 if ($workflow->get('type') === 'content_moderation') {
Chris@18 107 $configuration = $workflow->getTypePlugin()->getConfiguration();
Chris@18 108 $configuration['default_moderation_state'] = 'draft';
Chris@18 109 $workflow->getTypePlugin()->setConfiguration($configuration);
Chris@18 110 return TRUE;
Chris@18 111 }
Chris@18 112 return FALSE;
Chris@18 113 });
Chris@18 114 }
Chris@18 115
Chris@18 116 /**
Chris@18 117 * Set the filter on the moderation view to be the latest translation affected.
Chris@18 118 */
Chris@18 119 function content_moderation_post_update_set_views_filter_latest_translation_affected_revision(&$sandbox) {
Chris@18 120 $original_plugin_name = 'latest_revision';
Chris@18 121 $new_plugin_name = 'latest_translation_affected_revision';
Chris@18 122
Chris@18 123 // Check that views is installed and the moderated content view exists.
Chris@18 124 if (\Drupal::moduleHandler()->moduleExists('views') && $view = View::load('moderated_content')) {
Chris@18 125 $display = &$view->getDisplay('default');
Chris@18 126 if (!isset($display['display_options']['filters'][$original_plugin_name])) {
Chris@18 127 return;
Chris@18 128 }
Chris@18 129
Chris@18 130 $translation_affected_filter = [
Chris@18 131 'id' => $new_plugin_name,
Chris@18 132 'field' => $new_plugin_name,
Chris@18 133 'plugin_id' => $new_plugin_name,
Chris@18 134 ] + $display['display_options']['filters'][$original_plugin_name];
Chris@18 135
Chris@18 136 $display['display_options']['filters'] = [$new_plugin_name => $translation_affected_filter] + $display['display_options']['filters'];
Chris@18 137 unset($display['display_options']['filters'][$original_plugin_name]);
Chris@18 138
Chris@18 139 $view->save();
Chris@18 140 }
Chris@18 141 }
Chris@18 142
Chris@18 143 /**
Chris@18 144 * Update the dependencies of entity displays to include associated workflow.
Chris@18 145 */
Chris@18 146 function content_moderation_post_update_entity_display_dependencies(&$sandbox) {
Chris@18 147 /** @var \Drupal\content_moderation\ModerationInformationInterface $moderation_info */
Chris@18 148 $moderation_info = \Drupal::service('content_moderation.moderation_information');
Chris@18 149 /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */
Chris@18 150 $entity_type_manager = \Drupal::service('entity_type.manager');
Chris@18 151
Chris@18 152 \Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'entity_form_display', function (EntityFormDisplay $entity_form_display) use ($moderation_info, $entity_type_manager) {
Chris@18 153 $associated_entity_type = $entity_type_manager->getDefinition($entity_form_display->getTargetEntityTypeId());
Chris@18 154
Chris@18 155 if ($moderation_info->isModeratedEntityType($associated_entity_type)) {
Chris@18 156 $entity_form_display->calculateDependencies();
Chris@18 157 return TRUE;
Chris@18 158 }
Chris@18 159 elseif ($moderation_state_component = $entity_form_display->getComponent('moderation_state')) {
Chris@18 160 // Remove the component from the entity form display, then manually delete
Chris@18 161 // it from the hidden components list, completely purging it.
Chris@18 162 $entity_form_display->removeComponent('moderation_state');
Chris@18 163 $hidden_components = $entity_form_display->get('hidden');
Chris@18 164 unset($hidden_components['moderation_state']);
Chris@18 165 $entity_form_display->set('hidden', $hidden_components);
Chris@18 166 $entity_form_display->calculateDependencies();
Chris@18 167 return TRUE;
Chris@18 168 }
Chris@18 169
Chris@18 170 return FALSE;
Chris@18 171 });
Chris@18 172 }