diff --git a/extension/qfq/qfq/AbstractBuildForm.php b/extension/qfq/qfq/AbstractBuildForm.php index 43990df364e1b8f338f236669908aae14df13ba2..6af125ba23a3fa4d671e9290810e3eab312f70d8 100644 --- a/extension/qfq/qfq/AbstractBuildForm.php +++ b/extension/qfq/qfq/AbstractBuildForm.php @@ -118,7 +118,7 @@ abstract class AbstractBuildForm { * @throws DbException * @throws \qfq\UserFormException */ - public function process($mode) { + public function process($mode, $htmlElementNameIdZero = false) { $htmlHead = ''; $htmlTail = ''; $htmlSubrecords = ''; @@ -145,12 +145,14 @@ abstract class AbstractBuildForm { $json[] = $jsonTmp; } } else { - $htmlElements = $this->elements($this->store->getVar(SIP_RECORD_ID, STORE_SIP), $filter, 0, $json, $modeCollectFe); + $htmlElements = $this->elements($this->store->getVar(SIP_RECORD_ID, STORE_SIP), $filter, 0, $json, $modeCollectFe, $htmlElementNameIdZero); } + $htmlSip = $this->buildHiddenSip($json); + // </form> - return ($mode === FORM_LOAD) ? $htmlHead . $htmlElements . $htmlTail . $htmlSubrecords : $json; + return ($mode === FORM_LOAD) ? $htmlHead . $htmlElements . $htmlSip . $htmlTail . $htmlSubrecords : $json; } /** @@ -300,7 +302,8 @@ abstract class AbstractBuildForm { * @throws DbException * @throws \qfq\UserFormException */ - public function elements($recordId, $filter = FORM_ELEMENTS_NATIVE, $feIdContainer = 0, &$json, $modeCollectFe = FLAG_DYNAMIC_UPDATE) { + public function elements($recordId, $filter = FORM_ELEMENTS_NATIVE, $feIdContainer = 0, &$json, + $modeCollectFe = FLAG_DYNAMIC_UPDATE, $htmlElementNameIdZero = false) { $html = ''; // get current data record @@ -328,9 +331,12 @@ abstract class AbstractBuildForm { $formElement = $evaluate->parseArray($fe, $debugStack); // Get default value - $value = ($formElement['value'] === '') ? $this->store->getVar($formElement['name'], STORE_USE_DEFAULT, $formElement['checkType']) : $formElement['value']; + $value = ($formElement['value'] === '') ? $this->store->getVar($formElement['name'], STORE_USE_DEFAULT, + $formElement['checkType']) : $formElement['value']; - $htmlFormElementId = HelperFormElement::buildFormElementId($formElement['name'], $recordId); + // Typically: $htmlElementNameIdZero = true + // After Saving a record, staying on the form, the FormElements on the Client are still known as '<feName>:0'. + $htmlFormElementId = HelperFormElement::buildFormElementId($formElement['name'], ($htmlElementNameIdZero) ? 0 : $recordId); // Construct Marshaller Name: buildElement $buildElementFunctionName = 'build' . $this->buildElementFunctionName[$formElement['type']]; @@ -373,6 +379,57 @@ abstract class AbstractBuildForm { return $html; } + /** + * Create a hidden sip, based on latest STORE_SIP Values. Return complete HTML 'hidden' element. + * + * @param $json + * @return string <input type='hidden' name='s' value='<sip>'> + * @throws CodeException + * @throws \qfq\UserFormException + */ + public function buildHiddenSip(&$json) { + $sipArray = $this->store->getStore(STORE_SIP); + unset($sipArray[SIP_SIP]); + unset($sipArray[SIP_URLPARAM]); + + $queryString = Support::arrayToQueryString($sipArray); + $sip = $this->store->getSipInstance(); + + $sipValue = $sip->queryStringToSip($queryString, RETURN_SIP); + + $json[] = $this->getJsonElementUpdate(CLIENT_SIP, $sipValue, ''); + + return $this->buildNativeHidden(CLIENT_SIP, $sipValue); + } + + /** + * @param $htmlFormElementId + * @param string|array $value + * @param string $mode disabled|readonly|'' + * @return array + */ + private function getJsonElementUpdate($htmlFormElementId, $value, $mode) { + $json = array(); + + $json['form-element'] = $htmlFormElementId; + $json['value'] = $value; + $json['disabled'] = ($mode === 'disabled'); + $json['readonly'] = ($mode === 'readonly'); + + return $json; + } + + /** + * Builds a real HTML hidden form element. Useful for checkboxes, Multiple-Select and Radios. + * + * @param $htmlFormElementId + * @param $value + * @return string + */ + public function buildNativeHidden($htmlFormElementId, $value) { + return '<input type="hidden" name="' . $htmlFormElementId . '" value="' . htmlentities($value) . '">'; + } + /** * Takes the current SIP ('form' and additional parameter), set SIP_RECORD_ID=0 and create a new 'NewRecordUrl'. * @@ -621,23 +678,6 @@ abstract class AbstractBuildForm { return $attribute; } - /** - * @param $htmlFormElementId - * @param string|array $value - * @param $mode - * @return array - */ - private function getJsonElementUpdate($htmlFormElementId, $value, $mode) { - $json = array(); - - $json['form-element'] = $htmlFormElementId; - $json['value'] = $value; - $json['disabled'] = ($mode === 'disabled'); - $json['readonly'] = ($mode === 'readonly'); - - return $json; - } - /** * Builds HTML 'checkbox' element. * @@ -879,17 +919,6 @@ abstract class AbstractBuildForm { return $html; } - /** - * Builds a real HTML hidden form element. Useful for checkboxes, Multiple-Select and Radios. - * - * @param $htmlFormElementId - * @param $value - * @return string - */ - public function buildNativeHidden($htmlFormElementId, $value) { - return '<input type="hidden" name="' . $htmlFormElementId . '" value="' . htmlentities($value) . '">'; - } - /** * Build as many Checkboxes as items. * @@ -1513,24 +1542,6 @@ abstract class AbstractBuildForm { return $html; } - /** - * Create a new sip, based on latest STORE_SIP Values. Return complete HTML 'hidden' element. - * - * @return string - */ - public function buildNewSip() { - $sipArray = $this->store->getStore(STORE_SIP); - unset($sipArray[SIP_SIP]); - unset($sipArray[SIP_URLPARAM]); - - $queryString = Support::arrayToQueryString($sipArray); - $sip = $this->store->getSipInstance(); - - $sipValue = $sip->queryStringToSip($queryString, RETURN_SIP); - - return $this->buildNativeHidden(CLIENT_SIP, $sipValue); - } - /** * @param $table * @param $recordId diff --git a/extension/qfq/qfq/BuildFormBootstrap.php b/extension/qfq/qfq/BuildFormBootstrap.php index ff688059f0c3470549481b01563a664913e2bce0..14cb2ebea5139e778d7b15ef161be29750dab9c2 100644 --- a/extension/qfq/qfq/BuildFormBootstrap.php +++ b/extension/qfq/qfq/BuildFormBootstrap.php @@ -296,13 +296,11 @@ class BuildFormBootstrap extends AbstractBuildForm { */ public function tail() { $html = ''; - $html .= $this->buildNewSip(); +// $html .= $this->buildNewSip(); $deleteUrl = ''; $formId = $this->getFormId(); - // TODO: bootstrap. See BuildFormTable.tail() - $html .= '</div> <!--class="tab-content" -->'; // <div class="tab-content"> // $html .= '<input type="submit" value="Submit">'; diff --git a/extension/qfq/qfq/BuildFormPlain.php b/extension/qfq/qfq/BuildFormPlain.php index b115932eca2ff3bce0e9e9ef3966f45393bfcd55..72d59b0aaa9f29004dae6220a8ed2fc65c8d06ca 100644 --- a/extension/qfq/qfq/BuildFormPlain.php +++ b/extension/qfq/qfq/BuildFormPlain.php @@ -87,7 +87,7 @@ class BuildFormPlain extends AbstractBuildForm { public function tail() { $html = ''; - $html .= $this->buildNewSip(); +// $html .= $this->buildNewSip(); $html .= $this->wrapItem(WRAP_SETUP_INPUT, '<input type="submit" value="Submit">'); $html = $this->wrapItem(WRAP_SETUP_ELEMENT, $html); diff --git a/extension/qfq/qfq/BuildFormTable.php b/extension/qfq/qfq/BuildFormTable.php index f97880371f27f03eff25a203e8cfe37a838e451f..e47e44627009f6c2847fb772e132ace02935d7b5 100644 --- a/extension/qfq/qfq/BuildFormTable.php +++ b/extension/qfq/qfq/BuildFormTable.php @@ -130,7 +130,7 @@ class BuildFormTable extends AbstractBuildForm { $html .= $this->wrapItem(WRAP_SETUP_INPUT, '<input type="submit" value="Submit">'); $html = $this->wrapItem(WRAP_SETUP_ELEMENT, $html); $html .= '</table>'; - $html .= $this->buildNewSip(); +// $html .= $this->buildNewSip(); $html .= '</form>'; $html .= '</div>'; // main <div class=...> around everything diff --git a/extension/qfq/qfq/QuickFormQuery.php b/extension/qfq/qfq/QuickFormQuery.php index 399c3892d73b13792e158350dbd016c84055185e..9e5b70ffbd4c78070ae2c5834cb10943cf395491 100644 --- a/extension/qfq/qfq/QuickFormQuery.php +++ b/extension/qfq/qfq/QuickFormQuery.php @@ -226,10 +226,23 @@ class QuickFormQuery { case FORM_SAVE: $save = new Save($this->formSpec, $this->feSpecAction, $this->feSpecNative); - $save->process(); + $rc = $save->process(); + + // Reload fresh saved record and fill STORE_RECORD with it + $record = $this->db->sql("SELECT * FROM " . $this->formSpec['tableName'] . " WHERE id = ?", ROW_EXPECT_1, [$rc]); + $this->store->setVarArray($record, STORE_RECORD, true); + + $htmlElementNameIdZero = false; + // Retrieve current STORE_SIP. + $sipArray = $this->store->getStore(STORE_SIP); + if ($sipArray[SIP_RECORD_ID] == 0) { + // After insert: a new SIP for the new record id is required + $this->newRecordCreateSip($sipArray, $rc); + $htmlElementNameIdZero = true; + } // Retrieve FE Values as JSON - $data = $build->process($mode); + $data = $build->process($mode, $htmlElementNameIdZero); break; default: @@ -340,7 +353,7 @@ class QuickFormQuery { break; case FORM_SAVE: case FORM_UPDATE: - $store = STORE_SIP; + $store = STORE_SIP; break; default: throw new CodeException("Unknown mode: $mode.", ERROR_UNKNOWN_MODE); @@ -420,6 +433,43 @@ class QuickFormQuery { return $sipFound; } + /** + * @param $sipArray + * @param $recordId + */ + private function newRecordCreateSip($sipArray, $recordId) { + + $tmpParam = array(); + + foreach ($sipArray as $key => $value) { + switch ($key) { + case SIP_SIP: + case SIP_URLPARAM: + case SIP_TABLE: + continue; + + case SIP_RECORD_ID: + $tmpParam[SIP_RECORD_ID] = $recordId; + break; + default: + // further vars stored in old SIP (form, maybe default values) + $tmpParam[$key] = $value; + break; + } + } + + // Construct fake urlparam + $tmpUrlparam = OnArray::toString($tmpParam); + + // Create a SIP which has never been passed by URL - further processing might expect this to exist. + $sip = store::getSipInstance()->queryStringToSip($tmpUrlparam, RETURN_SIP); + $this->store->setVar(CLIENT_SIP, $sip, STORE_CLIENT); + + // Overwrite SIP Store + $tmpParam[SIP_SIP] = $sip; + $this->store->setVarArray($tmpParam, STORE_SIP, true); + } + /** * Process the SQL Queries from bodytext. Return the output. * diff --git a/extension/qfq/qfq/Save.php b/extension/qfq/qfq/Save.php index 38a261fdf3f30c2d66ccb3acd655109d714c328e..e4cc4c38b794959b81ecba923bf7435786177f5b 100644 --- a/extension/qfq/qfq/Save.php +++ b/extension/qfq/qfq/Save.php @@ -52,22 +52,25 @@ class Save { * @throws UserFormException */ public function process() { + $rc = 0; if ($this->formSpec['multiMode'] !== 'none') { $parentRecords = $this->db->sql($this->formSpec['multiSql']); foreach ($parentRecords as $row) { $this->store->setVarArray($row, STORE_PARENT_RECORD, true); - $this->elements($row['_id']); + $rc = $this->elements($row['_id']); } } else { - $this->elements($this->store->getVar(SIP_RECORD_ID, STORE_SIP . STORE_ZERO)); + $rc = $this->elements($this->store->getVar(SIP_RECORD_ID, STORE_SIP . STORE_ZERO)); } + + return $rc; } /** * @param $recordId - * @return string + * @return int record id (in case of insert, it's different from $recordId) * @throws CodeException * @throws DbException * @throws UserFormException @@ -98,7 +101,14 @@ class Save { } } - return ($recordId == 0) ? $this->insertRecord($this->formSpec['tableName'], $newValues) : $this->updateRecord($this->formSpec['tableName'], $newValues, $recordId); + if ($recordId == 0) { + $rc = $this->insertRecord($this->formSpec['tableName'], $newValues); + } else { + $this->updateRecord($this->formSpec['tableName'], $newValues, $recordId); + $rc = $recordId; + } + + return $rc; } /** @@ -119,7 +129,7 @@ class Save { * Insert new record in table $this->formSpec['tableName']. * * @param array $values - * @return string + * @return int last insert id * @throws DbException */ public function insertRecord($tableName, array $values) { @@ -142,7 +152,7 @@ class Save { * @param string $tableName * @param array $values * @param int $recordId - * @return bool|int false if $values is empty + * @return bool|int false if $values is empty, else affectedrows * @throws CodeException * @throws DbException */