From 83e1aa9da3e73bb7317e1b64cf266172f8344b37 Mon Sep 17 00:00:00 2001
From: catch <6915-catch@users.noreply.drupalcode.org>
Date: Thu, 10 Oct 2024 11:28:16 +0100
Subject: [PATCH] Issue #3469792 by amateescu, antonnavi, smustgrave, djdevin,
 quietone: Workspaces with thousands of items can't be published

---
 core/modules/workspaces/src/WorkspaceMerger.php   | 13 +++++++++++++
 .../modules/workspaces/src/WorkspacePublisher.php | 15 +++++++++++++--
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/core/modules/workspaces/src/WorkspaceMerger.php b/core/modules/workspaces/src/WorkspaceMerger.php
index 0cf34c3e26d3..56a198ee0d89 100644
--- a/core/modules/workspaces/src/WorkspaceMerger.php
+++ b/core/modules/workspaces/src/WorkspaceMerger.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Site\Settings;
 use Drupal\Core\Utility\Error;
 use Psr\Log\LoggerInterface;
 
@@ -31,6 +32,10 @@ public function merge() {
 
     try {
       $transaction = $this->database->startTransaction();
+      $max_execution_time = ini_get('max_execution_time');
+      $step_size = Settings::get('entity_update_batch_size', 50);
+      $counter = 0;
+
       foreach ($this->getDifferringRevisionIdsOnSource() as $entity_type_id => $revision_difference) {
         $entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
         $revisions_on_source = $this->entityTypeManager->getStorage($entity_type_id)
@@ -48,6 +53,14 @@ public function merge() {
           $revision->{$field_name}->target_id = $this->targetWorkspace->id();
           $revision->setSyncing(TRUE);
           $revision->save();
+          $counter++;
+
+          // Extend the execution time in order to allow processing workspaces
+          // that contain a large number of items.
+          if ((int) ($counter / $step_size) >= 1) {
+            set_time_limit($max_execution_time);
+            $counter = 0;
+          }
         }
       }
     }
diff --git a/core/modules/workspaces/src/WorkspacePublisher.php b/core/modules/workspaces/src/WorkspacePublisher.php
index 1c568b46b41b..f86102472693 100644
--- a/core/modules/workspaces/src/WorkspacePublisher.php
+++ b/core/modules/workspaces/src/WorkspacePublisher.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Site\Settings;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Core\Utility\Error;
 use Drupal\workspaces\Event\WorkspacePostPublishEvent;
@@ -45,9 +46,11 @@ public function publish() {
 
     try {
       $transaction = $this->database->startTransaction();
-      // @todo Handle the publishing of a workspace with a batch operation in
-      //   https://www.drupal.org/node/2958752.
       $this->workspaceManager->executeOutsideWorkspace(function () use ($tracked_entities) {
+        $max_execution_time = ini_get('max_execution_time');
+        $step_size = Settings::get('entity_update_batch_size', 50);
+        $counter = 0;
+
         foreach ($tracked_entities as $entity_type_id => $revision_difference) {
           $entity_revisions = $this->entityTypeManager->getStorage($entity_type_id)
             ->loadMultipleRevisions(array_keys($revision_difference));
@@ -68,6 +71,14 @@ public function publish() {
 
             $entity->original = $default_revisions[$entity->id()];
             $entity->save();
+            $counter++;
+
+            // Extend the execution time in order to allow processing workspaces
+            // that contain a large number of items.
+            if ((int) ($counter / $step_size) >= 1) {
+              set_time_limit($max_execution_time);
+              $counter = 0;
+            }
           }
         }
       });
-- 
GitLab