Commit 2598a1ba authored by Carsten  Rose's avatar Carsten Rose
Browse files

#3903 / Copy/Paste form: references inside a record are not updated at all

New option 'translateIdColumn=feIdContainer' implemented to translate table self referencing ids.
FormAction.php: collect translateMap during copying slave records. New function translateId().
formEditor.sql: Update to latest copyForm Version.
parent a622bbde
......@@ -31,8 +31,8 @@ Neue Versionsnummer
4) Neuen Tag vergeben:
git tag v0.18.3
git push -u origin v0.18.3
git tag v0.18.3a
git push -u origin v0.18.3a
5) Per PhpStorm Sync aller Files auf VM qfq.
......
......@@ -832,6 +832,7 @@ const FE_CHECKBOX_CHECKED = 'checked';
const FE_CHECKBOX_UNCHECKED = 'unchecked';
const FE_RECORD_DESTINATION_TABLE = 'recordDestinationTable';
const FE_RECORD_SOURCE_TABLE = 'recordSourceTable';
const FE_TRANSLATE_ID_COLUMN = 'translateIdColumn';
const FE_FLAG_ROW_OPEN_TAG = '_flagRowOpenTag'; // will be automatically computed during Formload: true | false
const FE_FLAG_ROW_CLOSE_TAG = '_flagRowCloseTag'; // will be automatically computed during Formload: true | false
......
......@@ -418,7 +418,7 @@ class FormAction {
$newValues = $this->evaluate->parse($formElement[FE_SQL1]);
# Dupliziere den Record. RC ist die ID des neu erzeugten Records.
$lastInsertId = $this->prepareDuplicate($feSpecAction, $newValues, $recordSourceTable, $recordDestinationTable, $sub, $clipboard, $formElement[FE_NAME]);
$lastInsertId = $this->prepareDuplicate($feSpecAction, $formElement, $newValues, $recordSourceTable, $recordDestinationTable, $sub, $clipboard);
# Lege die Record ID im Array ab, damit spaetere 'paste' Records diese entsprechend einsetzen koennen.
# Nur falls ein Name angegeben ist und dieser !='id' ist.
......@@ -432,7 +432,7 @@ class FormAction {
/**
*
*
* @param array $feSpecAction - all FE.class='action' - just process 'paste'
* @param array $feSpecActionAll - all FE.class='action' - just process 'paste'
* @param array $updateRecords - array of records: 'id' is the source.id, all other fields will replace source columns.
* @param $recordSourceTable - table name from where to copy the source records
* @param $recordDestinationTable - table name where the records will be duplicated to.
......@@ -444,7 +444,9 @@ class FormAction {
* @throws DbException
* @throws UserFormException
*/
private function prepareDuplicate(array $feSpecAction, array $updateRecords, $recordSourceTable, $recordDestinationTable, $sub, array $clipboard, $field) {
private function prepareDuplicate(array $feSpecActionAll, array $feSpecAction, array $updateRecords, $recordSourceTable, $recordDestinationTable, $sub, array $clipboard) {
$translateMap = array();
$field = $feSpecAction[FE_NAME];
// Sometimes there is no query at all.
if (count($updateRecords) == 0) {
......@@ -468,20 +470,54 @@ class FormAction {
$lastInsertId = $this->copyRecord($rowSrc, $recordDestinationTable);
$clipboard[$field] = $lastInsertId;
$translateMap[$newColumns[COLUMN_ID]] = $lastInsertId;
// Set the clipboard as the primary record as long as secondaries are created.
$this->store->setStore($clipboard, STORE_PARENT_RECORD, true);
# Do subqueries
if ($sub == "") {
$this->doAllFormElementPaste($feSpecAction, $recordSourceTable, $recordDestinationTable, $field, $clipboard);
$this->doAllFormElementPaste($feSpecActionAll, $recordSourceTable, $recordDestinationTable, $field, $clipboard);
}
}
// If necessary: correct table self referencing id columns
if (!empty($feSpecAction[FE_TRANSLATE_ID_COLUMN])) {
$this->translateId($translateMap, $feSpecAction[FE_TRANSLATE_ID_COLUMN], $recordDestinationTable);
}
return $lastInsertId;
} // prepareDuplicate()
/**
* Translate table self referencing columns to the new values.
* Rerun on all new records. Search and translate old id's (copied) to the new generated id's.
*
* Example with FormElement: id, feIdContainer, type
*
* Original: [1,2,'input'], [2,3,'templateGroup'], [3,0, 'pill']
* Duplicated: [4,2,'input'], [5,3,'templateGroup'], [6,0, 'pill']
* TranslateId: [4,5,'input'], [5,6,'templateGroup'], [6,0, 'pill']
*
* @param array $translateMap array with old id's as keys, and new id's as their value
* @param string $translateIdColumn column name to update. E.g. FormElement.feIdContainer, Ggroup.grId, ...
* @param string $tableName
*/
private function translateId(array $translateMap, $translateIdColumn, $tableName) {
foreach ($translateMap as $oldId => $newId) {
$row = $this->db->sql("SELECT $translateIdColumn FROM $tableName WHERE id=$newId", ROW_EXPECT_1);
if (!empty($row[$translateIdColumn])) {
$newNewId = $translateMap[$row[$translateIdColumn]];
$this->db->sql("UPDATE $tableName SET $translateIdColumn=$newNewId WHERE id=$newId LIMIT 1");
}
}
}
/**
* @param array $rowSrc
* @param array $rowDest
......
......@@ -331,8 +331,9 @@ CREATE TABLE IF NOT EXISTS `Clipboard` (
AUTO_INCREMENT = 0;
# Form: CopyForm
INSERT INTO Form (id, name, title, tableName, showButton, forwardPage)
VALUES (3, 'copyForm', 'Copy a form', 'Clipboard', 'close,save', '?id={{pageId:T}}&form=form&r={{formId:P0}}');
INSERT INTO Form (id, name, title, tableName, showButton, forwardMode, forwardPage)
VALUES
(3, 'copyForm', 'Copy a form', 'Clipboard', 'close,save', 'url-sip', '?id={{pageId:T}}&form=form&r={{formId:P0}}');
# FormElements: CopyForm
INSERT INTO FormElement (formId, name, label, type, class, ord, sql1, parameter)
......@@ -349,7 +350,7 @@ VALUES
'recordDestinationTable=Form'),
(3, 'formElementId', '', 'paste', 'action', 210,
'{{!SELECT fe.id AS id, {{formId:P}} AS formId FROM FormElement AS fe WHERE fe.formId={{id:P}} ORDER BY fe.ord}}',
'recordDestinationTable=FormElement');
'recordDestinationTable=FormElement\ntranslateIdColumn=feIdContainer');
Markdown is supported
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