From c17824b99ae103cd5ca22c04e393fdfdb2c74560 Mon Sep 17 00:00:00 2001
From: Marc Egger <marc.egger@uzh.ch>
Date: Mon, 12 Oct 2020 13:38:43 +0200
Subject: [PATCH] FormAsFile.php: keep old form during import and delete only
 at the end

---
 extension/Classes/Core/Form/FormAsFile.php | 25 +++++++++++++---------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/extension/Classes/Core/Form/FormAsFile.php b/extension/Classes/Core/Form/FormAsFile.php
index ecdfa4fe9..31a2f728e 100644
--- a/extension/Classes/Core/Form/FormAsFile.php
+++ b/extension/Classes/Core/Form/FormAsFile.php
@@ -85,10 +85,9 @@ class FormAsFile
             }
         }
 
-        // Delete old form with that name from DB if it exists.
-        if (array_key_exists(F_ID, $formFromDb)) {
-            self::deleteFormDBWithId($formFromDb[F_ID], $database);
-        }
+        // keep old form ID for deletion later & define temporary name for new form
+        $formIdOld = $formFromDb[F_ID] ?? null;
+        $newFormTempName = $formName . '_FAILED_IMPORT'; // will be renamed at the end
 
         // Insert new Form to DB (after filtering allowed columns and adding column 'name')
         $formSchema = $database->getTableDefinition(TABLE_NAME_FORM);
@@ -96,17 +95,18 @@ class FormAsFile
         $insertValues = array_filter($formFromFile, function ($columnName) use ($formColumns) {
             return $columnName !== F_ID && in_array($columnName, $formColumns);
         }, ARRAY_FILTER_USE_KEY); // array(column => value)
-        $insertValues[F_NAME] = $formName;
+        $insertValues[F_NAME] = $newFormTempName;
+        $insertValues[F_FILE_STATS] = $fileStatsNew;
         list($sqlFormInsert, $parameterArrayFormInsert) = SqlQuery::insertRecord(TABLE_NAME_FORM, $insertValues);
-        $formId = $database->sql($sqlFormInsert, ROW_REGULAR, $parameterArrayFormInsert);
+        $formIdNew = $database->sql($sqlFormInsert, ROW_REGULAR, $parameterArrayFormInsert);
 
         // Delete stale formElements with the new form id (these should not exist, but better make sure)
-        self::deleteFormElementsDBWithFormId($formId, $database);
+        self::deleteFormElementsDBWithFormId($formIdNew, $database);
 
         // Insert FormElements to DB and collect container ids
         $containerIds = []; // array(container_name => id)
         foreach ($formFromFile[F_FILE_FORM_ELEMENT] as &$formElementFromFile) {
-            $feId = self::insertFormElement($formElementFromFile, $formId, $database);
+            $feId = self::insertFormElement($formElementFromFile, $formIdNew, $database);
             $formElementFromFile[FE_ID] = $feId;
             if ($formElementFromFile[FE_CLASS] === FE_CLASS_CONTAINER) {
                 $containerIds[$formElementFromFile[FE_NAME]] =  $feId;
@@ -127,8 +127,13 @@ class FormAsFile
             }
         }
 
-        // Update column fileStats if everything went well
-        list($sql, $parameterArray) = SqlQuery::updateRecord(TABLE_NAME_FORM, [F_FILE_STATS => $fileStatsNew], $formId);
+        // Delete old form if everything went well
+        if ($formIdOld !== null) {
+            self::deleteFormDBWithId($formIdOld, $database);
+        }
+
+        // Replace temporary name of new form
+        list($sql, $parameterArray) = SqlQuery::updateRecord(TABLE_NAME_FORM, [F_NAME => $formName], $formIdNew);
         $database->sql($sql, ROW_REGULAR, $parameterArray);
 
         return true;
-- 
GitLab