Commit 7372d504 authored by Carsten  Rose's avatar Carsten Rose
Browse files

#3925 / templateGroup / non primary / delete records: only one at a time

Fixed by implementing an $correctDeleteIndex.
FormAction.php: extended elements(), doSlave() from RC=bool to 3 states, it's now possible to detect a deletion and correct the index of any further array processing.
parent 8a28ffd5
......@@ -1059,3 +1059,7 @@ const TOKEN_CLASS_EXTERNAL = 'e';
const WKHTML_OPTION_VIEWPORT = '--viewport-size';
const WKHTML_OPTION_VIEWPORT_VALUE = '1280x1024';
// FormAction.php:
const ACTION_ELEMENT_NO_CHANGE = 0;
const ACTION_ELEMENT_MODIFIED = 1;
const ACTION_ELEMENT_DELETED = -1;
\ No newline at end of file
......@@ -178,7 +178,7 @@ class Evaluate {
* The token have to be _without_ Delimiter '{{' / '}}'
* If neither a) or b) match, return the token itself.
*
* @param $token
* @param string $token
* @param string $foundInStore Returns the name of the store where $key has been found. If $key is not found, return ''.
* @return array|null|string
* @throws CodeException
......
......@@ -333,8 +333,8 @@ class QuickFormQuery {
$save->processAllUploads($rc);
// Action: After
$modified = $formAction->elements($rc, $this->feSpecAction, FE_TYPE_AFTER_INSERT . ',' . FE_TYPE_AFTER_UPDATE . ',' . FE_TYPE_AFTER_SAVE);
if ($modified) {
$status = $formAction->elements($rc, $this->feSpecAction, FE_TYPE_AFTER_INSERT . ',' . FE_TYPE_AFTER_UPDATE . ',' . FE_TYPE_AFTER_SAVE);
if ($status != ACTION_ELEMENT_NO_CHANGE) {
// Reload fresh saved record and fill STORE_RECORD with it.
$this->fillStoreWithRecord($this->formSpec[F_TABLE_NAME], $rc, STORE_RECORD);
}
......
......@@ -63,14 +63,16 @@ class FormAction {
* On FormLoad: FE_TYPE_BEFORE_LOAD, FE_TYPE_AFTER_LOAD
* Before Save: FE_TYPE_BEFORE_SAVE, FE_TYPE_BEFORE_INSERT, FE_TYPE_BEFORE_UPDATE, FE_TYPE_BEFORE_DELETE
* After Save: FE_TYPE_AFTER_SAVE, FE_TYPE_AFTER_INSERT, FE_TYPE_AFTER_UPDATE, FE_TYPE_AFTER_DELETE
* @return bool: true if there are potential changes on the DB like fired SQL statements, else false.
* @return int: ACTION_ELEMENT_MODIFIED if there are potential changes on the DB like fired SQL statements,
* ACTION_ELEMENT_NO_CHANGE if nothing happened
* ACTION_ELEMENT_DELETED: if a record has been deleted (only in recursive calls, not the initial one)
* @throws CodeException
* @throws DbException
* @throws UserFormException
*/
public function elements($recordId, array $feSpecAction, $feTypeList) {
$flagModified = false;
$rc = ACTION_ELEMENT_NO_CHANGE;
// Iterate over all Action FormElements
foreach ($feSpecAction as $fe) {
......@@ -94,11 +96,22 @@ class FormAction {
if (isset($templateGroup[FE_TYPE]) && $templateGroup[FE_TYPE] == FE_TYPE_TEMPLATE_GROUP) {
$maxCopies = HelperFormElement::tgGetMaxLength($templateGroup[FE_MAX_LENGTH]);
$fe[FE_ID_CONTAINER] = 0; // Flag to make the nested TG unnested and therefore the SQLs are fired.
// for ($ii = $maxCopies; $ii > 0; $ii--) { // Iterate backwards: deleting records starts at the end and doesn't affect remaining counting
$correctDeleteIndex = 0;
for ($ii = 1; $ii <= $maxCopies; $ii++) {
$feNew = OnArray::arrayValueReplace($fe, FE_TEMPLATE_GROUP_NAME_PATTERN, $ii);
$feNew = OnArray::arrayValueReplace($feNew, FE_TEMPLATE_GROUP_NAME_PATTERN_0, $ii - 1);
if ($this->elements($recordId, [$feNew], $feTypeList)) {
$flagModified = true;
$feNew = OnArray::arrayValueReplace($fe, FE_TEMPLATE_GROUP_NAME_PATTERN, $ii - $correctDeleteIndex);
$feNew = OnArray::arrayValueReplace($feNew, FE_TEMPLATE_GROUP_NAME_PATTERN_0, $ii - 1 - $correctDeleteIndex);
switch ($this->elements($recordId, [$feNew], $feTypeList)) {
case ACTION_ELEMENT_MODIFIED:
$rc = ACTION_ELEMENT_MODIFIED;
break;
case ACTION_ELEMENT_DELETED:
$rc = ACTION_ELEMENT_MODIFIED;
$correctDeleteIndex++;
break;
case ACTION_ELEMENT_NO_CHANGE:
default:
break;
}
}
continue; // skip to next FormElement
......@@ -145,12 +158,18 @@ class FormAction {
$this->validate($fe);
$this->doSlave($fe, $recordId);
$flagModified = true;
$rcTmp = $this->doSlave($fe, $recordId);
switch ($rcTmp) {
case ACTION_ELEMENT_MODIFIED:
case ACTION_ELEMENT_DELETED:
$rc = $rcTmp;
break;
default:
break;
}
}
return $flagModified;
return $rc;
}
/**
......@@ -270,13 +289,18 @@ class FormAction {
*
* @param array $fe
* @param int $recordId
* @return int
* @return int ACTION_ELEMENT_MODIFIED if there are potential(!) changes on the DB like INSERT / UPDATE,
* ACTION_ELEMENT_NO_CHANGE if nothing happened
* ACTION_ELEMENT_DELETED: if a record has been deleted
* $sqlAfter won't affect the $rc.
* @throws CodeException
* @throws DbException
* @throws UserFormException
*/
private function doSlave(array $fe, $recordId) {
$rcStatus = ACTION_ELEMENT_NO_CHANGE;
// Get the slaveId
$slaveId = $this->evaluate->parse($fe[FE_SLAVE_ID]);
......@@ -312,16 +336,19 @@ class FormAction {
$slaveId = $this->evaluate->parse($fe[FE_SQL_INSERT]);
// Store the slaveId: might be used later
$this->store->setVar(VAR_SLAVE_ID, $slaveId, STORE_VAR, true);
$rcStatus = ACTION_ELEMENT_MODIFIED;
}
if ($doUpdate) {
$this->evaluate->parse($fe[FE_SQL_UPDATE]);
$rcStatus = ACTION_ELEMENT_MODIFIED;
}
// Fire a delete query
if ($doDelete) {
$this->evaluate->parse($fe[FE_SQL_DELETE]);
$slaveId = 0;
$rcStatus = ACTION_ELEMENT_DELETED;
}
// Check if there is a column with the same name as the 'action'-FormElement.
......@@ -330,11 +357,10 @@ class FormAction {
$this->db->sql("UPDATE " . $this->primaryTableName . " SET " . $fe[FE_NAME] . " = $slaveId WHERE id = ? LIMIT 1", ROW_REGULAR, [$recordId]);
}
// If given: fire a sqlAfter query
// If given: fire a $sqlAfter query. $sqlAfter won't affect $rc
$this->evaluate->parse($fe[FE_SQL_AFTER]);
return $slaveId;
return $rcStatus;
}
/**
......
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