Commit 5d817af7 authored by Carsten  Rose's avatar Carsten Rose
Browse files

#3433 | templateGroup on primary Record: Values of removed copies are not deleted

The new implementation creates empty fake instances of all copies of templateGroup FormElements. Those are empty. Before save, the submitted form values will be expanded with the empty fake templateGroup FormElements and such empty values will be saved.
FormAction.php: Rename constant SQL_FORM_ELEMENT_TEMPLATE_GROUP to SQL_FORM_ELEMENT_TEMPLATE_GROUP_FE_ID - to be more precise.
HelperFormElement.php, Database.php: new function explodeTemplateGroupElements()
parent b94d6ce1
......@@ -52,7 +52,10 @@ const SQL_FORM_ELEMENT_SPECIFIC_CONTAINER = "SELECT *, ? AS 'nestedInFieldSet' F
const SQL_FORM_ELEMENT_ALL_CONTAINER = "SELECT *, ? AS 'nestedInFieldSet' FROM FormElement AS fe WHERE fe.formId = ? AND fe.deleted = 'no' AND FIND_IN_SET(fe.class, ? ) AND fe.enabled='yes' ORDER BY fe.ord, fe.id";
const SQL_FORM_ELEMENT_SIMPLE_ALL_CONTAINER = "SELECT fe.id, fe.feIdContainer, fe.name, fe.label, fe.type, fe.checkType, fe.checkPattern, fe.mode, fe.modeSql, fe.parameter, fe.dynamicUpdate FROM FormElement AS fe, Form AS f WHERE f.name = ? AND f.id = fe.formId AND fe.deleted = 'no' AND fe.class = 'native' AND fe.enabled='yes' ORDER BY fe.ord, fe.id";
const SQL_FORM_ELEMENT_CONTAINER_TEMPLATE_GROUP = "SELECT fe.id, fe.name, fe.label, fe.maxLength, fe.parameter FROM FormElement AS fe, Form AS f WHERE f.name = ? AND f.id = fe.formId AND fe.deleted = 'no' AND fe.class = 'container' AND fe.type='templateGroup' AND fe.enabled='yes' ORDER BY fe.ord, fe.id";
const SQL_FORM_ELEMENT_TEMPLATE_GROUP = "SELECT * FROM FormElement AS fe WHERE fe.id = ? AND fe.deleted = 'no' AND fe.class = 'container' AND fe.type='templateGroup' AND fe.enabled='yes' ";
const SQL_FORM_ELEMENT_TEMPLATE_GROUP_FE_ID = "SELECT * FROM FormElement AS fe WHERE fe.id = ? AND fe.deleted = 'no' AND fe.class = 'container' AND fe.type='templateGroup' AND fe.enabled='yes' ";
const SQL_FORM_ELEMENT_NATIVE_TG_COUNT = "SELECT fe.*, IFNULL(feTg.maxLength,0) AS _tgCopies FROM FormElement AS fe LEFT JOIN FormElement AS feTg ON fe.feIdContainer=feTg.id AND feTg.deleted = 'no' AND feTg.class = 'container' AND feTg.type='templateGroup' AND feTg.enabled='yes' WHERE fe.formId = ? AND fe.deleted = 'no' AND fe.class = 'native' AND fe.enabled='yes'";
const NAME_TG_COPIES = '_tgCopies';
// SANITIZE Classifier
const SANITIZE_ALLOW_ALNUMX = "alnumx";
......
......@@ -650,8 +650,11 @@ class Database {
// Check for retype FormElements which have to duplicated.
$feSpecNative = HelperFormElement::duplicateRetypeElements($feSpecNative);
// Check for templateGroup Elements to explode them
$feSpecNative = HelperFormElement::explodeTemplateGroupElements($feSpecNative);
// Copy Attributes to FormElements
$this->feSpecNative = HelperFormElement::copyAttributesToFormElements($formSpec, $feSpecNative);
$feSpecNative = HelperFormElement::copyAttributesToFormElements($formSpec, $feSpecNative);
return $feSpecNative;
}
......
......@@ -294,8 +294,8 @@ class QuickFormQuery {
case FORM_UPDATE:
$formAction->elements($recordId, $this->feSpecAction, FE_TYPE_BEFORE_LOAD);
// data['form-update']=....
$data = $build->process($formMode);
// data['form-update']=....
$data = $build->process($formMode);
$formAction->elements($recordId, $this->feSpecAction, FE_TYPE_AFTER_LOAD);
break;
......@@ -425,15 +425,13 @@ class QuickFormQuery {
switch ($mode) {
case FORM_LOAD:
// Select all Native elements (native, pill, fieldset, templateGroup) which are NOT nested = Root level.
$this->feSpecNative = $this->db->getNativeFormElements(SQL_FORM_ELEMENT_SPECIFIC_CONTAINER,
['no', $this->formSpec["id"], 'native,container', 0], $this->formSpec);
$this->feSpecNative = $this->db->getNativeFormElements(SQL_FORM_ELEMENT_SPECIFIC_CONTAINER, ['no', $this->formSpec["id"], 'native,container', 0], $this->formSpec);
break;
case FORM_SAVE:
case FORM_UPDATE:
$this->feSpecNative = $this->db->getNativeFormElements(SQL_FORM_ELEMENT_ALL_CONTAINER,
['no', $this->formSpec["id"], 'native'], $this->formSpec);
// $this->feSpecNative = $this->db->getNativeFormElements(SQL_FORM_ELEMENT_ALL_CONTAINER, ['no', $this->formSpec["id"], 'native'], $this->formSpec);
$this->feSpecNative = $this->db->getNativeFormElements(SQL_FORM_ELEMENT_NATIVE_TG_COUNT, [$this->formSpec["id"]], $this->formSpec);
break;
case FORM_DELETE:
......
......@@ -71,6 +71,22 @@ class Save {
return $rc;
}
/**
* @param array $formValues
* @return array
*/
private function createEmptyTemplateGroupElements(array $formValues) {
foreach ($this->feSpecNative as $formElement) {
$feName = $formElement[FE_NAME];
if (!isset($formValues[$feName])) {
$formValues[$feName] = $formElement[FE_VALUE];
}
}
return $formValues;
}
/**
* @param $recordId
* @return int record id (in case of insert, it's different from $recordId)
......@@ -86,6 +102,7 @@ class Save {
$tableColumns = array_keys($this->store->getStore(STORE_TABLE_COLUMN_TYPES));
$formValues = $this->store->getStore(STORE_FORM);
$formValues = $this->createEmptyTemplateGroupElements($formValues);
// Iterate over all table.columns. Built an assoc array $newValues.
foreach ($tableColumns AS $column) {
......@@ -384,7 +401,7 @@ class Save {
$flagUpdateSlaveId = false;
$flagSlaveDeleted = false;
if(!isset($fe[FE_SLAVE_ID])) {
if (!isset($fe[FE_SLAVE_ID])) {
throw new UserFormException("Missing 'slaveId'-definition", ERROR_MISSING_SLAVE_ID_DEFINITION);
}
......
......@@ -85,7 +85,7 @@ class FormAction {
// Process templateGroup action elements
if (isset($fe[FE_ID_CONTAINER]) && $fe[FE_ID_CONTAINER] > 0) {
$feTemplateGroup = $this->db->sql(SQL_FORM_ELEMENT_TEMPLATE_GROUP, ROW_REGULAR, [$fe[FE_ID_CONTAINER]]);
$feTemplateGroup = $this->db->sql(SQL_FORM_ELEMENT_TEMPLATE_GROUP_FE_ID, ROW_REGULAR, [$fe[FE_ID_CONTAINER]]);
if (count($feTemplateGroup) == 1) {
$fe[FE_ID_CONTAINER] = 0;
......
......@@ -17,8 +17,7 @@ require_once(__DIR__ . '/../../qfq/Constants.php');
require_once(__DIR__ . '/../../qfq/helper/KeyValueStringParser.php');
require_once(__DIR__ . '/../../qfq/exceptions/UserFormException.php');
class HelperFormElement
{
class HelperFormElement {
/**
* Expand column $keyName to row array as virtual columns.
......@@ -43,8 +42,7 @@ class HelperFormElement
* @throws CodeException
* @throws \qfq\UserFormException
*/
public static function explodeParameter(array &$element, $keyName)
{
public static function explodeParameter(array &$element, $keyName) {
// Something to explode?
if (isset($element[$keyName]) && $element[$keyName] !== '') {
// Explode
......@@ -70,8 +68,7 @@ class HelperFormElement
* @param string $id
* @return string
*/
public static function buildFormElementName($field, $id)
{
public static function buildFormElementName($field, $id) {
return "$field" . HTML_DELIMITER_NAME . "$id";
}
......@@ -144,6 +141,40 @@ class HelperFormElement
return $arr;
}
/**
* Iterate over all FormElements in $elements. If a row has a column NAME_TG_COPIES, copy those elements NAME_TG_COPIES-times.
* Adjust FE_TEMPLATE_GROUP_NAME_PATTERN (='%d') with current count on column FE_NAME and FE_LABEL.
*
* The resulting order of the FormElements, is not the same as on the Form during FormLoad!
*
* @param array $elements
* @return array
*/
public static function explodeTemplateGroupElements(array $elements) {
$new = array();
// No FormElements or no NAME_TG_COPIES column: nothing to do, return.
if ($elements == array() || count($elements) == 0 || !isset($elements[0][NAME_TG_COPIES])) {
return $elements;
}
// Iterate over all
foreach ($elements as $row) {
if (isset($row[NAME_TG_COPIES]) && $row[NAME_TG_COPIES] > 0) {
for ($ii = 1; $ii <= $row[NAME_TG_COPIES]; $ii++) {
$tmpRow = $row;
unset($tmpRow[NAME_TG_COPIES]);
$tmpRow[FE_NAME] = str_replace(FE_TEMPLATE_GROUP_NAME_PATTERN, $ii, $tmpRow[FE_NAME]);
$tmpRow[FE_LABEL] = str_replace(FE_TEMPLATE_GROUP_NAME_PATTERN, $ii, $tmpRow[FE_LABEL]);
$new[] = $tmpRow;
}
} else {
$new[] = $row;
}
}
return $new;
}
/**
* Copy specific attributes defined on the form to all FormElements.
*
......
......@@ -160,4 +160,32 @@ class HelperFormElementTest extends \PHPUnit_Framework_TestCase {
$this->assertEquals($expect, $result, "Both arrays should be equal");
}
public function testExplodeTemplateGroupElements() {
$formElements = array();
$result = HelperFormElement::explodeTemplateGroupElements(array());
$this->assertEquals(array(), $result, "Both arrays should be equal");
$formElements = [[FE_NAME => 'nameA', FE_LABEL => 'labelA', FE_VALUE => '1'], [FE_NAME => 'nameB', FE_LABEL => 'labelB', FE_VALUE => '11']];
$result = HelperFormElement::explodeTemplateGroupElements($formElements);
$this->assertEquals($formElements, $result, "Both arrays should be equal");
$formElements = [[FE_NAME => 'nameA', FE_LABEL => 'label' . FE_TEMPLATE_GROUP_NAME_PATTERN . 'A', FE_VALUE => '1'], [FE_NAME => 'nameB', FE_LABEL => 'labelB', FE_VALUE => '11']];
$result = HelperFormElement::explodeTemplateGroupElements($formElements);
$this->assertEquals($formElements, $result, "Both arrays should be equal");
$formElements = [[FE_NAME => 'nameA', FE_LABEL => 'label' . FE_TEMPLATE_GROUP_NAME_PATTERN . 'A', FE_VALUE => '1', NAME_TG_COPIES => 2], [FE_NAME => 'nameB', FE_LABEL => 'labelB', FE_VALUE => '11']];
$result = HelperFormElement::explodeTemplateGroupElements($formElements);
$formElements = [[FE_NAME => 'nameA', FE_LABEL => 'label1A', FE_VALUE => '1'],
[FE_NAME => 'nameA', FE_LABEL => 'label2A', FE_VALUE => '1'],
[FE_NAME => 'nameB', FE_LABEL => 'labelB', FE_VALUE => '11']];
$this->assertEquals($formElements, $result, "Both arrays should be equal");
$formElements = [[FE_NAME => FE_TEMPLATE_GROUP_NAME_PATTERN . 'nameA', FE_LABEL => 'label' . FE_TEMPLATE_GROUP_NAME_PATTERN . 'A', FE_VALUE => '1', NAME_TG_COPIES => 2], [FE_NAME => 'nameB', FE_LABEL => 'labelB', FE_VALUE => '11']];
$result = HelperFormElement::explodeTemplateGroupElements($formElements);
$formElements = [[FE_NAME => '1nameA', FE_LABEL => 'label1A', FE_VALUE => '1'],
[FE_NAME => '2nameA', FE_LABEL => 'label2A', FE_VALUE => '1'],
[FE_NAME => 'nameB', FE_LABEL => 'labelB', FE_VALUE => '11']];
$this->assertEquals($formElements, $result, "Both arrays should be equal");
}
}
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