Skip to content

Commit

Permalink
Merge branch 'MDL-38885-master-int' of git://github.com/FMCorz/moodle
Browse files Browse the repository at this point in the history
  • Loading branch information
stronk7 committed May 10, 2013
2 parents 05bf4b1 + d5909fd commit da2cff3
Show file tree
Hide file tree
Showing 2 changed files with 407 additions and 31 deletions.
144 changes: 114 additions & 30 deletions lib/formslib.php
Original file line number Diff line number Diff line change
Expand Up @@ -1270,25 +1270,42 @@ private function detectMissingSetType() {

$mform = $this->_form;
foreach ($mform->_elements as $element) {
switch ($element->getType()) {
case 'hidden':
case 'text':
case 'url':
$key = $element->getName();
// For repeated elements we need to look for
// the "main" type, not for the one present
// on each repetition. All the stuff in formslib
// (repeat_elements(), updateSubmission()... seems
// to work that way.
$pos = strpos($key, '[');
if ($pos !== false) {
$key = substr($key, 0, $pos);
}
if (!array_key_exists($key, $mform->_types)) {
debugging("Did you remember to call setType() for '$key'? ".
'Defaulting to PARAM_RAW cleaning.', DEBUG_DEVELOPER);
}
break;
$group = false;
$elements = array($element);

if ($element->getType() == 'group') {
$group = $element;
$elements = $element->getElements();
}

foreach ($elements as $index => $element) {
switch ($element->getType()) {
case 'hidden':
case 'text':
case 'url':
if ($group) {
$name = $group->getElementName($index);
} else {
$name = $element->getName();
}
$key = $name;
$found = array_key_exists($key, $mform->_types);
// For repeated elements we need to look for
// the "main" type, not for the one present
// on each repetition. All the stuff in formslib
// (repeat_elements(), updateSubmission()... seems
// to work that way.
while (!$found && strrpos($key, '[') !== false) {
$pos = strrpos($key, '[');
$key = substr($key, 0, $pos);
$found = array_key_exists($key, $mform->_types);
}
if (!$found) {
debugging("Did you remember to call setType() for '$name'? ".
'Defaulting to PARAM_RAW cleaning.', DEBUG_DEVELOPER);
}
break;
}
}
}
}
Expand Down Expand Up @@ -1673,6 +1690,81 @@ function setTypes($paramtypes) {
$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 clean type returned (param $default).
*
* @param string $elementname name of the element.
* @param mixed $value value that should be cleaned.
* @param int $default default constant value to be returned (PARAM_...)
* @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::getCleanedValue()');
}
return $value;
}

/**
* Updates submitted values
*
Expand All @@ -1685,17 +1777,9 @@ function updateSubmission($submission, $files) {
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;
Expand Down
Loading

0 comments on commit da2cff3

Please sign in to comment.