/** * Internal method. Alters submitted data to be suitable for quickforms processing. * Must be called when the form is fully set up. * * @param string $method name of the method which alters submitted data */ function _process_submission($method) { $submission = array(); if ($method == 'post') { if (!empty($_POST)) { $submission = $_POST; } } else { $submission = $_GET; merge_query_params($submission, $_POST); // Emulate handling of parameters in xxxx_param(). } // following trick is needed to enable proper sesskey checks when using GET forms // the _qf__.$this->_formname serves as a marker that form was actually submitted if (array_key_exists('_qf__' . $this->_formname, $submission) and $submission['_qf__' . $this->_formname] == 1) { if (!confirm_sesskey()) { print_error('invalidsesskey'); } $files = $_FILES; } else { $submission = array(); $files = array(); } $this->detectMissingSetType(); $this->_form->updateSubmission($submission, $files); }
/** * Merge parsed POST chunks. * * NOTE: this is not perfect, but it should work in most cases hopefully. * * @param array $target * @param array $values */ function merge_query_params(array &$target, array $values) { if (isset($values[0]) and isset($target[0])) { // This looks like a split [] array, lets verify the keys are continuous starting with 0. $keys1 = array_keys($values); $keys2 = array_keys($target); if ($keys1 === array_keys($keys1) and $keys2 === array_keys($keys2)) { foreach ($values as $v) { $target[] = $v; } return; } } foreach ($values as $k => $v) { if (!isset($target[$k])) { $target[$k] = $v; continue; } if (is_array($target[$k]) and is_array($v)) { merge_query_params($target[$k], $v); continue; } // We should not get here unless there are duplicates in params. $target[$k] = $v; } }
public function test_merge_query_params() { $original = array('id' => '1', 'course' => '2', 'action' => 'delete', 'grade' => array(0 => 'a', 1 => 'b', 2 => 'c'), 'items' => array('a' => 'aa', 'b' => 'bb'), 'mix' => array(0 => '2'), 'numerical' => array('2' => array('a' => 'b'), '1' => '2')); $chunk = array('numerical' => array('0' => 'z', '2' => array('d' => 'e')), 'action' => 'create', 'next' => '2', 'grade' => array(0 => 'e', 1 => 'f', 2 => 'g'), 'mix' => 'mix'); $expected = array('id' => '1', 'course' => '2', 'action' => 'create', 'grade' => array(0 => 'a', 1 => 'b', 2 => 'c', 3 => 'e', 4 => 'f', 5 => 'g'), 'items' => array('a' => 'aa', 'b' => 'bb'), 'mix' => 'mix', 'numerical' => array('2' => array('a' => 'b', 'd' => 'e'), '1' => '2', '0' => 'z'), 'next' => '2'); $array = $original; merge_query_params($array, $chunk); $this->assertSame($expected, $array); $this->assertNotSame($original, $array); $query = "id=1&course=2&action=create&grade%5B%5D=a&grade%5B%5D=b&grade%5B%5D=c&grade%5B%5D=e&grade%5B%5D=f&grade%5B%5D=g&items%5Ba%5D=aa&items%5Bb%5D=bb&mix=mix&numerical%5B2%5D%5Ba%5D=b&numerical%5B2%5D%5Bd%5D=e&numerical%5B1%5D=2&numerical%5B0%5D=z&next=2"; $decoded = array(); parse_str($query, $decoded); $this->assertSame($expected, $decoded); // Prove that we cannot use array_merge_recursive() instead. $this->assertNotSame($expected, array_merge_recursive($original, $chunk)); }