Commit ad5e0dfa authored by Marc Egger's avatar Marc Egger
Browse files

form as file: dont delete DB form if it was never exported

parent fa29573c
Pipeline #4051 passed with stages
in 3 minutes and 55 seconds
......@@ -18,6 +18,7 @@ class FormAsFile
/**
* Remove the form from the DB and insert it using the form file. (only if the form file was changed)
* If the form file can't be read, then the form is deleted from the DB and an exception is thrown.
* If the form exists only in the DB and was never exported, then it is exported.
*
* - Form file location: SYSTEM_FORM_FILE_PATH
* - Recognize form file change: Compare the current file stats with the ones saved in the Form table.
......@@ -33,7 +34,15 @@ class FormAsFile
*/
public static function importForm(string $formName, Database $database): bool
{
// Get file stats both from file system and DB and exit if they are equal
// Export form from DB if it was never exported before
list($sql, $parameterArray) = SqlQuery::selectFormByName($formName, [F_ID, F_FILE_STATS]);
$formFromDb = $database->sql($sql, ROW_EXPECT_0_1,
$parameterArray, "Multiple forms with the same name: '$formName'");
if (!isset($formFromDb[F_FILE_STATS]) || !self::isValidFileStats($formFromDb[F_FILE_STATS])) {
self::exportForm($formName, $database);
}
// Get file stats from file system and exit if they are equal
$cwdToFormFile = self::formPathFileName($formName, $database);
$fileReadException = new \UserFormException(json_encode([
ERROR_MESSAGE_TO_USER => "Form file not found or missing permission: " . baseName($cwdToFormFile),
......@@ -48,9 +57,6 @@ class FormAsFile
self::deleteFormDB($formName, $database, "Failed to read form file stats.");
throw $fileReadException;
}
list($sql, $parameterArray) = SqlQuery::selectFormByName($formName, [F_ID, F_FILE_STATS]);
$formFromDb = $database->sql($sql, ROW_EXPECT_0_1,
$parameterArray, "Multiple forms with the same name: '$formName'");
if (array_key_exists(F_FILE_STATS, $formFromDb) && $fileStatsNew === $formFromDb[F_FILE_STATS]) {
return false;
}
......@@ -362,7 +368,7 @@ class FormAsFile
*
* @param Database $database
* @param bool $enforceWritable Throw exception if one of the form files is not writable by current user.
* @param bool $deleteFromDB Delete forms from DB if there are no corresponding form files.
* @param bool $deleteFromDB Delete forms from DB if there are no corresponding form files. Except if the form was never exported.
* @throws \CodeException
* @throws \DbException
* @throws \UserFormException
......@@ -378,12 +384,12 @@ class FormAsFile
}
}
// Delete all forms which are in DB but not in files
// Delete all forms which are in DB but not in files. Except if they were never exported.
if ($deleteFromDB) {
$formNamesDB = self::queryAllFormNames($database);
$formsToDelete = array_diff($formNamesDB, $formFileNames);
foreach ($formsToDelete as $formToDelete) {
self::deleteFormDB($formToDelete, $database, "No corresponding form file found.");
self::deleteFormDB($formToDelete, $database, "No corresponding form file found.", true);
}
}
}
......@@ -443,26 +449,43 @@ class FormAsFile
}
/**
* Delete form with given name and its form elements from DB
* Delete form with given name and its form elements from DB.
* If $keepIfNeverExported is set to true then the form is kept (i.e. exported) instead of deleted if the form was never exported yet.
*
* @param string $formName
* @param Database $database
* @param string $logMessageReason
* @param bool $keepIfNeverExported
* @return void
* @throws \CodeException
* @throws \DbException
* @throws \UserFormException
*/
private static function deleteFormDB(string $formName, Database $database, string $logMessageReason = '') // : void
private static function deleteFormDB(string $formName, Database $database, string $logMessageReason = '', bool $keepIfNeverExported = false) // : void
{
list($sql, $parameterArray) = SqlQuery::selectFormByName($formName, [F_ID]);
list($sql, $parameterArray) = SqlQuery::selectFormByName($formName, [F_ID, F_FILE_STATS]);
$formFromDb = $database->sql($sql, ROW_EXPECT_0_1,
$parameterArray, "Multiple forms with the same name: '$formName'");
if (array_key_exists(F_ID, $formFromDb)) {
if ($keepIfNeverExported && (isset($formFromDb[F_ID]) && !isset($formFromDb[F_FILE_STATS])) || (isset($formFromDb[F_FILE_STATS]) && !self::isValidFileStats($formFromDb[F_FILE_STATS]))) {
// export form instead of deleting since it was never exported before
self::exportForm($formName, $database);
} else if (array_key_exists(F_ID, $formFromDb)) {
self::deleteFormDBWithId($formFromDb[F_ID], $database, $logMessageReason . " Form name '$formName'.");
}
}
/**
* Return true if the given string is a valid JSON encoded file stats string.
* Currently only checks if first char is '{'
*
* @param string $fileStats
* @return bool
*/
private static function isValidFileStats(string $fileStats) {
return substr($fileStats, 0, 1 ) === '{';
}
/**
* Delete form with given id and its form elements from DB
*
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment