MDL-38885 form: Recursively clean parameters based on right type

This commit is contained in:
Frederic Massart 2013-05-08 15:50:33 +08:00
parent b55248d5ad
commit 3c0ba94e87

View File

@ -1673,6 +1673,80 @@ class MoodleQuickForm extends HTML_QuickForm_DHTMLRulesTableless {
$this->_types = $paramtypes + $this->_types;
}
/**
* Return the type(s) to use to clean an element.
*
* In the case where the element has an array as a value, we will try to obtain a
* type defined for that specific key, and recursively until done.
*
* This method does not work reverse, you cannot pass a nested element and hoping to
* fallback on the clean type of a parent. This method intends to be used with the
* main element, which will generate child types if needed, not the other way around.
*
* Example scenario:
*
* You have defined a new repeated element containing a text field called 'foo'.
* By default there will always be 2 occurence of 'foo' in the form. Even though
* you've set the type on 'foo' to be PARAM_INT, for some obscure reason, you want
* the first value of 'foo', to be PARAM_FLOAT, which you set using setType:
* $mform->setType('foo[0]', PARAM_FLOAT).
*
* Now if you call this method passing 'foo', along with the submitted values of 'foo':
* array(0 => '1.23', 1 => '10'), you will get an array telling you that the key 0 is a
* FLOAT and 1 is an INT. If you had passed 'foo[1]', along with its value '10', you would
* get the default value returned.
*
* @param string $elementname name of the element.
* @param mixed $value value that should be cleaned.
* @return string|array constant value or array of constant values (PARAM_...)
*/
public function getCleanType($elementname, $value, $default = PARAM_RAW) {
$type = $default;
if (array_key_exists($elementname, $this->_types)) {
$type = $this->_types[$elementname];
}
if (is_array($value)) {
$default = $type;
$type = array();
foreach ($value as $subkey => $subvalue) {
$typekey = "$elementname" . "[$subkey]";
if (array_key_exists($typekey, $this->_types)) {
$subtype = $this->_types[$typekey];
} else {
$subtype = $default;
}
if (is_array($subvalue)) {
$type[$subkey] = $this->getCleanType($typekey, $subvalue, $subtype);
} else {
$type[$subkey] = $subtype;
}
}
}
return $type;
}
/**
* Return the cleaned value using the passed type(s).
*
* @param mixed $value value that has to be cleaned.
* @param int|array $type constant value to use to clean (PARAM_...), typically returned by {@link self::getCleanType()}.
* @return mixed cleaned up value.
*/
public function getCleanedValue($value, $type) {
if (is_array($type) && is_array($value)) {
foreach ($type as $key => $param) {
$value[$key] = $this->getCleanedValue($value[$key], $param);
}
} else if (!is_array($type) && !is_array($value)) {
$value = clean_param($value, $type);
} else if (!is_array($type) && is_array($value)) {
$value = clean_param_array($value, $type, true);
} else {
throw new coding_exception('Unexpected type or value received in MoodleQuickForm::cleanValue()');
}
return $value;
}
/**
* Updates submitted values
*
@ -1685,17 +1759,9 @@ class MoodleQuickForm extends HTML_QuickForm_DHTMLRulesTableless {
if (empty($submission)) {
$this->_submitValues = array();
} else {
foreach ($submission as $key=>$s) {
if (array_key_exists($key, $this->_types)) {
$type = $this->_types[$key];
} else {
$type = PARAM_RAW;
}
if (is_array($s)) {
$submission[$key] = clean_param_array($s, $type, true);
} else {
$submission[$key] = clean_param($s, $type);
}
foreach ($submission as $key => $s) {
$type = $this->getCleanType($key, $s);
$submission[$key] = $this->getCleanedValue($s, $type);
}
$this->_submitValues = $submission;
$this->_flagSubmitted = true;