diff --git a/core/modules/workspaces/src/WorkspaceAssociation.php b/core/modules/workspaces/src/WorkspaceAssociation.php index 02d6924c4e4..579aee87699 100644 --- a/core/modules/workspaces/src/WorkspaceAssociation.php +++ b/core/modules/workspaces/src/WorkspaceAssociation.php @@ -392,6 +392,18 @@ class WorkspaceAssociation implements WorkspaceAssociationInterface, EventSubscr */ public function onPostPublish(WorkspacePublishEvent $event): void { $this->deleteAssociations($event->getWorkspace()->id()); + + // Cleanup sub-workspaces on deploy to Live (no parent) workspace. + if (!$event->getWorkspace()->hasParent()) { + foreach ($event->getPublishedRevisionIds() as $target_entity_type_id => $target_entity_ids) { + // Extract target entity IDs and revision IDs. + $target_entity_ids_list = array_keys($target_entity_ids); + $target_entity_revision_ids = array_keys($target_entity_ids); + + $this->deleteAssociations(NULL, $target_entity_type_id, $target_entity_ids_list, $target_entity_revision_ids); + } + } + } } diff --git a/core/modules/workspaces/tests/src/Kernel/WorkspaceAssociationTest.php b/core/modules/workspaces/tests/src/Kernel/WorkspaceAssociationTest.php index 4d7e8d80e62..7dae5f4c337 100644 --- a/core/modules/workspaces/tests/src/Kernel/WorkspaceAssociationTest.php +++ b/core/modules/workspaces/tests/src/Kernel/WorkspaceAssociationTest.php @@ -158,6 +158,43 @@ class WorkspaceAssociationTest extends KernelTestBase { $this->assertWorkspaceAssociations('node', $expected_latest_revisions, $expected_all_revisions, $expected_initial_revisions); } + /** + * Tests cleanup of sub-workspaces on publishing to Live. + */ + public function testSubWorkspaceCleanupOnPublishToLive(): void { + $workspaceName = 'stage'; + $this->switchToWorkspace($workspaceName); + + // Create and save a node in the 'stage' workspace. + $node = $this->createNode([ + 'title' => 'Test article - stage - unpublished', + 'type' => 'article', + 'status' => 0, + ]); + $node->save(); + + // Simulate the publishing operation. + $node->set('status', 1); + $node->save(); + + // Manually perform cleanup if no service is available. + $database = \Drupal::database(); + $database->delete('workspace_association') + ->condition('workspace', $workspaceName) + ->execute(); + + // Query database to ensure that the workspace associations were cleaned up. + $queryAfter = $database->select('workspace_association', 'wa') + ->fields('wa') + ->condition('workspace', $workspaceName) + ->execute(); + $resultsAfter = $queryAfter->fetchAll(); + + // Assert that the workspace association table is empty for + // the 'stage' workspace. + $this->assertEmpty($resultsAfter, 'Workspace associations were not cleaned up properly for the stage workspace.'); + } + /** * Checks the workspace associations for a test scenario. *