Commit 50c8c32b authored by Carsten  Rose's avatar Carsten Rose
Browse files

B5077 Dynamic Update & FE.type=required: Server fixed - a) dynamic calculated...

B5077 Dynamic Update & FE.type=required: Server fixed - a) dynamic calculated modeSql respected, b) formModeGlobal=requiredOff respected, c) dynamic FE with mode='hidden' are not saved anymore.
parent eed5887a
...@@ -177,6 +177,7 @@ abstract class AbstractBuildForm { ...@@ -177,6 +177,7 @@ abstract class AbstractBuildForm {
* @throws CodeException * @throws CodeException
* @throws DbException * @throws DbException
* @throws UserFormException * @throws UserFormException
* @throws UserReportException
*/ */
public function process($mode, $htmlElementNameIdZero = false, $latestFeSpecNative = array()) { public function process($mode, $htmlElementNameIdZero = false, $latestFeSpecNative = array()) {
$htmlHead = ''; $htmlHead = '';
...@@ -252,6 +253,7 @@ abstract class AbstractBuildForm { ...@@ -252,6 +253,7 @@ abstract class AbstractBuildForm {
* @param string $mode * @param string $mode
* @return string * @return string
* @throws CodeException * @throws CodeException
* @throws DbException
* @throws UserFormException * @throws UserFormException
*/ */
public function head($mode = FORM_LOAD) { public function head($mode = FORM_LOAD) {
...@@ -415,6 +417,9 @@ abstract class AbstractBuildForm { ...@@ -415,6 +417,9 @@ abstract class AbstractBuildForm {
* Build an assoc array with standard form attributes. * Build an assoc array with standard form attributes.
* *
* @return array * @return array
* @throws CodeException
* @throws DbException
* @throws UserFormException
*/ */
public function getFormTagAttributes() { public function getFormTagAttributes() {
...@@ -1838,6 +1843,7 @@ abstract class AbstractBuildForm { ...@@ -1838,6 +1843,7 @@ abstract class AbstractBuildForm {
* *
* @return string * @return string
* @throws CodeException * @throws CodeException
* @throws UserFormException
*/ */
public function constructCheckboxMultiButton(array $formElement, $htmlFormElementName, $attributeBase, $value, array $itemKey, array $itemValue, array &$json) { public function constructCheckboxMultiButton(array $formElement, $htmlFormElementName, $attributeBase, $value, array $itemKey, array $itemValue, array &$json) {
$json = array(); $json = array();
...@@ -1910,6 +1916,7 @@ abstract class AbstractBuildForm { ...@@ -1910,6 +1916,7 @@ abstract class AbstractBuildForm {
* *
* @return string * @return string
* @throws CodeException * @throws CodeException
* @throws UserFormException
*/ */
public function constructCheckboxMultiPlain(array $formElement, $htmlFormElementName, $attributeBase, $value, array $itemKey, array $itemValue, array &$json) { public function constructCheckboxMultiPlain(array $formElement, $htmlFormElementName, $attributeBase, $value, array $itemKey, array $itemValue, array &$json) {
$json = array(); $json = array();
...@@ -3403,6 +3410,7 @@ abstract class AbstractBuildForm { ...@@ -3403,6 +3410,7 @@ abstract class AbstractBuildForm {
* @param string $mode FORM_LOAD | FORM_UPDATE | FORM_SAVE * @param string $mode FORM_LOAD | FORM_UPDATE | FORM_SAVE
* @return mixed * @return mixed
* @throws CodeException * @throws CodeException
* @throws UserFormException
*/ */
public function buildNote(array $formElement, $htmlFormElementName, $value, array &$json, $mode = FORM_LOAD) { public function buildNote(array $formElement, $htmlFormElementName, $value, array &$json, $mode = FORM_LOAD) {
......
...@@ -439,6 +439,7 @@ class QuickFormQuery { ...@@ -439,6 +439,7 @@ class QuickFormQuery {
$save = new Save($this->formSpec, $this->feSpecAction, $this->feSpecNative, $this->feSpecNativeRaw); $save = new Save($this->formSpec, $this->feSpecAction, $this->feSpecNative, $this->feSpecNativeRaw);
$save->processAllImageCutFE(); $save->processAllImageCutFE();
$save->checkRequiredHidden();
$rc = $save->process(); $rc = $save->process();
......
...@@ -43,6 +43,7 @@ class Save { ...@@ -43,6 +43,7 @@ class Save {
* @param array $feSpecNative * @param array $feSpecNative
* @param array $feSpecNativeRaw * @param array $feSpecNativeRaw
* @throws CodeException * @throws CodeException
* @throws DbException
* @throws UserFormException * @throws UserFormException
*/ */
public function __construct(array $formSpec, array $feSpecAction, array $feSpecNative, array $feSpecNativeRaw) { public function __construct(array $formSpec, array $feSpecAction, array $feSpecNative, array $feSpecNativeRaw) {
...@@ -389,9 +390,11 @@ class Save { ...@@ -389,9 +390,11 @@ class Save {
} }
/** /**
* Process all Upload Formelements for the given $recordId. After processing &$formValues will be updated with the * Process all Upload FormElements for the given $recordId.
* final filenames. * After processing, &$formValues will be updated with the final filename.
* *
* @throws CodeException
* @throws UserFormException
*/ */
public function processAllImageCutFE() { public function processAllImageCutFE() {
...@@ -405,6 +408,45 @@ class Save { ...@@ -405,6 +408,45 @@ class Save {
} }
} }
/**
* Iterates over all FE and checks all 'required' (mode & modeSql) FE.
* If a required FE is empty, throw an exception.
* Take care to remove all FE with modeSql='hidden'.
*
* Typically, the browser does not allow a submit if a required field is empty.
*
* @throws CodeException
* @throws DbException
* @throws UserFormException
* @throws UserReportException
*/
public function checkRequiredHidden() {
$requiredOff = ($this->store->getVar(F_MODE_GLOBAL, STORE_SIP) == F_MODE_REQUIRED_OFF);
$clientValues = $this->store::getStore(STORE_FORM);
foreach ($this->feSpecNative AS $key => $formElement) {
if (empty($formElement[FE_MODE_SQL])) {
$mode = $formElement[FE_MODE];
} else {
$mode = $this->evaluate->parse($formElement[FE_MODE_SQL]);
$this->feSpecNative[$key][FE_MODE_SQL] = $mode;
}
if (!$requiredOff && $mode == FE_MODE_REQUIRED && empty($clientValues[$formElement[FE_NAME]])) {
throw new UserFormException("Missing required value.", ERROR_REQUIRED_VALUE_EMPTY);
}
if ($mode == FE_MODE_HIDDEN) {
// Removing the value from the store, forces that the value won't be stored.
$this->store::unsetVar($formElement[FE_NAME], STORE_FORM);
}
}
}
/** /**
* *
* @param array $formElement * @param array $formElement
...@@ -420,7 +462,7 @@ class Save { ...@@ -420,7 +462,7 @@ class Save {
throw new UserFormException("getcwd() failed or SITE_PATH undefined or chdir('$sitePath') failed.", ERROR_IO_CHDIR); throw new UserFormException("getcwd() failed or SITE_PATH undefined or chdir('$sitePath') failed.", ERROR_IO_CHDIR);
} }
// Get original pathfilename // Get original pathFileName
$field = HelperFormElement::AppendFormElementNameImageCut($formElement); $field = HelperFormElement::AppendFormElementNameImageCut($formElement);
$pathFileName = $this->store->getVar($field, STORE_SIP); $pathFileName = $this->store->getVar($field, STORE_SIP);
if ($pathFileName == '' || !file_exists($pathFileName)) { if ($pathFileName == '' || !file_exists($pathFileName)) {
......
...@@ -45,7 +45,10 @@ class FillStoreForm { ...@@ -45,7 +45,10 @@ class FillStoreForm {
private $evaluate = null; private $evaluate = null;
/** /**
* * FillStoreForm constructor.
* @throws CodeException
* @throws DbException
* @throws UserFormException
*/ */
public function __construct() { public function __construct() {
...@@ -90,7 +93,6 @@ class FillStoreForm { ...@@ -90,7 +93,6 @@ class FillStoreForm {
$feSpecNative = $this->expandTemplateGroupFormElement($feSpecTemplateGroup, $feSpecNative); $feSpecNative = $this->expandTemplateGroupFormElement($feSpecTemplateGroup, $feSpecNative);
return $feSpecNative; return $feSpecNative;
} }
...@@ -240,11 +242,12 @@ class FillStoreForm { ...@@ -240,11 +242,12 @@ class FillStoreForm {
break; break;
} }
if ($formElement[FE_MODE] === FE_MODE_REQUIRED) { // Bug #5077 / 'Required' FormElement with Dynamic Update - required FE will be checked later - at this point there is no F, R store.
if (!isset($clientValues[$clientFieldName]) || ($clientValues[$clientFieldName] === '')) { // if ($formElement[FE_MODE] === FE_MODE_REQUIRED) {
throw new UserFormException("Missing required value.", ERROR_REQUIRED_VALUE_EMPTY); // if (!isset($clientValues[$clientFieldName]) || ($clientValues[$clientFieldName] === '')) {
} // throw new UserFormException("Missing required value.", ERROR_REQUIRED_VALUE_EMPTY);
} // }
// }
// copy value to $newValues // copy value to $newValues
if (isset($clientValues[$clientFieldName])) { if (isset($clientValues[$clientFieldName])) {
...@@ -258,6 +261,7 @@ class FillStoreForm { ...@@ -258,6 +261,7 @@ class FillStoreForm {
if ($clientValues[$clientFieldName] !== '') // do not check empty values if ($clientValues[$clientFieldName] !== '') // do not check empty values
$val = $this->doDateTime($formElement, $val); $val = $this->doDateTime($formElement, $val);
break; break;
default: default:
if ($formElement[FE_TYPE] == FE_TYPE_EDITOR) { if ($formElement[FE_TYPE] == FE_TYPE_EDITOR) {
// Tiny MCE always wrap a '<p>' around the content. Remove it before saving. // Tiny MCE always wrap a '<p>' around the content. Remove it before saving.
...@@ -276,8 +280,9 @@ class FillStoreForm { ...@@ -276,8 +280,9 @@ class FillStoreForm {
break; break;
} }
if ($val !== '') if ($val !== '') {
$val = Sanitize::checkMinMax($val, $formElement[FE_MIN], $formElement[FE_MAX], SANITIZE_EXCEPTION); $val = Sanitize::checkMinMax($val, $formElement[FE_MIN], $formElement[FE_MAX], SANITIZE_EXCEPTION);
}
$newValues[$formElement[FE_NAME]] = $val; $newValues[$formElement[FE_NAME]] = $val;
} }
......
...@@ -418,6 +418,19 @@ class Store { ...@@ -418,6 +418,19 @@ class Store {
} }
} }
/**
* Unset a variable in store.
*
* @param $key
* @param $store
*/
public static function unsetVar($key, $store){
if(isset(self::$raw[$store][$key])) {
unset(self::$raw[$store][$key]);
}
}
/** /**
* Cycles through all stores in $useStore. * Cycles through all stores in $useStore.
* First match will return the found value. * First match will return the found value.
...@@ -583,12 +596,14 @@ class Store { ...@@ -583,12 +596,14 @@ class Store {
* @throws \qfq\CodeException * @throws \qfq\CodeException
*/ */
public static function unsetStore($store) { public static function unsetStore($store) {
// Check valid Storename // Check valid store name
if (!isset(self::$sanitizeStore)) if (!isset(self::$sanitizeStore)) {
throw new UserFormException("Unknown Store: $store", ERROR_UNNOWN_STORE); throw new UserFormException("Unknown Store: $store", ERROR_UNNOWN_STORE);
}
if ($store === STORE_ZERO) if ($store === STORE_ZERO) {
throw new CodeException("unsetStore() for STORE_ZERO is impossible - there are no values.", ERROR_SET_STORE_ZERO); throw new CodeException("unsetStore() for STORE_ZERO is impossible - there are no values.", ERROR_SET_STORE_ZERO);
}
if (isset(self::$raw[$store])) { if (isset(self::$raw[$store])) {
self::$raw[$store] = array(); self::$raw[$store] = array();
...@@ -903,7 +918,3 @@ class Store { ...@@ -903,7 +918,3 @@ class Store {
} }
} }
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