diff --git a/core/modules/content_moderation/src/EntityOperations.php b/core/modules/content_moderation/src/EntityOperations.php index 3f66100581..428ce8971d 100644 --- a/core/modules/content_moderation/src/EntityOperations.php +++ b/core/modules/content_moderation/src/EntityOperations.php @@ -3,6 +3,7 @@ namespace Drupal\content_moderation; use Drupal\content_moderation\Entity\ContentModerationState as ContentModerationStateEntity; +use Drupal\Core\Database\Connection; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Entity\EntityInterface; @@ -55,6 +56,13 @@ class EntityOperations implements ContainerInjectionInterface { protected $bundleInfo; /** + * The database connection. + * + * @var \Drupal\Core\Database\Connection + */ + protected $database; + + /** * Constructs a new EntityOperations object. * * @param \Drupal\content_moderation\ModerationInformationInterface $moderation_info @@ -67,13 +75,16 @@ class EntityOperations implements ContainerInjectionInterface { * The revision tracker. * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info * The entity bundle information service. + * @param \Drupal\Core\Database\Connection $database + * The database connection. */ - public function __construct(ModerationInformationInterface $moderation_info, EntityTypeManagerInterface $entity_type_manager, FormBuilderInterface $form_builder, RevisionTrackerInterface $tracker, EntityTypeBundleInfoInterface $bundle_info) { + public function __construct(ModerationInformationInterface $moderation_info, EntityTypeManagerInterface $entity_type_manager, FormBuilderInterface $form_builder, RevisionTrackerInterface $tracker, EntityTypeBundleInfoInterface $bundle_info, Connection $database) { $this->moderationInfo = $moderation_info; $this->entityTypeManager = $entity_type_manager; $this->formBuilder = $form_builder; $this->tracker = $tracker; $this->bundleInfo = $bundle_info; + $this->database = $database; } /** @@ -85,7 +96,8 @@ public static function create(ContainerInterface $container) { $container->get('entity_type.manager'), $container->get('form_builder'), $container->get('content_moderation.revision_tracker'), - $container->get('entity_type.bundle.info') + $container->get('entity_type.bundle.info'), + $container->get('database') ); } @@ -145,6 +157,25 @@ public function entityUpdate(EntityInterface $entity) { $this->updateOrCreateFromEntity($entity); $this->setLatestRevision($entity); } + + if ($entity->getEntityTypeId() == 'workflow') { + $deleted_states = array_diff_key($entity->original->getStates(), $entity->getStates()); + /** @var \Drupal\content_moderation\ContentModerationState $deleted_state */ + foreach ($deleted_states as $deleted_state) { + $new_state = $deleted_state->isPublishedState() ? 'published' : 'draft'; + $content_moderation_state_type = $this->entityTypeManager->getDefinition('content_moderation_state'); + $this->database + ->update($content_moderation_state_type->getDataTable()) + ->condition('moderation_state', $deleted_state->id()) + ->fields(['moderation_state' => $new_state]) + ->execute(); + $this->database + ->update($content_moderation_state_type->getRevisionDataTable()) + ->condition('moderation_state', $deleted_state->id()) + ->fields(['moderation_state' => $new_state]) + ->execute(); + } + } } /** diff --git a/core/modules/content_moderation/src/Plugin/WorkflowType/ContentModeration.php b/core/modules/content_moderation/src/Plugin/WorkflowType/ContentModeration.php index b80ccdda87..939b453df7 100644 --- a/core/modules/content_moderation/src/Plugin/WorkflowType/ContentModeration.php +++ b/core/modules/content_moderation/src/Plugin/WorkflowType/ContentModeration.php @@ -5,6 +5,7 @@ use Drupal\Component\Serialization\Json; use Drupal\content_moderation\ModerationInformationInterface; use Drupal\Core\Access\AccessResult; +use Drupal\Core\Database\Connection; use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\EntityPublishedInterface; diff --git a/core/modules/content_moderation/tests/src/Kernel/DeleteWorkflowStateTest.php b/core/modules/content_moderation/tests/src/Kernel/DeleteWorkflowStateTest.php new file mode 100644 index 0000000000..266c157708 --- /dev/null +++ b/core/modules/content_moderation/tests/src/Kernel/DeleteWorkflowStateTest.php @@ -0,0 +1,113 @@ +installSchema('node', 'node_access'); + $this->installEntitySchema('node'); + $this->installEntitySchema('user'); + $this->installEntitySchema('content_moderation_state'); + $this->installConfig('content_moderation'); + + $this->entityTypeManager = $this->container->get('entity_type.manager'); + } + + /** + * Test deleting a node's moderation state. + */ + function testNodeModeration() { + $node_type = NodeType::create([ + 'type' => 'example', + ]); + $node_type->save(); + + $workflow = Workflow::load('editorial'); + $workflow->addState('test', 'Test'); + $workflow->addState('unpub_test', 'Unpublished Test'); + $workflow->getTypePlugin()->setConfiguration([ + 'states' => [ + 'test' => [ + 'published' => TRUE, + 'default_revision' => TRUE, + ], + 'unpub_test' => [ + 'published' => FALSE, + 'default_revision' => FALSE, + ], + ], + ]); + $workflow->addTransition('test', 'Test', ['draft'], 'test'); + $workflow->addTransition('unpub_test', 'Unpublished Test', ['draft'], 'unpub_test'); + $workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example'); + $workflow->save(); + + // Tests deleting a published moderation state. + $node = Node::create([ + 'type' => 'example', + 'title' => 'Test title', + ]); + $node->moderation_state->value = 'test'; + $node->save(); + $this->assertEquals('test', $node->moderation_state->value); + $this->assertTrue($node->isPublished()); + + $workflow->deleteState('test'); + $workflow->save(); + + $loaded_node = Node::load($node->id()); + $this->assertEquals('published', $loaded_node->moderation_state->value); + $this->assertTrue($loaded_node->isPublished()); + + // Tests deleting an unpublished moderation state. + $node2 = Node::create([ + 'type' => 'example', + 'title' => 'Test title 2', + ]); + $node2->moderation_state->value = 'unpub_test'; + $node2->save(); + $this->assertEquals('unpub_test', $node2->moderation_state->value); + $this->assertFalse($node2->isPublished()); + + $workflow->deleteState('unpub_test'); + $workflow->save(); + + $loaded_node2 = Node::load($node2->id()); + $this->assertEquals('draft', $loaded_node2->moderation_state->value); + $this->assertFalse($loaded_node2->isPublished()); + } + +}