diff --git a/extension/Classes/Core/Form/FormAsFile.php b/extension/Classes/Core/Form/FormAsFile.php index c0a1c87839ccf989acb00e5d3dabef5c42bcb388..b75d3bc57ab0e50bd795b652de431994f1dc74fd 100644 --- a/extension/Classes/Core/Form/FormAsFile.php +++ b/extension/Classes/Core/Form/FormAsFile.php @@ -129,17 +129,23 @@ class FormAsFile */ public static function exportForm(string $formName, Database $database, ?int $formId = null) // : void { - list($formName, $formId, $formJson) = self::formToJson($formName, $database, $formId); + list($formName, $formId, $formJson, $adjustContainerName) = self::formToJson($formName, $database, $formId); // backup and write file $pathFileName = self::formPathFileName($formName, $database); self::backupFormFile($pathFileName); HelperFile::file_put_contents($pathFileName, $formJson); - // Update column fileStats - $fileStats = self::formFileStatsJson($pathFileName); - list($sql, $parameterArray) = SqlQuery::updateRecord(TABLE_NAME_FORM, [F_FILE_STATS => $fileStats], $formId); - $database->sql($sql, ROW_REGULAR, $parameterArray); + // some column names where adjusted => import form + if ($adjustContainerName) { + self::importForm($formName, $database); + + // otherwise => Update column fileStats + } else { + $fileStats = self::formFileStatsJson($pathFileName); + list($sql, $parameterArray) = SqlQuery::updateRecord(TABLE_NAME_FORM, [F_FILE_STATS => $fileStats], $formId); + $database->sql($sql, ROW_REGULAR, $parameterArray); + } } /** @@ -595,13 +601,14 @@ class FormAsFile * Return json string of the given form with form-elements. If $formId is given, $formName is ignored. * * - Container FormElements: The form file uses names instead if ids to reference containers. These references are translated before saving the file. + * - Adjust container names: If a container name is empty or not unique it is adjusted. In that case the fourth return parameter is set to true. * - Ignored columns: The columns 'id', 'name' (only Form table), 'fileStats', 'formId', 'feIdContainer' are not added to the json output. * - FormElement order: The formElements are ordered by the 'ord' column before writing them to the file. * * @param string $formName * @param Database $database * @param int|null $formId If given, $formName is ignored - * @return array + * @return array [$formName, $formId, $formJson, $adjustedContainerNames > 0] * @throws \CodeException * @throws \DbException * @throws \UserFormException @@ -632,21 +639,27 @@ class FormAsFile $formElements = $database->sql($sql, ROW_REGULAR, $parameterArray); // array(array(column name => value)) // Translate container references (id to name) and remove all id columns - $containerNames = array_reduce($formElements, function ($result, $formElement) use ($formName, $formId) { + $adjustedContainerNames = 0; + $containerNames = array_reduce($formElements, function ($result, $formElement) use ($formName, $formId, &$adjustedContainerNames) { if ($formElement[FE_CLASS] === FE_CLASS_CONTAINER) { $containerName = $formElement[FE_NAME]; if (in_array($containerName, $result)) { - Thrower::userFormException("Failed exporting Form '$formName' to file." - , "Container Form Elements must have a unique and nonempty name. Container name: '$containerName'. Container id: " . $formElement[FE_ID]); + $containerName = $containerName . '_auto_adjust_not_unique_' . count($result); + $adjustedContainerNames++; } if ($containerName === '') { - Thrower::userFormException("Failed exporting Form '$formName' to file.", "Container form-elements may not have an empty name. Container id: " . $formElement[FE_ID]); + $containerName = 'auto_adjust_empty_' . count($result); + $adjustedContainerNames++; } $result[$formElement[FE_ID]] = $containerName; } return $result; }, []); // array(id => name) $formElements = array_map(function ($formElement) use ($containerNames) { + if (array_key_exists($formElement[FE_ID], $containerNames)) { + // in case container name was auto adjusted above we set new name + $formElement[FE_NAME] = $containerNames[$formElement[FE_ID]]; + } $containerId = $formElement[FE_ID_CONTAINER]; if ($containerId !== 0) { $formElement[FE_FILE_CONTAINER_NAME] = $containerNames[$containerId]; @@ -660,7 +673,7 @@ class FormAsFile // add form elements and create json $form[F_FILE_FORM_ELEMENT] = $formElements; $formJson = json_encode($form, JSON_PRETTY_PRINT); - return array($formName, $formId, $formJson); + return array($formName, $formId, $formJson, $adjustedContainerNames > 0); } /** diff --git a/extension/Classes/Sql/formEditor.sql b/extension/Classes/Sql/formEditor.sql index 923b174e44e070e29f619d5b327ebcf118659f81..c6d99d92d4891d0267ea45948526adde0bae7e07 100644 --- a/extension/Classes/Sql/formEditor.sql +++ b/extension/Classes/Sql/formEditor.sql @@ -477,17 +477,22 @@ VALUES (2, 'feIdContainer', 'Container', 'show', 'select', 'all', 'native', 120, '', 'no', '', '', '', '', '', 'none'); -INSERT INTO `FormElement` (`id`, `formId`, `feIdContainer`, `dynamicUpdate`, `enabled`, `name`, `label`, `mode`, +INSERT INTO `FormElement` (`formId`, `feIdContainer`, `dynamicUpdate`, `enabled`, `name`, `label`, `mode`, `modeSql`, `class`, `type`, `subrecordOption`, `encode`, `checkType`, `checkPattern`, `onChange`, `ord`, `tabindex`, `size`, `maxLength`, `bsLabelColumns`, `bsInputColumns`, `bsNoteColumns`, `rowLabelInputNote`, `note`, `adminNote`, `tooltip`, `placeholder`, `value`, `sql1`, `parameter`, `parameterLanguageA`, `parameterLanguageB`, `parameterLanguageC`, `parameterLanguageD`, `clientJs`, `feGroup`, `deleted`) -VALUES (NULL, '2', '0', 'no', 'yes', 'Check Name Conflict', '', 'show', '', 'action', 'beforeSave', '', 'specialchar', +VALUES (2, '0', 'no', 'yes', 'Check Name Conflict', '', 'show', '', 'action', 'beforeSave', '', 'specialchar', 'auto', '', '', '650', '0', '', '', '', '', '', 'row,label,/label,input,/input,note,/note,/row', '', '', '', '', '', '', 'sqlValidate={{!SELECT fe.id FROM FormElement AS fe WHERE "{{class:F:alnumx}}"=fe.class AND fe.formId={{formId:RF}} AND fe.name!="" AND fe.name="{{name:F:alnumx}}" AND fe.id!={{id:R0}} }}\r\n\r\nexpectRecords=0\r\n\r\nmessageFail=There is already another {{class:F:alnumx}} form element with name "{{name:F:alnumx}}".', + '', '', '', '', '', '', 'no'), + (2, 0, 'no', 'yes', 'Check Name Empty Container', '', 'show', '', 'action', 'beforeSave', '', 'specialchar', + 'auto', '', '', 660, 0, '', '', '', '', '', 'row,label,/label,input,/input,note,/note,/row', '', '', '', + '', '', '', + 'sqlValidate ={{!SELECT \'1\' FROM (SELECT \'\') AS _fake WHERE \"{{class:F:alnumx}}\"=\"container\" AND \"{{name:F:alnumx}}\"=\"\"}}\r\n\r\nexpectRecords=0\r\n\r\nmessageFail=Form elements of class container must have a unique non-empty name.', '', '', '', '', '', '', 'no'); # ----------------------------------------